Changeset 40907 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Apr 13, 2012 8:50:14 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
r39078 r40907 36 36 #include <iprt/assert.h> 37 37 #include <iprt/string.h> 38 39 #include "dtrace/VBoxVMM.h" 40 #include "PDMInline.h" 38 41 39 42 … … 56 59 * Internal Functions * 57 60 *******************************************************************************/ 58 static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel); 59 static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel); 60 static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue); 61 static bool pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc); 61 62 62 63 … … 71 72 PDMDEV_ASSERT_DEVINS(pDevIns); 72 73 LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel)); 73 74 74 PVM pVM = pDevIns->Internal.s.pVMR0; 75 75 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR0; 76 76 PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusR0; 77 78 pdmLock(pVM); 79 uint32_t uTagSrc; 80 if (iLevel & PDM_IRQ_LEVEL_HIGH) 81 { 82 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); 83 if (iLevel == PDM_IRQ_LEVEL_HIGH) 84 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 85 else 86 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 87 } 88 else 89 uTagSrc = pDevIns->Internal.s.uLastIrqTag; 90 77 91 if ( pPciDev 78 92 && pPciBus 79 93 && pPciBus->pDevInsR0) 80 94 { 81 p dmLock(pVM);82 pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel); 95 pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc); 96 83 97 pdmUnlock(pVM); 98 99 if (iLevel == PDM_IRQ_LEVEL_LOW) 100 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 84 101 } 85 102 else 86 103 { 104 pdmUnlock(pVM); 105 87 106 /* queue for ring-3 execution. */ 88 107 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 89 if (pTask) 90 { 91 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ; 92 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns); 93 pTask->u.SetIRQ.iIrq = iIrq; 94 pTask->u.SetIRQ.iLevel = iLevel; 95 96 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 97 } 98 else 99 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 100 } 101 102 LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance)); 108 AssertReturnVoid(pTask); 109 110 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ; 111 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns); 112 pTask->u.SetIRQ.iIrq = iIrq; 113 pTask->u.SetIRQ.iLevel = iLevel; 114 pTask->u.SetIRQ.uTagSrc = uTagSrc; 115 116 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 117 } 118 119 LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); 103 120 } 104 121 … … 109 126 PDMDEV_ASSERT_DEVINS(pDevIns); 110 127 LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel)); 111 112 pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel); 113 114 LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance)); 128 PVM pVM = pDevIns->Internal.s.pVMR0; 129 130 pdmLock(pVM); 131 uint32_t uTagSrc; 132 if (iLevel & PDM_IRQ_LEVEL_HIGH) 133 { 134 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); 135 if (iLevel == PDM_IRQ_LEVEL_HIGH) 136 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 137 else 138 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 139 } 140 else 141 uTagSrc = pDevIns->Internal.s.uLastIrqTag; 142 143 bool fRc = pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc); 144 145 if (iLevel == PDM_IRQ_LEVEL_LOW && fRc) 146 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 147 pdmUnlock(pVM); 148 LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); 115 149 } 116 150 … … 213 247 214 248 215 /** @ copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/249 /** @interface_method_impl{PDMDEVHLPR0,pfnPATMSetMMIOPatchInfo} */ 216 250 static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData) 217 251 { … … 233 267 LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance)); 234 268 return pDevIns->Internal.s.pVMR0; 235 }236 237 238 /** @interface_method_impl{PDMDEVHLPR0,pfnCanEmulateIoBlock} */239 static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)240 {241 PDMDEV_ASSERT_DEVINS(pDevIns);242 LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));243 return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));244 269 } 245 270 … … 288 313 LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf)); 289 314 return hTraceBuf; 315 } 316 317 318 /** @interface_method_impl{PDMDEVHLPR0,pfnCanEmulateIoBlock} */ 319 static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns) 320 { 321 PDMDEV_ASSERT_DEVINS(pDevIns); 322 LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance)); 323 return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0)); 290 324 } 291 325 … … 568 602 /** @interface_method_impl{PDMIOAPICHLPR0,pfnApicBusDeliver} */ 569 603 static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 570 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode )604 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc) 571 605 { 572 606 PDMDEV_ASSERT_DEVINS(pDevIns); 573 607 PVM pVM = pDevIns->Internal.s.pVMR0; 574 LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 \n",575 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode ));608 LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n", 609 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc)); 576 610 Assert(pVM->pdm.s.Apic.pDevInsR0); 577 611 if (pVM->pdm.s.Apic.pfnBusDeliverR0) 578 return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode); 612 return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, 613 u8Polarity, u8TriggerMode, uTagSrc); 579 614 return VINF_SUCCESS; 580 615 } … … 619 654 620 655 /** @interface_method_impl{PDMPCIHLPR0,pfnIsaSetIrq} */ 621 static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 622 { 623 PDMDEV_ASSERT_DEVINS(pDevIns); 624 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 625 pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel); 656 static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) 657 { 658 PDMDEV_ASSERT_DEVINS(pDevIns); 659 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc)); 660 PVM pVM = pDevIns->Internal.s.pVMR0; 661 662 pdmLock(pVM); 663 pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc); 664 pdmUnlock(pVM); 626 665 } 627 666 628 667 629 668 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSetIrq} */ 630 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 631 { 632 PDMDEV_ASSERT_DEVINS(pDevIns); 633 Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 634 pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel); 635 } 669 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) 670 { 671 PDMDEV_ASSERT_DEVINS(pDevIns); 672 Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc)); 673 PVM pVM = pDevIns->Internal.s.pVMR0; 674 675 if (pVM->pdm.s.IoApic.pDevInsR0) 676 { 677 pdmLock(pVM); 678 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc); 679 pdmUnlock(pVM); 680 } 681 else if (pVM->pdm.s.IoApic.pDevInsR3) 682 { 683 /* queue for ring-3 execution. */ 684 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 685 if (pTask) 686 { 687 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ; 688 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 689 pTask->u.SetIRQ.iIrq = iIrq; 690 pTask->u.SetIRQ.iLevel = iLevel; 691 pTask->u.SetIRQ.uTagSrc = uTagSrc; 692 693 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 694 } 695 else 696 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 697 } 698 } 699 636 700 637 701 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSendMsi} */ 638 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue) 639 { 640 PDMDEV_ASSERT_DEVINS(pDevIns); 641 Log4(("pdmR0PciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue)); 642 pdmR0IoApicSendMsi(pDevIns->Internal.s.pVMR0, GCAddr, uValue); 643 } 702 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc) 703 { 704 PDMDEV_ASSERT_DEVINS(pDevIns); 705 Log4(("pdmR0PciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc)); 706 PVM pVM = pDevIns->Internal.s.pVMR0; 707 if (pVM->pdm.s.IoApic.pDevInsR0) 708 { 709 pdmLock(pVM); 710 pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc); 711 pdmUnlock(pVM); 712 } 713 else 714 { 715 AssertFatalMsgFailed(("Lazy bastards!")); 716 } 717 } 718 644 719 645 720 /** @interface_method_impl{PDMPCIHLPR0,pfnLock} */ … … 814 889 815 890 /** 816 * Sets an irq on the I/O APIC.891 * Sets an irq on the PIC and I/O APIC. 817 892 * 818 * @param pVM The VM handle. 819 * @param iIrq The irq. 820 * @param iLevel The new level. 821 */ 822 static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel) 823 { 824 if ( ( pVM->pdm.s.IoApic.pDevInsR0 825 || !pVM->pdm.s.IoApic.pDevInsR3) 826 && ( pVM->pdm.s.Pic.pDevInsR0 827 || !pVM->pdm.s.Pic.pDevInsR3)) 828 { 829 pdmLock(pVM); 893 * @returns true if delivered, false if postponed. 894 * @param pVM The VM handle. 895 * @param iIrq The irq. 896 * @param iLevel The new level. 897 * @param uTagSrc The IRQ tag and source. 898 * 899 * @remarks The caller holds the PDM lock. 900 */ 901 static bool pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc) 902 { 903 if (RT_LIKELY( ( pVM->pdm.s.IoApic.pDevInsR0 904 || !pVM->pdm.s.IoApic.pDevInsR3) 905 && ( pVM->pdm.s.Pic.pDevInsR0 906 || !pVM->pdm.s.Pic.pDevInsR3))) 907 { 830 908 if (pVM->pdm.s.Pic.pDevInsR0) 831 pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel );909 pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel, uTagSrc); 832 910 if (pVM->pdm.s.IoApic.pDevInsR0) 833 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel); 834 pdmUnlock(pVM); 835 } 836 else 837 { 838 /* queue for ring-3 execution. */ 839 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 840 if (pTask) 841 { 842 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ; 843 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 844 pTask->u.SetIRQ.iIrq = iIrq; 845 pTask->u.SetIRQ.iLevel = iLevel; 846 847 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 848 } 849 else 850 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 851 } 852 } 853 854 855 /** 856 * Sets an irq on the I/O APIC. 857 * 858 * @param pVM The VM handle. 859 * @param iIrq The irq. 860 * @param iLevel The new level. 861 */ 862 static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel) 863 { 864 if (pVM->pdm.s.IoApic.pDevInsR0) 865 { 866 pdmLock(pVM); 867 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel); 868 pdmUnlock(pVM); 869 } 870 else if (pVM->pdm.s.IoApic.pDevInsR3) 871 { 872 /* queue for ring-3 execution. */ 873 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 874 if (pTask) 875 { 876 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ; 877 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 878 pTask->u.SetIRQ.iIrq = iIrq; 879 pTask->u.SetIRQ.iLevel = iLevel; 880 881 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 882 } 883 else 884 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 885 } 911 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc); 912 return true; 913 } 914 915 /* queue for ring-3 execution. */ 916 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0); 917 AssertReturn(pTask, false); 918 919 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ; 920 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 921 pTask->u.SetIRQ.iIrq = iIrq; 922 pTask->u.SetIRQ.iLevel = iLevel; 923 pTask->u.SetIRQ.uTagSrc = uTagSrc; 924 925 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0); 926 return false; 886 927 } 887 928 … … 913 954 } 914 955 915 /**916 * Sends an MSI to I/O APIC.917 *918 * @param pVM The VM handle.919 * @param GCAddr Address of the message.920 * @param uValue Value of the message.921 */922 static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)923 {924 if (pVM->pdm.s.IoApic.pDevInsR0)925 {926 pdmLock(pVM);927 pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCAddr, uValue);928 pdmUnlock(pVM);929 }930 }
Note:
See TracChangeset
for help on using the changeset viewer.