Changeset 12980 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 4, 2008 9:20:46 PM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r12964 r12980 69 69 PDM.cpp \ 70 70 PDMDevice.cpp \ 71 PDMDevHlp.cpp \ 72 PDMDevMiscHlp.cpp \ 71 73 PDMDriver.cpp \ 72 74 PDMLdr.cpp \ -
trunk/src/VBox/VMM/PDMDevHlp.cpp
r12979 r12980 1 1 /* $Id$ */ 2 2 /** @file 3 * PDM - Pluggable Device and Driver Manager, Device parts.3 * PDM - Pluggable Device and Driver Manager, Device Helpers. 4 4 */ 5 5 … … 30 30 #include <VBox/pgm.h> 31 31 #include <VBox/iom.h> 32 #include <VBox/cfgm.h>33 32 #include <VBox/rem.h> 34 33 #include <VBox/dbgf.h> … … 39 38 #include <VBox/log.h> 40 39 #include <VBox/err.h> 41 #include <iprt/alloc.h>42 #include <iprt/alloca.h>43 40 #include <iprt/asm.h> 44 41 #include <iprt/assert.h> 45 #include <iprt/path.h>46 #include <iprt/semaphore.h>47 42 #include <iprt/string.h> 48 43 #include <iprt/thread.h> … … 50 45 51 46 /******************************************************************************* 52 * Structures and Typedefs*47 * Defined Constants And Macros * 53 48 *******************************************************************************/ 54 /**55 * Internal callback structure pointer.56 * The main purpose is to define the extra data we associate57 * with PDMDEVREGCB so we can find the VM instance and so on.58 */59 typedef struct PDMDEVREGCBINT60 {61 /** The callback structure. */62 PDMDEVREGCB Core;63 /** A bit of padding. */64 uint32_t u32[4];65 /** VM Handle. */66 PVM pVM;67 } PDMDEVREGCBINT, *PPDMDEVREGCBINT;68 typedef const PDMDEVREGCBINT *PCPDMDEVREGCBINT;69 70 71 /*******************************************************************************72 * Internal Functions *73 *******************************************************************************/74 __BEGIN_DECLS75 static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg);76 static DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb);77 static DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);78 79 /* VSlick regex:80 search : \om/\*\*.+?\*\/\nDECLCALLBACKMEMBER\(([^,]*), *pfn([^)]*)\)\(81 replace: \/\*\* @copydoc PDMDEVHLPR3::pfn\2 \*\/\nstatic DECLCALLBACK\(\1\) pdmR3DevHlp_\2\(82 */83 84 /** @name R3 DevHlp85 * @{86 */87 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc);88 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);89 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);90 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts);91 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,92 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,93 const char *pszDesc);94 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,95 const char *pszWrite, const char *pszRead, const char *pszFill,96 const char *pszDesc);97 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,98 const char *pszWrite, const char *pszRead, const char *pszFill,99 const char *pszDesc);100 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);101 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);102 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,103 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,104 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);105 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);106 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc);107 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev);108 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback);109 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,110 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld);111 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);112 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);113 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);114 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);115 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc);116 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb);117 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb);118 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv);119 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);120 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);121 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);122 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);123 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);124 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);125 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args);126 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler);127 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc);128 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...);129 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args);130 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);131 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime);132 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,133 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);134 135 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns);136 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);137 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);138 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);139 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);140 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);141 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp);142 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue);143 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);144 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);145 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);146 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);147 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);148 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);149 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns);150 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);151 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable);152 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns);153 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns);154 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns);155 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns);156 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns);157 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);158 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);159 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);160 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);161 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);162 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);163 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns);164 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);165 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);166 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,167 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);168 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);169 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);170 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);171 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);172 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);173 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);174 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);175 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);176 177 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns);178 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);179 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);180 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);181 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);182 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);183 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);184 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);185 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);186 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);187 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);188 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC);189 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr);190 191 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns);192 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable);193 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns);194 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns);195 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns);196 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns);197 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns);198 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);199 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);200 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);201 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);202 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);203 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);204 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns);205 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);206 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);207 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,208 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);209 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);210 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);211 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);212 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);213 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);214 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);215 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);216 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);217 /** @} */218 219 220 /** @name HC PIC Helpers221 * @{222 */223 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);224 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);225 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc);226 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns);227 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns);228 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns);229 /** @} */230 231 232 /** @name HC APIC Helpers233 * @{234 */235 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);236 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);237 static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);238 static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);239 static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns);240 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns);241 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);242 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);243 /** @} */244 245 246 /** @name HC I/O APIC Helpers247 * @{248 */249 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,250 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);251 static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);252 static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns);253 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);254 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);255 /** @} */256 257 258 /** @name HC PCI Bus Helpers259 * @{260 */261 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);262 static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);263 static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys);264 static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc);265 static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns);266 static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns);267 static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns);268 /** @} */269 270 /** @def PDMDEV_ASSERT_DEVINS271 * Asserts the validity of the device instance.272 */273 #ifdef VBOX_STRICT274 # define PDMDEV_ASSERT_DEVINS(pDevIns) \275 do { \276 AssertPtr(pDevIns); \277 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \278 Assert(pDevIns->pvInstanceDataR3 == (void *)&pDevIns->achInstanceData[0]); \279 } while (0)280 #else281 # define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)282 #endif283 284 static int pdmR3DevLoadModules(PVM pVM);285 static int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName);286 287 288 49 /* 289 50 * Allow physical read and writes from any thread … … 291 52 #define PDM_PHYS_READWRITE_FROM_ANY_THREAD 292 53 293 __END_DECLS 294 295 /******************************************************************************* 296 * Global Variables * 297 *******************************************************************************/ 54 55 /** @name R3 DevHlp 56 * @{ 57 */ 58 59 60 /** @copydoc PDMDEVHLPR3::pfnIOPortRegister */ 61 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, 62 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc) 63 { 64 PDMDEV_ASSERT_DEVINS(pDevIns); 65 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 66 Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc)); 67 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 68 69 int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc); 70 71 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 72 return rc; 73 } 74 75 76 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterGC */ 77 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, 78 const char *pszOut, const char *pszIn, 79 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 80 { 81 PDMDEV_ASSERT_DEVINS(pDevIns); 82 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 83 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 84 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 85 86 /* 87 * Resolve the functions (one of the can be NULL). 88 */ 89 int rc = VINF_SUCCESS; 90 if ( pDevIns->pDevReg->szRCMod[0] 91 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 92 { 93 RTGCPTR32 GCPtrIn = 0; 94 if (pszIn) 95 { 96 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszIn, &GCPtrIn); 97 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szRCMod, pszIn)); 98 } 99 RTGCPTR32 GCPtrOut = 0; 100 if (pszOut && VBOX_SUCCESS(rc)) 101 { 102 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOut, &GCPtrOut); 103 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szRCMod, pszOut)); 104 } 105 RTGCPTR32 GCPtrInStr = 0; 106 if (pszInStr && VBOX_SUCCESS(rc)) 107 { 108 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszInStr, &GCPtrInStr); 109 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szRCMod, pszInStr)); 110 } 111 RTGCPTR32 GCPtrOutStr = 0; 112 if (pszOutStr && VBOX_SUCCESS(rc)) 113 { 114 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOutStr, &GCPtrOutStr); 115 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szRCMod, pszOutStr)); 116 } 117 118 if (VBOX_SUCCESS(rc)) 119 rc = IOMR3IOPortRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc); 120 } 121 else 122 { 123 AssertMsgFailed(("No GC module for this driver!\n")); 124 rc = VERR_INVALID_PARAMETER; 125 } 126 127 LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 128 return rc; 129 } 130 131 132 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0 */ 133 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, 134 const char *pszOut, const char *pszIn, 135 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 136 { 137 PDMDEV_ASSERT_DEVINS(pDevIns); 138 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 139 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 140 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 141 142 /* 143 * Resolve the functions (one of the can be NULL). 144 */ 145 int rc = VINF_SUCCESS; 146 if ( pDevIns->pDevReg->szR0Mod[0] 147 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 148 { 149 R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0; 150 if (pszIn) 151 { 152 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn); 153 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn)); 154 } 155 R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0; 156 if (pszOut && VBOX_SUCCESS(rc)) 157 { 158 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut); 159 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut)); 160 } 161 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0; 162 if (pszInStr && VBOX_SUCCESS(rc)) 163 { 164 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr); 165 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr)); 166 } 167 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0; 168 if (pszOutStr && VBOX_SUCCESS(rc)) 169 { 170 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr); 171 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr)); 172 } 173 174 if (VBOX_SUCCESS(rc)) 175 rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc); 176 } 177 else 178 { 179 AssertMsgFailed(("No R0 module for this driver!\n")); 180 rc = VERR_INVALID_PARAMETER; 181 } 182 183 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 184 return rc; 185 } 186 187 188 /** @copydoc PDMDEVHLPR3::pfnIOPortDeregister */ 189 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts) 190 { 191 PDMDEV_ASSERT_DEVINS(pDevIns); 192 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 193 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 194 Port, cPorts)); 195 196 int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts); 197 198 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 199 return rc; 200 } 201 202 203 /** @copydoc PDMDEVHLPR3::pfnMMIORegister */ 204 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, 205 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, 206 const char *pszDesc) 207 { 208 PDMDEV_ASSERT_DEVINS(pDevIns); 209 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 210 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n", 211 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc)); 212 213 int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc); 214 215 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 216 return rc; 217 } 218 219 220 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterGC */ 221 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser, 222 const char *pszWrite, const char *pszRead, const char *pszFill, 223 const char *pszDesc) 224 { 225 PDMDEV_ASSERT_DEVINS(pDevIns); 226 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 227 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 228 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 229 230 /* 231 * Resolve the functions. 232 * Not all function have to present, leave it to IOM to enforce this. 233 */ 234 int rc = VINF_SUCCESS; 235 if ( pDevIns->pDevReg->szRCMod[0] 236 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 237 { 238 RTGCPTR32 GCPtrWrite = 0; 239 if (pszWrite) 240 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszWrite, &GCPtrWrite); 241 RTGCPTR32 GCPtrRead = 0; 242 int rc2 = VINF_SUCCESS; 243 if (pszRead) 244 rc2 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszRead, &GCPtrRead); 245 RTGCPTR32 GCPtrFill = 0; 246 int rc3 = VINF_SUCCESS; 247 if (pszFill) 248 rc3 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszFill, &GCPtrFill); 249 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 250 rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill); 251 else 252 { 253 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szRCMod, pszWrite)); 254 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szRCMod, pszRead)); 255 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szRCMod, pszFill)); 256 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 257 rc = rc2; 258 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 259 rc = rc3; 260 } 261 } 262 else 263 { 264 AssertMsgFailed(("No GC module for this driver!\n")); 265 rc = VERR_INVALID_PARAMETER; 266 } 267 268 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 269 return rc; 270 } 271 272 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterR0 */ 273 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser, 274 const char *pszWrite, const char *pszRead, const char *pszFill, 275 const char *pszDesc) 276 { 277 PDMDEV_ASSERT_DEVINS(pDevIns); 278 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 279 LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 280 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 281 282 /* 283 * Resolve the functions. 284 * Not all function have to present, leave it to IOM to enforce this. 285 */ 286 int rc = VINF_SUCCESS; 287 if ( pDevIns->pDevReg->szR0Mod[0] 288 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 289 { 290 R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0; 291 if (pszWrite) 292 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite); 293 R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0; 294 int rc2 = VINF_SUCCESS; 295 if (pszRead) 296 rc2 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead); 297 R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0; 298 int rc3 = VINF_SUCCESS; 299 if (pszFill) 300 rc3 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill); 301 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 302 rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill); 303 else 304 { 305 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite)); 306 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead)); 307 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill)); 308 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 309 rc = rc2; 310 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 311 rc = rc3; 312 } 313 } 314 else 315 { 316 AssertMsgFailed(("No R0 module for this driver!\n")); 317 rc = VERR_INVALID_PARAMETER; 318 } 319 320 LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 321 return rc; 322 } 323 324 325 /** @copydoc PDMDEVHLPR3::pfnMMIODeregister */ 326 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 327 { 328 PDMDEV_ASSERT_DEVINS(pDevIns); 329 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 330 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 331 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 332 333 int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange); 334 335 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 336 return rc; 337 } 338 339 340 /** @copydoc PDMDEVHLPR3::pfnROMRegister */ 341 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc) 342 { 343 PDMDEV_ASSERT_DEVINS(pDevIns); 344 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 345 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n", 346 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc)); 347 348 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc); 349 350 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 351 return rc; 352 } 353 354 355 /** @copydoc PDMDEVHLPR3::pfnSSMRegister */ 356 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, 357 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, 358 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone) 359 { 360 PDMDEV_ASSERT_DEVINS(pDevIns); 361 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 362 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n", 363 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone)); 364 365 int rc = SSMR3Register(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess, 366 pfnSavePrep, pfnSaveExec, pfnSaveDone, 367 pfnLoadPrep, pfnLoadExec, pfnLoadDone); 368 369 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 370 return rc; 371 } 372 373 374 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */ 375 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer) 376 { 377 PDMDEV_ASSERT_DEVINS(pDevIns); 378 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 379 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n", 380 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer)); 381 382 int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer); 383 384 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 385 return rc; 386 } 387 388 389 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreateExternal */ 390 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc) 391 { 392 PDMDEV_ASSERT_DEVINS(pDevIns); 393 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 394 395 return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMR3, enmClock, pfnCallback, pvUser, pszDesc); 396 } 397 398 /** @copydoc PDMDEVHLPR3::pfnPCIRegister */ 399 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev) 400 { 401 PDMDEV_ASSERT_DEVINS(pDevIns); 402 PVM pVM = pDevIns->Internal.s.pVMR3; 403 VM_ASSERT_EMT(pVM); 404 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n", 405 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config)); 406 407 /* 408 * Validate input. 409 */ 410 if (!pPciDev) 411 { 412 Assert(pPciDev); 413 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 414 return VERR_INVALID_PARAMETER; 415 } 416 if (!pPciDev->config[0] && !pPciDev->config[1]) 417 { 418 Assert(pPciDev->config[0] || pPciDev->config[1]); 419 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 420 return VERR_INVALID_PARAMETER; 421 } 422 if (pDevIns->Internal.s.pPciDeviceR3) 423 { 424 /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to 425 * support a PDM device with multiple PCI devices. This might become a problem 426 * when upgrading the chipset for instance... 427 */ 428 AssertMsgFailed(("Only one PCI device per device is currently implemented!\n")); 429 return VERR_INTERNAL_ERROR; 430 } 431 432 /* 433 * Choose the PCI bus for the device. 434 * This is simple. If the device was configured for a particular bus, it'll 435 * already have one. If not, we'll just take the first one. 436 */ 437 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 438 if (!pBus) 439 pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[0]; 440 int rc; 441 if (pBus) 442 { 443 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 444 pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3); 445 else 446 pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR; 447 448 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 449 pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3); 450 else 451 pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR; 452 453 /* 454 * Check the configuration for PCI device and function assignment. 455 */ 456 int iDev = -1; 457 uint8_t u8Device; 458 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device); 459 if (VBOX_SUCCESS(rc)) 460 { 461 if (u8Device > 31) 462 { 463 AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n", 464 u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 465 return VERR_INTERNAL_ERROR; 466 } 467 468 uint8_t u8Function; 469 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function); 470 if (VBOX_FAILURE(rc)) 471 { 472 AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n", 473 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 474 return rc; 475 } 476 if (u8Function > 7) 477 { 478 AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n", 479 u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 480 return VERR_INTERNAL_ERROR; 481 } 482 iDev = (u8Device << 3) | u8Function; 483 } 484 else if (rc != VERR_CFGM_VALUE_NOT_FOUND) 485 { 486 AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n", 487 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 488 return rc; 489 } 490 491 /* 492 * Call the pci bus device to do the actual registration. 493 */ 494 pdmLock(pVM); 495 rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev); 496 pdmUnlock(pVM); 497 if (VBOX_SUCCESS(rc)) 498 { 499 pPciDev->pDevIns = pDevIns; 500 501 pDevIns->Internal.s.pPciDeviceR3 = pPciDev; 502 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0) 503 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev); 504 else 505 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR; 506 507 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 508 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev); 509 else 510 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR; 511 512 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n", 513 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus)); 514 } 515 } 516 else 517 { 518 AssertMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n")); 519 rc = VERR_PDM_NO_PCI_BUS; 520 } 521 522 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 523 return rc; 524 } 525 526 527 /** @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister */ 528 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback) 529 { 530 PDMDEV_ASSERT_DEVINS(pDevIns); 531 PVM pVM = pDevIns->Internal.s.pVMR3; 532 VM_ASSERT_EMT(pVM); 533 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n", 534 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback)); 535 536 /* 537 * Validate input. 538 */ 539 if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS) 540 { 541 Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS); 542 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 543 return VERR_INVALID_PARAMETER; 544 } 545 switch (enmType) 546 { 547 case PCI_ADDRESS_SPACE_MEM: 548 case PCI_ADDRESS_SPACE_IO: 549 case PCI_ADDRESS_SPACE_MEM_PREFETCH: 550 break; 551 default: 552 AssertMsgFailed(("enmType=%#x is unknown\n", enmType)); 553 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 554 return VERR_INVALID_PARAMETER; 555 } 556 if (!pfnCallback) 557 { 558 Assert(pfnCallback); 559 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 560 return VERR_INVALID_PARAMETER; 561 } 562 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 563 564 /* 565 * Must have a PCI device registered! 566 */ 567 int rc; 568 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 569 if (pPciDev) 570 { 571 /* 572 * We're currently restricted to page aligned MMIO regions. 573 */ 574 if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH) 575 && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE)) 576 { 577 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n", 578 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE))); 579 cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE); 580 } 581 582 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 583 Assert(pBus); 584 pdmLock(pVM); 585 rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback); 586 pdmUnlock(pVM); 587 } 588 else 589 { 590 AssertMsgFailed(("No PCI device registered!\n")); 591 rc = VERR_PDM_NOT_PCI_DEVICE; 592 } 593 594 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 595 return rc; 596 } 597 598 599 /** @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks */ 600 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, 601 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld) 602 { 603 PDMDEV_ASSERT_DEVINS(pDevIns); 604 PVM pVM = pDevIns->Internal.s.pVMR3; 605 VM_ASSERT_EMT(pVM); 606 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n", 607 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld)); 608 609 /* 610 * Validate input and resolve defaults. 611 */ 612 AssertPtr(pfnRead); 613 AssertPtr(pfnWrite); 614 AssertPtrNull(ppfnReadOld); 615 AssertPtrNull(ppfnWriteOld); 616 AssertPtrNull(pPciDev); 617 618 if (!pPciDev) 619 pPciDev = pDevIns->Internal.s.pPciDeviceR3; 620 AssertReleaseMsg(pPciDev, ("You must register your device first!\n")); 621 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 622 AssertRelease(pBus); 623 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 624 625 /* 626 * Do the job. 627 */ 628 pdmLock(pVM); 629 pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld); 630 pdmUnlock(pVM); 631 632 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 633 } 634 635 636 /** @copydoc PDMDEVHLPR3::pfnPCISetIrq */ 637 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 638 { 639 PDMDEV_ASSERT_DEVINS(pDevIns); 640 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 641 642 /* 643 * Validate input. 644 */ 645 /** @todo iIrq and iLevel checks. */ 646 647 /* 648 * Must have a PCI device registered! 649 */ 650 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 651 if (pPciDev) 652 { 653 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */ 654 Assert(pBus); 655 PVM pVM = pDevIns->Internal.s.pVMR3; 656 pdmLock(pVM); 657 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel); 658 pdmUnlock(pVM); 659 } 660 else 661 AssertReleaseMsgFailed(("No PCI device registered!\n")); 662 663 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 664 } 665 666 667 /** @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait */ 668 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 669 { 670 pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel); 671 } 672 673 674 /** @copydoc PDMDEVHLPR3::pfnISASetIrq */ 675 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 676 { 677 PDMDEV_ASSERT_DEVINS(pDevIns); 678 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 679 680 /* 681 * Validate input. 682 */ 683 /** @todo iIrq and iLevel checks. */ 684 685 PVM pVM = pDevIns->Internal.s.pVMR3; 686 PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */ 687 688 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 689 } 690 691 692 /** @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait */ 693 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 694 { 695 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel); 696 } 697 698 699 /** @copydoc PDMDEVHLPR3::pfnDriverAttach */ 700 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc) 701 { 702 PDMDEV_ASSERT_DEVINS(pDevIns); 703 PVM pVM = pDevIns->Internal.s.pVMR3; 704 VM_ASSERT_EMT(pVM); 705 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n", 706 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc)); 707 708 /* 709 * Lookup the LUN, it might already be registered. 710 */ 711 PPDMLUN pLunPrev = NULL; 712 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; 713 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext) 714 if (pLun->iLun == iLun) 715 break; 716 717 /* 718 * Create the LUN if if wasn't found, else check if driver is already attached to it. 719 */ 720 if (!pLun) 721 { 722 if ( !pBaseInterface 723 || !pszDesc 724 || !*pszDesc) 725 { 726 Assert(pBaseInterface); 727 Assert(pszDesc || *pszDesc); 728 return VERR_INVALID_PARAMETER; 729 } 730 731 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun)); 732 if (!pLun) 733 return VERR_NO_MEMORY; 734 735 pLun->iLun = iLun; 736 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL; 737 pLun->pTop = NULL; 738 pLun->pBottom = NULL; 739 pLun->pDevIns = pDevIns; 740 pLun->pszDesc = pszDesc; 741 pLun->pBase = pBaseInterface; 742 if (!pLunPrev) 743 pDevIns->Internal.s.pLunsR3 = pLun; 744 else 745 pLunPrev->pNext = pLun; 746 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n", 747 iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 748 } 749 else if (pLun->pTop) 750 { 751 AssertMsgFailed(("Already attached! The device should keep track of such things!\n")); 752 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED)); 753 return VERR_PDM_DRIVER_ALREADY_ATTACHED; 754 } 755 Assert(pLun->pBase == pBaseInterface); 756 757 758 /* 759 * Get the attached driver configuration. 760 */ 761 int rc; 762 char szNode[48]; 763 RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun); 764 PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode); 765 if (pNode) 766 { 767 char *pszName; 768 rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName); 769 if (VBOX_SUCCESS(rc)) 770 { 771 /* 772 * Find the driver. 773 */ 774 PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName); 775 if (pDrv) 776 { 777 /* config node */ 778 PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config"); 779 if (!pConfigNode) 780 rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode); 781 if (VBOX_SUCCESS(rc)) 782 { 783 CFGMR3SetRestrictedRoot(pConfigNode); 784 785 /* 786 * Allocate the driver instance. 787 */ 788 size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]); 789 cb = RT_ALIGN_Z(cb, 16); 790 PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb); 791 if (pNew) 792 { 793 /* 794 * Initialize the instance structure (declaration order). 795 */ 796 pNew->u32Version = PDM_DRVINS_VERSION; 797 //pNew->Internal.s.pUp = NULL; 798 //pNew->Internal.s.pDown = NULL; 799 pNew->Internal.s.pLun = pLun; 800 pNew->Internal.s.pDrv = pDrv; 801 pNew->Internal.s.pVM = pVM; 802 //pNew->Internal.s.fDetaching = false; 803 pNew->Internal.s.pCfgHandle = pNode; 804 pNew->pDrvHlp = &g_pdmR3DrvHlp; 805 pNew->pDrvReg = pDrv->pDrvReg; 806 pNew->pCfgHandle = pConfigNode; 807 pNew->iInstance = pDrv->cInstances++; 808 pNew->pUpBase = pBaseInterface; 809 //pNew->pDownBase = NULL; 810 //pNew->IBase.pfnQueryInterface = NULL; 811 pNew->pvInstanceData = &pNew->achInstanceData[0]; 812 813 /* 814 * Link with LUN and call the constructor. 815 */ 816 pLun->pTop = pLun->pBottom = pNew; 817 rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle); 818 if (VBOX_SUCCESS(rc)) 819 { 820 MMR3HeapFree(pszName); 821 *ppBaseInterface = &pNew->IBase; 822 Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n", 823 pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 824 LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 825 /* 826 * Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS) */ 827 return rc; 828 } 829 830 /* 831 * Free the driver. 832 */ 833 pLun->pTop = pLun->pBottom = NULL; 834 ASMMemFill32(pNew, cb, 0xdeadd0d0); 835 MMR3HeapFree(pNew); 836 pDrv->cInstances--; 837 } 838 else 839 { 840 AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName)); 841 rc = VERR_NO_MEMORY; 842 } 843 } 844 else 845 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc)); 846 } 847 else 848 { 849 AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName)); 850 rc = VERR_PDM_DRIVER_NOT_FOUND; 851 } 852 MMR3HeapFree(pszName); 853 } 854 else 855 { 856 AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc)); 857 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 858 rc = VERR_PDM_CFG_MISSING_DRIVER_NAME; 859 } 860 } 861 else 862 rc = VERR_PDM_NO_ATTACHED_DRIVER; 863 864 865 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 866 return rc; 867 } 868 869 870 /** @copydoc PDMDEVHLPR3::pfnMMHeapAlloc */ 871 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb) 872 { 873 PDMDEV_ASSERT_DEVINS(pDevIns); 874 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 875 876 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 877 878 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 879 return pv; 880 } 881 882 883 /** @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ */ 884 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb) 885 { 886 PDMDEV_ASSERT_DEVINS(pDevIns); 887 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 888 889 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 890 891 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 892 return pv; 893 } 894 895 896 /** @copydoc PDMDEVHLPR3::pfnMMHeapFree */ 897 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv) 898 { 899 PDMDEV_ASSERT_DEVINS(pDevIns); 900 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 901 902 MMR3HeapFree(pv); 903 904 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 905 } 906 907 908 /** @copydoc PDMDEVHLPR3::pfnVMSetError */ 909 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) 910 { 911 PDMDEV_ASSERT_DEVINS(pDevIns); 912 va_list args; 913 va_start(args, pszFormat); 914 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2); 915 va_end(args); 916 return rc; 917 } 918 919 920 /** @copydoc PDMDEVHLPR3::pfnVMSetErrorV */ 921 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) 922 { 923 PDMDEV_ASSERT_DEVINS(pDevIns); 924 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2); 925 return rc; 926 } 927 928 929 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError */ 930 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...) 931 { 932 PDMDEV_ASSERT_DEVINS(pDevIns); 933 va_list args; 934 va_start(args, pszFormat); 935 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, args); 936 va_end(args); 937 return rc; 938 } 939 940 941 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeErrorV */ 942 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va) 943 { 944 PDMDEV_ASSERT_DEVINS(pDevIns); 945 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, va); 946 return rc; 947 } 948 949 950 /** @copydoc PDMDEVHLPR3::pfnAssertEMT */ 951 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 952 { 953 PDMDEV_ASSERT_DEVINS(pDevIns); 954 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 955 return true; 956 957 char szMsg[100]; 958 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 959 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 960 AssertBreakpoint(); 961 return false; 962 } 963 964 965 /** @copydoc PDMDEVHLPR3::pfnAssertOther */ 966 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 967 { 968 PDMDEV_ASSERT_DEVINS(pDevIns); 969 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 970 return true; 971 972 char szMsg[100]; 973 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 974 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 975 AssertBreakpoint(); 976 return false; 977 } 978 979 980 /** @copydoc PDMDEVHLPR3::pfnDBGFStopV */ 981 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args) 982 { 983 PDMDEV_ASSERT_DEVINS(pDevIns); 984 #ifdef LOG_ENABLED 985 va_list va2; 986 va_copy(va2, args); 987 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n", 988 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2)); 989 va_end(va2); 990 #endif 991 992 PVM pVM = pDevIns->Internal.s.pVMR3; 993 VM_ASSERT_EMT(pVM); 994 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args); 995 996 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 997 return rc; 998 } 999 1000 1001 /** @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister */ 1002 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler) 1003 { 1004 PDMDEV_ASSERT_DEVINS(pDevIns); 1005 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n", 1006 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler)); 1007 1008 PVM pVM = pDevIns->Internal.s.pVMR3; 1009 VM_ASSERT_EMT(pVM); 1010 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns); 1011 1012 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1013 return rc; 1014 } 1015 1016 1017 /** @copydoc PDMDEVHLPR3::pfnSTAMRegister */ 1018 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc) 1019 { 1020 PDMDEV_ASSERT_DEVINS(pDevIns); 1021 PVM pVM = pDevIns->Internal.s.pVMR3; 1022 VM_ASSERT_EMT(pVM); 1023 1024 STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); 1025 NOREF(pVM); 1026 } 1027 1028 1029 1030 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterF */ 1031 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 1032 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...) 1033 { 1034 PDMDEV_ASSERT_DEVINS(pDevIns); 1035 PVM pVM = pDevIns->Internal.s.pVMR3; 1036 VM_ASSERT_EMT(pVM); 1037 1038 va_list args; 1039 va_start(args, pszName); 1040 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 1041 va_end(args); 1042 AssertRC(rc); 1043 1044 NOREF(pVM); 1045 } 1046 1047 1048 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterV */ 1049 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 1050 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args) 1051 { 1052 PDMDEV_ASSERT_DEVINS(pDevIns); 1053 PVM pVM = pDevIns->Internal.s.pVMR3; 1054 VM_ASSERT_EMT(pVM); 1055 1056 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 1057 AssertRC(rc); 1058 1059 NOREF(pVM); 1060 } 1061 1062 1063 /** @copydoc PDMDEVHLPR3::pfnRTCRegister */ 1064 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp) 1065 { 1066 PDMDEV_ASSERT_DEVINS(pDevIns); 1067 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1068 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n", 1069 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite, 1070 pRtcReg->pfnWrite, ppRtcHlp)); 1071 1072 /* 1073 * Validate input. 1074 */ 1075 if (pRtcReg->u32Version != PDM_RTCREG_VERSION) 1076 { 1077 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version, 1078 PDM_RTCREG_VERSION)); 1079 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n", 1080 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1081 return VERR_INVALID_PARAMETER; 1082 } 1083 if ( !pRtcReg->pfnWrite 1084 || !pRtcReg->pfnRead) 1085 { 1086 Assert(pRtcReg->pfnWrite); 1087 Assert(pRtcReg->pfnRead); 1088 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 1089 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1090 return VERR_INVALID_PARAMETER; 1091 } 1092 1093 if (!ppRtcHlp) 1094 { 1095 Assert(ppRtcHlp); 1096 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n", 1097 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1098 return VERR_INVALID_PARAMETER; 1099 } 1100 1101 /* 1102 * Only one DMA device. 1103 */ 1104 PVM pVM = pDevIns->Internal.s.pVMR3; 1105 if (pVM->pdm.s.pRtc) 1106 { 1107 AssertMsgFailed(("Only one RTC device is supported!\n")); 1108 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 1109 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1110 return VERR_INVALID_PARAMETER; 1111 } 1112 1113 /* 1114 * Allocate and initialize pci bus structure. 1115 */ 1116 int rc = VINF_SUCCESS; 1117 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc)); 1118 if (pRtc) 1119 { 1120 pRtc->pDevIns = pDevIns; 1121 pRtc->Reg = *pRtcReg; 1122 pVM->pdm.s.pRtc = pRtc; 1123 1124 /* set the helper pointer. */ 1125 *ppRtcHlp = &g_pdmR3DevRtcHlp; 1126 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n", 1127 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1128 } 1129 else 1130 rc = VERR_NO_MEMORY; 1131 1132 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 1133 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1134 return rc; 1135 } 1136 1137 1138 /** @copydoc PDMDEVHLPR3::pfnPDMQueueCreate */ 1139 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, 1140 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue) 1141 { 1142 PDMDEV_ASSERT_DEVINS(pDevIns); 1143 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n", 1144 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue)); 1145 1146 PVM pVM = pDevIns->Internal.s.pVMR3; 1147 VM_ASSERT_EMT(pVM); 1148 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue); 1149 1150 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue)); 1151 return rc; 1152 } 1153 1154 1155 /** @copydoc PDMDEVHLPR3::pfnCritSectInit */ 1156 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName) 1157 { 1158 PDMDEV_ASSERT_DEVINS(pDevIns); 1159 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n", 1160 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName)); 1161 1162 PVM pVM = pDevIns->Internal.s.pVMR3; 1163 VM_ASSERT_EMT(pVM); 1164 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName); 1165 1166 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1167 return rc; 1168 } 1169 1170 1171 /** @copydoc PDMDEVHLPR3::pfnUTCNow */ 1172 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime) 1173 { 1174 PDMDEV_ASSERT_DEVINS(pDevIns); 1175 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n", 1176 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime)); 1177 1178 pTime = TMR3UTCNow(pDevIns->Internal.s.pVMR3, pTime); 1179 1180 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime))); 1181 return pTime; 1182 } 1183 1184 1185 /** @copydoc PDMDEVHLPR3::pfnPDMThreadCreate */ 1186 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 1187 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 1188 { 1189 PDMDEV_ASSERT_DEVINS(pDevIns); 1190 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1191 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n", 1192 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName)); 1193 1194 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 1195 1196 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1197 rc, *ppThread)); 1198 return rc; 1199 } 1200 1201 1202 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 1203 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns) 1204 { 1205 PDMDEV_ASSERT_DEVINS(pDevIns); 1206 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3)); 1207 return pDevIns->Internal.s.pVMR3; 1208 } 1209 1210 1211 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 1212 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 1213 { 1214 PDMDEV_ASSERT_DEVINS(pDevIns); 1215 PVM pVM = pDevIns->Internal.s.pVMR3; 1216 VM_ASSERT_EMT(pVM); 1217 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, " 1218 ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n", 1219 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3, 1220 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3, 1221 pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3)); 1222 1223 /* 1224 * Validate the structure. 1225 */ 1226 if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION) 1227 { 1228 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION)); 1229 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1230 return VERR_INVALID_PARAMETER; 1231 } 1232 if ( !pPciBusReg->pfnRegisterR3 1233 || !pPciBusReg->pfnIORegionRegisterR3 1234 || !pPciBusReg->pfnSetIrqR3 1235 || !pPciBusReg->pfnSaveExecR3 1236 || !pPciBusReg->pfnLoadExecR3 1237 || !pPciBusReg->pfnFakePCIBIOSR3) 1238 { 1239 Assert(pPciBusReg->pfnRegisterR3); 1240 Assert(pPciBusReg->pfnIORegionRegisterR3); 1241 Assert(pPciBusReg->pfnSetIrqR3); 1242 Assert(pPciBusReg->pfnSaveExecR3); 1243 Assert(pPciBusReg->pfnLoadExecR3); 1244 Assert(pPciBusReg->pfnFakePCIBIOSR3); 1245 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1246 return VERR_INVALID_PARAMETER; 1247 } 1248 if ( pPciBusReg->pszSetIrqRC 1249 && !VALID_PTR(pPciBusReg->pszSetIrqRC)) 1250 { 1251 Assert(VALID_PTR(pPciBusReg->pszSetIrqRC)); 1252 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1253 return VERR_INVALID_PARAMETER; 1254 } 1255 if ( pPciBusReg->pszSetIrqR0 1256 && !VALID_PTR(pPciBusReg->pszSetIrqR0)) 1257 { 1258 Assert(VALID_PTR(pPciBusReg->pszSetIrqR0)); 1259 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1260 return VERR_INVALID_PARAMETER; 1261 } 1262 if (!ppPciHlpR3) 1263 { 1264 Assert(ppPciHlpR3); 1265 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1266 return VERR_INVALID_PARAMETER; 1267 } 1268 1269 /* 1270 * Find free PCI bus entry. 1271 */ 1272 unsigned iBus = 0; 1273 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++) 1274 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3) 1275 break; 1276 if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses)) 1277 { 1278 AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses))); 1279 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1280 return VERR_INVALID_PARAMETER; 1281 } 1282 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus]; 1283 1284 /* 1285 * Resolve and init the RC bits. 1286 */ 1287 if (pPciBusReg->pszSetIrqRC) 1288 { 1289 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC); 1290 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, rc)); 1291 if (VBOX_FAILURE(rc)) 1292 { 1293 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1294 return rc; 1295 } 1296 pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1297 } 1298 else 1299 { 1300 pPciBus->pfnSetIrqRC = 0; 1301 pPciBus->pDevInsRC = 0; 1302 } 1303 1304 /* 1305 * Resolve and init the R0 bits. 1306 */ 1307 if (pPciBusReg->pszSetIrqR0) 1308 { 1309 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0); 1310 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc)); 1311 if (VBOX_FAILURE(rc)) 1312 { 1313 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1314 return rc; 1315 } 1316 pPciBus->pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 1317 } 1318 else 1319 { 1320 pPciBus->pfnSetIrqR0 = 0; 1321 pPciBus->pDevInsR0 = 0; 1322 } 1323 1324 /* 1325 * Init the R3 bits. 1326 */ 1327 pPciBus->iBus = iBus; 1328 pPciBus->pDevInsR3 = pDevIns; 1329 pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3; 1330 pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3; 1331 pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3; 1332 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3; 1333 pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3; 1334 pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3; 1335 pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3; 1336 1337 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1338 1339 /* set the helper pointer and return. */ 1340 *ppPciHlpR3 = &g_pdmR3DevPciHlp; 1341 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 1342 return VINF_SUCCESS; 1343 } 1344 1345 1346 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 1347 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 1348 { 1349 PDMDEV_ASSERT_DEVINS(pDevIns); 1350 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1351 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n", 1352 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3, 1353 pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC, 1354 pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0, 1355 ppPicHlpR3)); 1356 1357 /* 1358 * Validate input. 1359 */ 1360 if (pPicReg->u32Version != PDM_PICREG_VERSION) 1361 { 1362 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION)); 1363 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1364 return VERR_INVALID_PARAMETER; 1365 } 1366 if ( !pPicReg->pfnSetIrqR3 1367 || !pPicReg->pfnGetInterruptR3) 1368 { 1369 Assert(pPicReg->pfnSetIrqR3); 1370 Assert(pPicReg->pfnGetInterruptR3); 1371 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1372 return VERR_INVALID_PARAMETER; 1373 } 1374 if ( ( pPicReg->pszSetIrqRC 1375 || pPicReg->pszGetInterruptRC) 1376 && ( !VALID_PTR(pPicReg->pszSetIrqRC) 1377 || !VALID_PTR(pPicReg->pszGetInterruptRC)) 1378 ) 1379 { 1380 Assert(VALID_PTR(pPicReg->pszSetIrqRC)); 1381 Assert(VALID_PTR(pPicReg->pszGetInterruptRC)); 1382 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1383 return VERR_INVALID_PARAMETER; 1384 } 1385 if ( pPicReg->pszSetIrqRC 1386 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 1387 { 1388 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC); 1389 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1390 return VERR_INVALID_PARAMETER; 1391 } 1392 if ( pPicReg->pszSetIrqR0 1393 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 1394 { 1395 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0); 1396 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1397 return VERR_INVALID_PARAMETER; 1398 } 1399 if (!ppPicHlpR3) 1400 { 1401 Assert(ppPicHlpR3); 1402 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1403 return VERR_INVALID_PARAMETER; 1404 } 1405 1406 /* 1407 * Only one PIC device. 1408 */ 1409 PVM pVM = pDevIns->Internal.s.pVMR3; 1410 if (pVM->pdm.s.Pic.pDevInsR3) 1411 { 1412 AssertMsgFailed(("Only one pic device is supported!\n")); 1413 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1414 return VERR_INVALID_PARAMETER; 1415 } 1416 1417 /* 1418 * RC stuff. 1419 */ 1420 if (pPicReg->pszSetIrqRC) 1421 { 1422 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC); 1423 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, rc)); 1424 if (VBOX_SUCCESS(rc)) 1425 { 1426 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC); 1427 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, rc)); 1428 } 1429 if (VBOX_FAILURE(rc)) 1430 { 1431 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1432 return rc; 1433 } 1434 pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1435 } 1436 else 1437 { 1438 pVM->pdm.s.Pic.pDevInsRC = 0; 1439 pVM->pdm.s.Pic.pfnSetIrqRC = 0; 1440 pVM->pdm.s.Pic.pfnGetInterruptRC = 0; 1441 } 1442 1443 /* 1444 * R0 stuff. 1445 */ 1446 if (pPicReg->pszSetIrqR0) 1447 { 1448 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0); 1449 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc)); 1450 if (VBOX_SUCCESS(rc)) 1451 { 1452 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0); 1453 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc)); 1454 } 1455 if (VBOX_FAILURE(rc)) 1456 { 1457 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1458 return rc; 1459 } 1460 pVM->pdm.s.Pic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 1461 Assert(pVM->pdm.s.Pic.pDevInsR0); 1462 } 1463 else 1464 { 1465 pVM->pdm.s.Pic.pfnSetIrqR0 = 0; 1466 pVM->pdm.s.Pic.pfnGetInterruptR0 = 0; 1467 pVM->pdm.s.Pic.pDevInsR0 = 0; 1468 } 1469 1470 /* 1471 * R3 stuff. 1472 */ 1473 pVM->pdm.s.Pic.pDevInsR3 = pDevIns; 1474 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3; 1475 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3; 1476 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1477 1478 /* set the helper pointer and return. */ 1479 *ppPicHlpR3 = &g_pdmR3DevPicHlp; 1480 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 1481 return VINF_SUCCESS; 1482 } 1483 1484 1485 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 1486 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 1487 { 1488 PDMDEV_ASSERT_DEVINS(pDevIns); 1489 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1490 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, " 1491 ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, " 1492 ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n", 1493 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3, 1494 pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC, 1495 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC, 1496 pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC, 1497 pApicReg->pszBusDeliverRC, ppApicHlpR3)); 1498 1499 /* 1500 * Validate input. 1501 */ 1502 if (pApicReg->u32Version != PDM_APICREG_VERSION) 1503 { 1504 AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION)); 1505 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1506 return VERR_INVALID_PARAMETER; 1507 } 1508 if ( !pApicReg->pfnGetInterruptR3 1509 || !pApicReg->pfnHasPendingIrqR3 1510 || !pApicReg->pfnSetBaseR3 1511 || !pApicReg->pfnGetBaseR3 1512 || !pApicReg->pfnSetTPRR3 1513 || !pApicReg->pfnGetTPRR3 1514 || !pApicReg->pfnBusDeliverR3) 1515 { 1516 Assert(pApicReg->pfnGetInterruptR3); 1517 Assert(pApicReg->pfnHasPendingIrqR3); 1518 Assert(pApicReg->pfnSetBaseR3); 1519 Assert(pApicReg->pfnGetBaseR3); 1520 Assert(pApicReg->pfnSetTPRR3); 1521 Assert(pApicReg->pfnGetTPRR3); 1522 Assert(pApicReg->pfnBusDeliverR3); 1523 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1524 return VERR_INVALID_PARAMETER; 1525 } 1526 if ( ( pApicReg->pszGetInterruptRC 1527 || pApicReg->pszHasPendingIrqRC 1528 || pApicReg->pszSetBaseRC 1529 || pApicReg->pszGetBaseRC 1530 || pApicReg->pszSetTPRRC 1531 || pApicReg->pszGetTPRRC 1532 || pApicReg->pszBusDeliverRC) 1533 && ( !VALID_PTR(pApicReg->pszGetInterruptRC) 1534 || !VALID_PTR(pApicReg->pszHasPendingIrqRC) 1535 || !VALID_PTR(pApicReg->pszSetBaseRC) 1536 || !VALID_PTR(pApicReg->pszGetBaseRC) 1537 || !VALID_PTR(pApicReg->pszSetTPRRC) 1538 || !VALID_PTR(pApicReg->pszGetTPRRC) 1539 || !VALID_PTR(pApicReg->pszBusDeliverRC)) 1540 ) 1541 { 1542 Assert(VALID_PTR(pApicReg->pszGetInterruptRC)); 1543 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC)); 1544 Assert(VALID_PTR(pApicReg->pszSetBaseRC)); 1545 Assert(VALID_PTR(pApicReg->pszGetBaseRC)); 1546 Assert(VALID_PTR(pApicReg->pszSetTPRRC)); 1547 Assert(VALID_PTR(pApicReg->pszGetTPRRC)); 1548 Assert(VALID_PTR(pApicReg->pszBusDeliverRC)); 1549 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1550 return VERR_INVALID_PARAMETER; 1551 } 1552 if ( ( pApicReg->pszGetInterruptR0 1553 || pApicReg->pszHasPendingIrqR0 1554 || pApicReg->pszSetBaseR0 1555 || pApicReg->pszGetBaseR0 1556 || pApicReg->pszSetTPRR0 1557 || pApicReg->pszGetTPRR0 1558 || pApicReg->pszBusDeliverR0) 1559 && ( !VALID_PTR(pApicReg->pszGetInterruptR0) 1560 || !VALID_PTR(pApicReg->pszHasPendingIrqR0) 1561 || !VALID_PTR(pApicReg->pszSetBaseR0) 1562 || !VALID_PTR(pApicReg->pszGetBaseR0) 1563 || !VALID_PTR(pApicReg->pszSetTPRR0) 1564 || !VALID_PTR(pApicReg->pszGetTPRR0) 1565 || !VALID_PTR(pApicReg->pszBusDeliverR0)) 1566 ) 1567 { 1568 Assert(VALID_PTR(pApicReg->pszGetInterruptR0)); 1569 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0)); 1570 Assert(VALID_PTR(pApicReg->pszSetBaseR0)); 1571 Assert(VALID_PTR(pApicReg->pszGetBaseR0)); 1572 Assert(VALID_PTR(pApicReg->pszSetTPRR0)); 1573 Assert(VALID_PTR(pApicReg->pszGetTPRR0)); 1574 Assert(VALID_PTR(pApicReg->pszBusDeliverR0)); 1575 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1576 return VERR_INVALID_PARAMETER; 1577 } 1578 if (!ppApicHlpR3) 1579 { 1580 Assert(ppApicHlpR3); 1581 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1582 return VERR_INVALID_PARAMETER; 1583 } 1584 1585 /* 1586 * Only one APIC device. (malc: only in UP case actually) 1587 */ 1588 PVM pVM = pDevIns->Internal.s.pVMR3; 1589 if (pVM->pdm.s.Apic.pDevInsR3) 1590 { 1591 AssertMsgFailed(("Only one apic device is supported!\n")); 1592 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1593 return VERR_INVALID_PARAMETER; 1594 } 1595 1596 /* 1597 * Resolve & initialize the RC bits. 1598 */ 1599 if (pApicReg->pszGetInterruptRC) 1600 { 1601 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC); 1602 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, rc)); 1603 if (RT_SUCCESS(rc)) 1604 { 1605 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC); 1606 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc)); 1607 } 1608 if (RT_SUCCESS(rc)) 1609 { 1610 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC); 1611 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, rc)); 1612 } 1613 if (RT_SUCCESS(rc)) 1614 { 1615 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC); 1616 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, rc)); 1617 } 1618 if (RT_SUCCESS(rc)) 1619 { 1620 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC); 1621 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, rc)); 1622 } 1623 if (RT_SUCCESS(rc)) 1624 { 1625 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC); 1626 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc)); 1627 } 1628 if (RT_SUCCESS(rc)) 1629 { 1630 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC); 1631 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc)); 1632 } 1633 if (VBOX_FAILURE(rc)) 1634 { 1635 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1636 return rc; 1637 } 1638 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1639 } 1640 else 1641 { 1642 pVM->pdm.s.Apic.pDevInsRC = 0; 1643 pVM->pdm.s.Apic.pfnGetInterruptRC = 0; 1644 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0; 1645 pVM->pdm.s.Apic.pfnSetBaseRC = 0; 1646 pVM->pdm.s.Apic.pfnGetBaseRC = 0; 1647 pVM->pdm.s.Apic.pfnSetTPRRC = 0; 1648 pVM->pdm.s.Apic.pfnGetTPRRC = 0; 1649 pVM->pdm.s.Apic.pfnBusDeliverRC = 0; 1650 } 1651 1652 /* 1653 * Resolve & initialize the R0 bits. 1654 */ 1655 if (pApicReg->pszGetInterruptR0) 1656 { 1657 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0); 1658 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc)); 1659 if (RT_SUCCESS(rc)) 1660 { 1661 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0); 1662 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc)); 1663 } 1664 if (RT_SUCCESS(rc)) 1665 { 1666 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0); 1667 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc)); 1668 } 1669 if (RT_SUCCESS(rc)) 1670 { 1671 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0); 1672 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc)); 1673 } 1674 if (RT_SUCCESS(rc)) 1675 { 1676 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0); 1677 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc)); 1678 } 1679 if (RT_SUCCESS(rc)) 1680 { 1681 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0); 1682 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc)); 1683 } 1684 if (RT_SUCCESS(rc)) 1685 { 1686 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0); 1687 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc)); 1688 } 1689 if (VBOX_FAILURE(rc)) 1690 { 1691 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1692 return rc; 1693 } 1694 pVM->pdm.s.Apic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 1695 Assert(pVM->pdm.s.Apic.pDevInsR0); 1696 } 1697 else 1698 { 1699 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0; 1700 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0; 1701 pVM->pdm.s.Apic.pfnSetBaseR0 = 0; 1702 pVM->pdm.s.Apic.pfnGetBaseR0 = 0; 1703 pVM->pdm.s.Apic.pfnSetTPRR0 = 0; 1704 pVM->pdm.s.Apic.pfnGetTPRR0 = 0; 1705 pVM->pdm.s.Apic.pfnBusDeliverR0 = 0; 1706 pVM->pdm.s.Apic.pDevInsR0 = 0; 1707 } 1708 1709 /* 1710 * Initialize the HC bits. 1711 */ 1712 pVM->pdm.s.Apic.pDevInsR3 = pDevIns; 1713 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3; 1714 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3; 1715 pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3; 1716 pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3; 1717 pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3; 1718 pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3; 1719 pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3; 1720 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1721 1722 /* set the helper pointer and return. */ 1723 *ppApicHlpR3 = &g_pdmR3DevApicHlp; 1724 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 1725 return VINF_SUCCESS; 1726 } 1727 1728 1729 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 1730 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 1731 { 1732 PDMDEV_ASSERT_DEVINS(pDevIns); 1733 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1734 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n", 1735 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3, 1736 pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3)); 1737 1738 /* 1739 * Validate input. 1740 */ 1741 if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION) 1742 { 1743 AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION)); 1744 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1745 return VERR_INVALID_PARAMETER; 1746 } 1747 if (!pIoApicReg->pfnSetIrqR3) 1748 { 1749 Assert(pIoApicReg->pfnSetIrqR3); 1750 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1751 return VERR_INVALID_PARAMETER; 1752 } 1753 if ( pIoApicReg->pszSetIrqRC 1754 && !VALID_PTR(pIoApicReg->pszSetIrqRC)) 1755 { 1756 Assert(VALID_PTR(pIoApicReg->pszSetIrqRC)); 1757 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1758 return VERR_INVALID_PARAMETER; 1759 } 1760 if ( pIoApicReg->pszSetIrqR0 1761 && !VALID_PTR(pIoApicReg->pszSetIrqR0)) 1762 { 1763 Assert(VALID_PTR(pIoApicReg->pszSetIrqR0)); 1764 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1765 return VERR_INVALID_PARAMETER; 1766 } 1767 if (!ppIoApicHlpR3) 1768 { 1769 Assert(ppIoApicHlpR3); 1770 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1771 return VERR_INVALID_PARAMETER; 1772 } 1773 1774 /* 1775 * The I/O APIC requires the APIC to be present (hacks++). 1776 * If the I/O APIC does GC stuff so must the APIC. 1777 */ 1778 PVM pVM = pDevIns->Internal.s.pVMR3; 1779 if (!pVM->pdm.s.Apic.pDevInsR3) 1780 { 1781 AssertMsgFailed(("Configuration error / Init order error! No APIC!\n")); 1782 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1783 return VERR_INVALID_PARAMETER; 1784 } 1785 if ( pIoApicReg->pszSetIrqRC 1786 && !pVM->pdm.s.Apic.pDevInsRC) 1787 { 1788 AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n")); 1789 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1790 return VERR_INVALID_PARAMETER; 1791 } 1792 1793 /* 1794 * Only one I/O APIC device. 1795 */ 1796 if (pVM->pdm.s.IoApic.pDevInsR3) 1797 { 1798 AssertMsgFailed(("Only one ioapic device is supported!\n")); 1799 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1800 return VERR_INVALID_PARAMETER; 1801 } 1802 1803 /* 1804 * Resolve & initialize the GC bits. 1805 */ 1806 if (pIoApicReg->pszSetIrqRC) 1807 { 1808 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC); 1809 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, rc)); 1810 if (VBOX_FAILURE(rc)) 1811 { 1812 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1813 return rc; 1814 } 1815 pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1816 } 1817 else 1818 { 1819 pVM->pdm.s.IoApic.pDevInsRC = 0; 1820 pVM->pdm.s.IoApic.pfnSetIrqRC = 0; 1821 } 1822 1823 /* 1824 * Resolve & initialize the R0 bits. 1825 */ 1826 if (pIoApicReg->pszSetIrqR0) 1827 { 1828 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0); 1829 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc)); 1830 if (VBOX_FAILURE(rc)) 1831 { 1832 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1833 return rc; 1834 } 1835 pVM->pdm.s.IoApic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 1836 Assert(pVM->pdm.s.IoApic.pDevInsR0); 1837 } 1838 else 1839 { 1840 pVM->pdm.s.IoApic.pfnSetIrqR0 = 0; 1841 pVM->pdm.s.IoApic.pDevInsR0 = 0; 1842 } 1843 1844 /* 1845 * Initialize the R3 bits. 1846 */ 1847 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns; 1848 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3; 1849 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1850 1851 /* set the helper pointer and return. */ 1852 *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp; 1853 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 1854 return VINF_SUCCESS; 1855 } 1856 1857 1858 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 1859 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 1860 { 1861 PDMDEV_ASSERT_DEVINS(pDevIns); 1862 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1863 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n", 1864 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister, 1865 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp)); 1866 1867 /* 1868 * Validate input. 1869 */ 1870 if (pDmacReg->u32Version != PDM_DMACREG_VERSION) 1871 { 1872 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version, 1873 PDM_DMACREG_VERSION)); 1874 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n", 1875 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1876 return VERR_INVALID_PARAMETER; 1877 } 1878 if ( !pDmacReg->pfnRun 1879 || !pDmacReg->pfnRegister 1880 || !pDmacReg->pfnReadMemory 1881 || !pDmacReg->pfnWriteMemory 1882 || !pDmacReg->pfnSetDREQ 1883 || !pDmacReg->pfnGetChannelMode) 1884 { 1885 Assert(pDmacReg->pfnRun); 1886 Assert(pDmacReg->pfnRegister); 1887 Assert(pDmacReg->pfnReadMemory); 1888 Assert(pDmacReg->pfnWriteMemory); 1889 Assert(pDmacReg->pfnSetDREQ); 1890 Assert(pDmacReg->pfnGetChannelMode); 1891 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 1892 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1893 return VERR_INVALID_PARAMETER; 1894 } 1895 1896 if (!ppDmacHlp) 1897 { 1898 Assert(ppDmacHlp); 1899 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n", 1900 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1901 return VERR_INVALID_PARAMETER; 1902 } 1903 1904 /* 1905 * Only one DMA device. 1906 */ 1907 PVM pVM = pDevIns->Internal.s.pVMR3; 1908 if (pVM->pdm.s.pDmac) 1909 { 1910 AssertMsgFailed(("Only one DMA device is supported!\n")); 1911 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 1912 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1913 return VERR_INVALID_PARAMETER; 1914 } 1915 1916 /* 1917 * Allocate and initialize pci bus structure. 1918 */ 1919 int rc = VINF_SUCCESS; 1920 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac)); 1921 if (pDmac) 1922 { 1923 pDmac->pDevIns = pDevIns; 1924 pDmac->Reg = *pDmacReg; 1925 pVM->pdm.s.pDmac = pDmac; 1926 1927 /* set the helper pointer. */ 1928 *ppDmacHlp = &g_pdmR3DevDmacHlp; 1929 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n", 1930 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 1931 } 1932 else 1933 rc = VERR_NO_MEMORY; 1934 1935 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 1936 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1937 return rc; 1938 } 1939 1940 1941 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 1942 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 1943 { 1944 PDMDEV_ASSERT_DEVINS(pDevIns); 1945 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n", 1946 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead)); 1947 1948 /* 1949 * For the convenience of the device we put no thread restriction on this interface. 1950 * That means we'll have to check which thread we're in and choose our path. 1951 */ 1952 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 1953 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 1954 #else 1955 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 1956 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 1957 else 1958 { 1959 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1960 PVMREQ pReq; 1961 AssertCompileSize(RTGCPHYS, 4); 1962 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 1963 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 1964 while (rc == VERR_TIMEOUT) 1965 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 1966 AssertReleaseRC(rc); 1967 VMR3ReqFree(pReq); 1968 } 1969 #endif 1970 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1971 } 1972 1973 1974 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 1975 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 1976 { 1977 PDMDEV_ASSERT_DEVINS(pDevIns); 1978 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n", 1979 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite)); 1980 1981 /* 1982 * For the convenience of the device we put no thread restriction on this interface. 1983 * That means we'll have to check which thread we're in and choose our path. 1984 */ 1985 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 1986 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 1987 #else 1988 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 1989 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 1990 else 1991 { 1992 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1993 PVMREQ pReq; 1994 AssertCompileSize(RTGCPHYS, 4); 1995 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 1996 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 1997 while (rc == VERR_TIMEOUT) 1998 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 1999 AssertReleaseRC(rc); 2000 VMR3ReqFree(pReq); 2001 } 2002 #endif 2003 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2004 } 2005 2006 2007 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 2008 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 2009 { 2010 PDMDEV_ASSERT_DEVINS(pDevIns); 2011 PVM pVM = pDevIns->Internal.s.pVMR3; 2012 VM_ASSERT_EMT(pVM); 2013 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n", 2014 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb)); 2015 2016 if (!VM_IS_EMT(pVM)) 2017 return VERR_ACCESS_DENIED; 2018 2019 int rc = PGMPhysReadGCPtr(pVM, pvDst, GCVirtSrc, cb); 2020 2021 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2022 2023 return rc; 2024 } 2025 2026 2027 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 2028 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 2029 { 2030 PDMDEV_ASSERT_DEVINS(pDevIns); 2031 PVM pVM = pDevIns->Internal.s.pVMR3; 2032 VM_ASSERT_EMT(pVM); 2033 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n", 2034 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb)); 2035 2036 if (!VM_IS_EMT(pVM)) 2037 return VERR_ACCESS_DENIED; 2038 2039 int rc = PGMPhysWriteGCPtr(pVM, GCVirtDst, pvSrc, cb); 2040 2041 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2042 2043 return rc; 2044 } 2045 2046 2047 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 2048 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 2049 { 2050 PDMDEV_ASSERT_DEVINS(pDevIns); 2051 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2052 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n", 2053 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc)); 2054 2055 int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMR3, GCPhys, cbRange, pszDesc); 2056 2057 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2058 2059 return rc; 2060 } 2061 2062 2063 /** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */ 2064 static DECLCALLBACK(int) pdmR3DevHlp_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC) 2065 { 2066 PDMDEV_ASSERT_DEVINS(pDevIns); 2067 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2068 NOREF(GCPhys); 2069 NOREF(cbRange); 2070 NOREF(ppvHC); 2071 return VERR_ACCESS_DENIED; 2072 } 2073 2074 2075 /** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */ 2076 static DECLCALLBACK(int) pdmR3DevHlp_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr) 2077 { 2078 PDMDEV_ASSERT_DEVINS(pDevIns); 2079 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2080 NOREF(GCPtr); 2081 NOREF(pHCPtr); 2082 return VERR_ACCESS_DENIED; 2083 } 2084 2085 2086 /** @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys */ 2087 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys) 2088 { 2089 PDMDEV_ASSERT_DEVINS(pDevIns); 2090 PVM pVM = pDevIns->Internal.s.pVMR3; 2091 VM_ASSERT_EMT(pVM); 2092 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n", 2093 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys)); 2094 2095 if (!VM_IS_EMT(pVM)) 2096 return VERR_ACCESS_DENIED; 2097 2098 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys); 2099 2100 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys)); 2101 2102 return rc; 2103 } 2104 2105 2106 /** @copydoc PDMDEVHLPR3::pfnVMState */ 2107 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns) 2108 { 2109 PDMDEV_ASSERT_DEVINS(pDevIns); 2110 2111 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3); 2112 2113 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 2114 enmVMState, VMR3GetStateName(enmVMState))); 2115 return enmVMState; 2116 } 2117 2118 2119 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 2120 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns) 2121 { 2122 PDMDEV_ASSERT_DEVINS(pDevIns); 2123 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2124 2125 bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMR3); 2126 2127 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc)); 2128 return fRc; 2129 } 2130 2131 2132 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 2133 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable) 2134 { 2135 PDMDEV_ASSERT_DEVINS(pDevIns); 2136 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2137 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable)); 2138 //Assert(*(unsigned *)&fEnable <= 1); 2139 PGMR3PhysSetA20(pDevIns->Internal.s.pVMR3, fEnable); 2140 } 2141 2142 2143 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 2144 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns) 2145 { 2146 PDMDEV_ASSERT_DEVINS(pDevIns); 2147 PVM pVM = pDevIns->Internal.s.pVMR3; 2148 VM_ASSERT_EMT(pVM); 2149 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n", 2150 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET))); 2151 2152 /* 2153 * We postpone this operation because we're likely to be inside a I/O instruction 2154 * and the EIP will be updated when we return. 2155 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation. 2156 */ 2157 bool fHaltOnReset; 2158 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset); 2159 if (VBOX_SUCCESS(rc) && fHaltOnReset) 2160 { 2161 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n")); 2162 rc = VINF_EM_HALT; 2163 } 2164 else 2165 { 2166 VM_FF_SET(pVM, VM_FF_RESET); 2167 rc = VINF_EM_RESET; 2168 } 2169 2170 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2171 return rc; 2172 } 2173 2174 2175 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 2176 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns) 2177 { 2178 PDMDEV_ASSERT_DEVINS(pDevIns); 2179 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2180 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n", 2181 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2182 2183 int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3); 2184 2185 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2186 return rc; 2187 } 2188 2189 2190 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 2191 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns) 2192 { 2193 PDMDEV_ASSERT_DEVINS(pDevIns); 2194 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2195 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n", 2196 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2197 2198 int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3); 2199 2200 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2201 return rc; 2202 } 2203 2204 2205 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 2206 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns) 2207 { 2208 return VMMR3Lock(pDevIns->Internal.s.pVMR3); 2209 } 2210 2211 2212 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 2213 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns) 2214 { 2215 return VMMR3Unlock(pDevIns->Internal.s.pVMR3); 2216 } 2217 2218 2219 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 2220 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2221 { 2222 PVM pVM = pDevIns->Internal.s.pVMR3; 2223 if (VMMR3LockIsOwner(pVM)) 2224 return true; 2225 2226 RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM); 2227 RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner); 2228 char szMsg[100]; 2229 RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n", 2230 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 2231 NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName()); 2232 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 2233 AssertBreakpoint(); 2234 return false; 2235 } 2236 2237 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 2238 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 2239 { 2240 PDMDEV_ASSERT_DEVINS(pDevIns); 2241 PVM pVM = pDevIns->Internal.s.pVMR3; 2242 VM_ASSERT_EMT(pVM); 2243 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n", 2244 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser)); 2245 int rc = VINF_SUCCESS; 2246 if (pVM->pdm.s.pDmac) 2247 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser); 2248 else 2249 { 2250 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2251 rc = VERR_PDM_NO_DMAC_INSTANCE; 2252 } 2253 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n", 2254 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2255 return rc; 2256 } 2257 2258 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 2259 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 2260 { 2261 PDMDEV_ASSERT_DEVINS(pDevIns); 2262 PVM pVM = pDevIns->Internal.s.pVMR3; 2263 VM_ASSERT_EMT(pVM); 2264 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n", 2265 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead)); 2266 int rc = VINF_SUCCESS; 2267 if (pVM->pdm.s.pDmac) 2268 { 2269 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 2270 if (pcbRead) 2271 *pcbRead = cb; 2272 } 2273 else 2274 { 2275 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2276 rc = VERR_PDM_NO_DMAC_INSTANCE; 2277 } 2278 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n", 2279 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2280 return rc; 2281 } 2282 2283 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 2284 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 2285 { 2286 PDMDEV_ASSERT_DEVINS(pDevIns); 2287 PVM pVM = pDevIns->Internal.s.pVMR3; 2288 VM_ASSERT_EMT(pVM); 2289 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n", 2290 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten)); 2291 int rc = VINF_SUCCESS; 2292 if (pVM->pdm.s.pDmac) 2293 { 2294 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 2295 if (pcbWritten) 2296 *pcbWritten = cb; 2297 } 2298 else 2299 { 2300 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2301 rc = VERR_PDM_NO_DMAC_INSTANCE; 2302 } 2303 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n", 2304 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2305 return rc; 2306 } 2307 2308 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 2309 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 2310 { 2311 PDMDEV_ASSERT_DEVINS(pDevIns); 2312 PVM pVM = pDevIns->Internal.s.pVMR3; 2313 VM_ASSERT_EMT(pVM); 2314 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n", 2315 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel)); 2316 int rc = VINF_SUCCESS; 2317 if (pVM->pdm.s.pDmac) 2318 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel); 2319 else 2320 { 2321 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2322 rc = VERR_PDM_NO_DMAC_INSTANCE; 2323 } 2324 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n", 2325 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2326 return rc; 2327 } 2328 2329 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 2330 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 2331 { 2332 PDMDEV_ASSERT_DEVINS(pDevIns); 2333 PVM pVM = pDevIns->Internal.s.pVMR3; 2334 VM_ASSERT_EMT(pVM); 2335 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n", 2336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel)); 2337 uint8_t u8Mode; 2338 if (pVM->pdm.s.pDmac) 2339 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel); 2340 else 2341 { 2342 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2343 u8Mode = 3 << 2 /* illegal mode type */; 2344 } 2345 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n", 2346 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode)); 2347 return u8Mode; 2348 } 2349 2350 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 2351 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns) 2352 { 2353 PDMDEV_ASSERT_DEVINS(pDevIns); 2354 PVM pVM = pDevIns->Internal.s.pVMR3; 2355 VM_ASSERT_EMT(pVM); 2356 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n", 2357 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA))); 2358 2359 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 2360 VM_FF_SET(pVM, VM_FF_PDM_DMA); 2361 REMR3NotifyDmaPending(pVM); 2362 VMR3NotifyFF(pVM, true); 2363 } 2364 2365 2366 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 2367 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 2368 { 2369 PDMDEV_ASSERT_DEVINS(pDevIns); 2370 PVM pVM = pDevIns->Internal.s.pVMR3; 2371 VM_ASSERT_EMT(pVM); 2372 2373 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n", 2374 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value)); 2375 int rc; 2376 if (pVM->pdm.s.pRtc) 2377 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value); 2378 else 2379 rc = VERR_PDM_NO_RTC_INSTANCE; 2380 2381 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 2382 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2383 return rc; 2384 } 2385 2386 2387 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 2388 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 2389 { 2390 PDMDEV_ASSERT_DEVINS(pDevIns); 2391 PVM pVM = pDevIns->Internal.s.pVMR3; 2392 VM_ASSERT_EMT(pVM); 2393 2394 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n", 2395 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value)); 2396 int rc; 2397 if (pVM->pdm.s.pRtc) 2398 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value); 2399 else 2400 rc = VERR_PDM_NO_RTC_INSTANCE; 2401 2402 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 2403 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2404 return rc; 2405 } 2406 2407 2408 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 2409 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 2410 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 2411 { 2412 PDMDEV_ASSERT_DEVINS(pDevIns); 2413 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n", 2414 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx)); 2415 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx); 2416 2417 CPUMGetGuestCpuId(pDevIns->Internal.s.pVMR3, iLeaf, pEax, pEbx, pEcx, pEdx); 2418 2419 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n", 2420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx)); 2421 } 2422 2423 2424 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 2425 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 2426 { 2427 PDMDEV_ASSERT_DEVINS(pDevIns); 2428 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 2429 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 2430 2431 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange); 2432 2433 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2434 return rc; 2435 } 2436 2437 2438 /** 2439 * @copydoc PDMDEVHLPR3::pfnMMIO2Register 2440 */ 2441 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 2442 { 2443 PDMDEV_ASSERT_DEVINS(pDevIns); 2444 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2445 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n", 2446 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc)); 2447 2448 int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc); 2449 2450 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2451 return rc; 2452 } 2453 2454 2455 /** 2456 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister 2457 */ 2458 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 2459 { 2460 PDMDEV_ASSERT_DEVINS(pDevIns); 2461 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2462 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n", 2463 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion)); 2464 2465 AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER); 2466 2467 int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion); 2468 2469 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2470 return rc; 2471 } 2472 2473 2474 /** 2475 * @copydoc PDMDEVHLPR3::pfnMMIO2Map 2476 */ 2477 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 2478 { 2479 PDMDEV_ASSERT_DEVINS(pDevIns); 2480 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2481 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 2482 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 2483 2484 int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 2485 2486 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2487 return rc; 2488 } 2489 2490 2491 /** 2492 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap 2493 */ 2494 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 2495 { 2496 PDMDEV_ASSERT_DEVINS(pDevIns); 2497 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2498 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 2499 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 2500 2501 int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 2502 2503 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2504 return rc; 2505 } 2506 2507 2508 /** 2509 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 2510 */ 2511 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, 2512 const char *pszDesc, PRTRCPTR pRCPtr) 2513 { 2514 PDMDEV_ASSERT_DEVINS(pDevIns); 2515 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2516 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n", 2517 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr)); 2518 2519 int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, off, cb, pszDesc, pRCPtr); 2520 2521 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr)); 2522 return rc; 2523 } 2524 2525 2526 /** 2527 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap 2528 */ 2529 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 2530 { 2531 PDMDEV_ASSERT_DEVINS(pDevIns); 2532 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2533 2534 int rc = PDMR3RegisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys, pvHeap, cbSize); 2535 return rc; 2536 } 2537 2538 2539 /** 2540 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap 2541 */ 2542 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 2543 { 2544 PDMDEV_ASSERT_DEVINS(pDevIns); 2545 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2546 2547 int rc = PDMR3UnregisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys); 2548 return rc; 2549 } 2550 2551 298 2552 /** 299 2553 * The device helper structure for trusted devices. … … 361 2615 pdmR3DevHlp_PhysWriteGCVirt, 362 2616 pdmR3DevHlp_PhysReserve, 363 pdmR3DevHlp_ Untrusted_Obsolete_Phys2HCVirt,364 pdmR3DevHlp_ Untrusted_Obsolete_PhysGCPtr2HCPtr,2617 pdmR3DevHlp_Obsolete_Phys2HCVirt, 2618 pdmR3DevHlp_Obsolete_PhysGCPtr2HCPtr, 365 2619 pdmR3DevHlp_A20IsEnabled, 366 2620 pdmR3DevHlp_A20Set, … … 390 2644 PDM_DEVHLP_VERSION /* the end */ 391 2645 }; 2646 2647 2648 2649 2650 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 2651 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns) 2652 { 2653 PDMDEV_ASSERT_DEVINS(pDevIns); 2654 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2655 return NULL; 2656 } 2657 2658 2659 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 2660 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 2661 { 2662 PDMDEV_ASSERT_DEVINS(pDevIns); 2663 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2664 NOREF(pPciBusReg); 2665 NOREF(ppPciHlpR3); 2666 return VERR_ACCESS_DENIED; 2667 } 2668 2669 2670 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 2671 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 2672 { 2673 PDMDEV_ASSERT_DEVINS(pDevIns); 2674 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2675 NOREF(pPicReg); 2676 NOREF(ppPicHlpR3); 2677 return VERR_ACCESS_DENIED; 2678 } 2679 2680 2681 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 2682 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 2683 { 2684 PDMDEV_ASSERT_DEVINS(pDevIns); 2685 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2686 NOREF(pApicReg); 2687 NOREF(ppApicHlpR3); 2688 return VERR_ACCESS_DENIED; 2689 } 2690 2691 2692 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 2693 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 2694 { 2695 PDMDEV_ASSERT_DEVINS(pDevIns); 2696 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2697 NOREF(pIoApicReg); 2698 NOREF(ppIoApicHlpR3); 2699 return VERR_ACCESS_DENIED; 2700 } 2701 2702 2703 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 2704 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 2705 { 2706 PDMDEV_ASSERT_DEVINS(pDevIns); 2707 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2708 NOREF(pDmacReg); 2709 NOREF(ppDmacHlp); 2710 return VERR_ACCESS_DENIED; 2711 } 2712 2713 2714 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 2715 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 2716 { 2717 PDMDEV_ASSERT_DEVINS(pDevIns); 2718 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2719 NOREF(GCPhys); 2720 NOREF(pvBuf); 2721 NOREF(cbRead); 2722 } 2723 2724 2725 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 2726 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 2727 { 2728 PDMDEV_ASSERT_DEVINS(pDevIns); 2729 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2730 NOREF(GCPhys); 2731 NOREF(pvBuf); 2732 NOREF(cbWrite); 2733 } 2734 2735 2736 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 2737 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 2738 { 2739 PDMDEV_ASSERT_DEVINS(pDevIns); 2740 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2741 NOREF(pvDst); 2742 NOREF(GCVirtSrc); 2743 NOREF(cb); 2744 return VERR_ACCESS_DENIED; 2745 } 2746 2747 2748 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 2749 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 2750 { 2751 PDMDEV_ASSERT_DEVINS(pDevIns); 2752 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2753 NOREF(GCVirtDst); 2754 NOREF(pvSrc); 2755 NOREF(cb); 2756 return VERR_ACCESS_DENIED; 2757 } 2758 2759 2760 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 2761 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 2762 { 2763 PDMDEV_ASSERT_DEVINS(pDevIns); 2764 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2765 NOREF(GCPhys); 2766 NOREF(cbRange); 2767 return VERR_ACCESS_DENIED; 2768 } 2769 2770 2771 /** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */ 2772 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC) 2773 { 2774 PDMDEV_ASSERT_DEVINS(pDevIns); 2775 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2776 NOREF(GCPhys); 2777 NOREF(cbRange); 2778 NOREF(ppvHC); 2779 return VERR_ACCESS_DENIED; 2780 } 2781 2782 2783 /** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */ 2784 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr) 2785 { 2786 PDMDEV_ASSERT_DEVINS(pDevIns); 2787 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2788 NOREF(GCPtr); 2789 NOREF(pHCPtr); 2790 return VERR_ACCESS_DENIED; 2791 } 2792 2793 2794 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 2795 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns) 2796 { 2797 PDMDEV_ASSERT_DEVINS(pDevIns); 2798 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2799 return false; 2800 } 2801 2802 2803 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 2804 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable) 2805 { 2806 PDMDEV_ASSERT_DEVINS(pDevIns); 2807 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2808 NOREF(fEnable); 2809 } 2810 2811 2812 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 2813 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns) 2814 { 2815 PDMDEV_ASSERT_DEVINS(pDevIns); 2816 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2817 return VERR_ACCESS_DENIED; 2818 } 2819 2820 2821 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 2822 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns) 2823 { 2824 PDMDEV_ASSERT_DEVINS(pDevIns); 2825 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2826 return VERR_ACCESS_DENIED; 2827 } 2828 2829 2830 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 2831 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns) 2832 { 2833 PDMDEV_ASSERT_DEVINS(pDevIns); 2834 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2835 return VERR_ACCESS_DENIED; 2836 } 2837 2838 2839 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 2840 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns) 2841 { 2842 PDMDEV_ASSERT_DEVINS(pDevIns); 2843 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2844 return VERR_ACCESS_DENIED; 2845 } 2846 2847 2848 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 2849 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns) 2850 { 2851 PDMDEV_ASSERT_DEVINS(pDevIns); 2852 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2853 return VERR_ACCESS_DENIED; 2854 } 2855 2856 2857 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 2858 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2859 { 2860 PDMDEV_ASSERT_DEVINS(pDevIns); 2861 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2862 return false; 2863 } 2864 2865 2866 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 2867 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 2868 { 2869 PDMDEV_ASSERT_DEVINS(pDevIns); 2870 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2871 return VERR_ACCESS_DENIED; 2872 } 2873 2874 2875 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 2876 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 2877 { 2878 PDMDEV_ASSERT_DEVINS(pDevIns); 2879 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2880 if (pcbRead) 2881 *pcbRead = 0; 2882 return VERR_ACCESS_DENIED; 2883 } 2884 2885 2886 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 2887 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 2888 { 2889 PDMDEV_ASSERT_DEVINS(pDevIns); 2890 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2891 if (pcbWritten) 2892 *pcbWritten = 0; 2893 return VERR_ACCESS_DENIED; 2894 } 2895 2896 2897 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 2898 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 2899 { 2900 PDMDEV_ASSERT_DEVINS(pDevIns); 2901 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2902 return VERR_ACCESS_DENIED; 2903 } 2904 2905 2906 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 2907 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 2908 { 2909 PDMDEV_ASSERT_DEVINS(pDevIns); 2910 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2911 return 3 << 2 /* illegal mode type */; 2912 } 2913 2914 2915 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 2916 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns) 2917 { 2918 PDMDEV_ASSERT_DEVINS(pDevIns); 2919 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2920 } 2921 2922 2923 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 2924 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 2925 { 2926 PDMDEV_ASSERT_DEVINS(pDevIns); 2927 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2928 return VERR_ACCESS_DENIED; 2929 } 2930 2931 2932 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 2933 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 2934 { 2935 PDMDEV_ASSERT_DEVINS(pDevIns); 2936 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2937 return VERR_ACCESS_DENIED; 2938 } 2939 2940 2941 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 2942 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 2943 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 2944 { 2945 PDMDEV_ASSERT_DEVINS(pDevIns); 2946 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2947 } 2948 2949 2950 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 2951 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 2952 { 2953 PDMDEV_ASSERT_DEVINS(pDevIns); 2954 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2955 return VERR_ACCESS_DENIED; 2956 } 2957 2958 2959 /** @copydoc PDMDEVHLPR3::pfnMMIO2Register */ 2960 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 2961 { 2962 PDMDEV_ASSERT_DEVINS(pDevIns); 2963 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2964 return VERR_ACCESS_DENIED; 2965 } 2966 2967 2968 /** @copydoc PDMDEVHLPR3::pfnMMIO2Deregister */ 2969 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 2970 { 2971 PDMDEV_ASSERT_DEVINS(pDevIns); 2972 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2973 return VERR_ACCESS_DENIED; 2974 } 2975 2976 2977 /** @copydoc PDMDEVHLPR3::pfnMMIO2Map */ 2978 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 2979 { 2980 PDMDEV_ASSERT_DEVINS(pDevIns); 2981 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2982 return VERR_ACCESS_DENIED; 2983 } 2984 2985 2986 /** @copydoc PDMDEVHLPR3::pfnMMIO2Unmap */ 2987 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 2988 { 2989 PDMDEV_ASSERT_DEVINS(pDevIns); 2990 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2991 return VERR_ACCESS_DENIED; 2992 } 2993 2994 2995 /** @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 */ 2996 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr) 2997 { 2998 PDMDEV_ASSERT_DEVINS(pDevIns); 2999 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3000 return VERR_ACCESS_DENIED; 3001 } 3002 3003 3004 /** @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap */ 3005 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 3006 { 3007 PDMDEV_ASSERT_DEVINS(pDevIns); 3008 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3009 return VERR_ACCESS_DENIED; 3010 } 3011 3012 3013 /** @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap */ 3014 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 3015 { 3016 PDMDEV_ASSERT_DEVINS(pDevIns); 3017 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3018 return VERR_ACCESS_DENIED; 3019 } 392 3020 393 3021 … … 488 3116 489 3117 490 /**491 * PIC Device Helpers.492 */493 const PDMPICHLPR3 g_pdmR3DevPicHlp =494 {495 PDM_PICHLPR3_VERSION,496 pdmR3PicHlp_SetInterruptFF,497 pdmR3PicHlp_ClearInterruptFF,498 pdmR3PicHlp_Lock,499 pdmR3PicHlp_Unlock,500 pdmR3PicHlp_GetRCHelpers,501 pdmR3PicHlp_GetR0Helpers,502 PDM_PICHLPR3_VERSION /* the end */503 };504 505 506 /**507 * APIC Device Helpers.508 */509 const PDMAPICHLPR3 g_pdmR3DevApicHlp =510 {511 PDM_APICHLPR3_VERSION,512 pdmR3ApicHlp_SetInterruptFF,513 pdmR3ApicHlp_ClearInterruptFF,514 pdmR3ApicHlp_ChangeFeature,515 pdmR3ApicHlp_Lock,516 pdmR3ApicHlp_Unlock,517 pdmR3ApicHlp_GetCpuId,518 pdmR3ApicHlp_GetRCHelpers,519 pdmR3ApicHlp_GetR0Helpers,520 PDM_APICHLPR3_VERSION /* the end */521 };522 523 524 /**525 * I/O APIC Device Helpers.526 */527 const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =528 {529 PDM_IOAPICHLPR3_VERSION,530 pdmR3IoApicHlp_ApicBusDeliver,531 pdmR3IoApicHlp_Lock,532 pdmR3IoApicHlp_Unlock,533 pdmR3IoApicHlp_GetRCHelpers,534 pdmR3IoApicHlp_GetR0Helpers,535 PDM_IOAPICHLPR3_VERSION /* the end */536 };537 538 539 /**540 * PCI Bus Device Helpers.541 */542 const PDMPCIHLPR3 g_pdmR3DevPciHlp =543 {544 PDM_PCIHLPR3_VERSION,545 pdmR3PciHlp_IsaSetIrq,546 pdmR3PciHlp_IoApicSetIrq,547 pdmR3PciHlp_IsMMIO2Base,548 pdmR3PciHlp_GetRCHelpers,549 pdmR3PciHlp_GetR0Helpers,550 pdmR3PciHlp_Lock,551 pdmR3PciHlp_Unlock,552 PDM_PCIHLPR3_VERSION, /* the end */553 };554 555 556 /**557 * DMAC Device Helpers.558 */559 const PDMDMACHLP g_pdmR3DevDmacHlp =560 {561 PDM_DMACHLP_VERSION562 };563 564 565 /**566 * RTC Device Helpers.567 */568 const PDMRTCHLP g_pdmR3DevRtcHlp =569 {570 PDM_RTCHLP_VERSION571 };572 573 574 575 /**576 * This function will initialize the devices for this VM instance.577 *578 *579 * First of all this mean loading the builtin device and letting them580 * register themselves. Beyond that any additional device modules are581 * loaded and called for registration.582 *583 * Then the device configuration is enumerated, the instantiation order584 * is determined, and finally they are instantiated.585 *586 * After all device have been successfully instantiated the the primary587 * PCI Bus device is called to emulate the PCI BIOS, i.e. making the588 * resource assignments. If there is no PCI device, this step is of course589 * skipped.590 *591 * Finally the init completion routines of the instantiated devices592 * are called.593 *594 * @returns VBox status code.595 * @param pVM VM Handle.596 */597 int pdmR3DevInit(PVM pVM)598 {599 LogFlow(("pdmR3DevInit:\n"));600 601 AssertRelease(!(RT_OFFSETOF(PDMDEVINS, achInstanceData) & 15));602 AssertRelease(sizeof(pVM->pdm.s.pDevInstances->Internal.s) <= sizeof(pVM->pdm.s.pDevInstances->Internal.padding));603 604 /*605 * Load device modules.606 */607 int rc = pdmR3DevLoadModules(pVM);608 if (RT_FAILURE(rc))609 return rc;610 611 #ifdef VBOX_WITH_USB612 /* ditto for USB Devices. */613 rc = pdmR3UsbLoadModules(pVM);614 if (RT_FAILURE(rc))615 return rc;616 #endif617 618 /*619 * Get the RC & R0 devhlps and create the devhlp R3 task queue.620 */621 PCPDMDEVHLPRC pDevHlpRC;622 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCDevHlp", &pDevHlpRC);623 AssertReleaseRCReturn(rc, rc);624 625 PCPDMDEVHLPR0 pDevHlpR0;626 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0DevHlp", &pDevHlpR0);627 AssertReleaseRCReturn(rc, rc);628 629 rc = PDMR3QueueCreateInternal(pVM, sizeof(PDMDEVHLPTASK), 8, 0, pdmR3DevHlpQueueConsumer, true, &pVM->pdm.s.pDevHlpQueueHC);630 AssertRCReturn(rc, rc);631 pVM->pdm.s.pDevHlpQueueGC = PDMQueueGCPtr(pVM->pdm.s.pDevHlpQueueHC);632 633 634 /*635 *636 * Enumerate the device instance configurations637 * and come up with a instantiation order.638 *639 */640 /* Switch to /Devices, which contains the device instantiations. */641 PCFGMNODE pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices");642 643 /*644 * Count the device instances.645 */646 PCFGMNODE pCur;647 PCFGMNODE pInstanceNode;648 unsigned cDevs = 0;649 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))650 for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode))651 cDevs++;652 if (!cDevs)653 {654 Log(("PDM: No devices were configured!\n"));655 return VINF_SUCCESS;656 }657 Log2(("PDM: cDevs=%d!\n", cDevs));658 659 /*660 * Collect info on each device instance.661 */662 struct DEVORDER663 {664 /** Configuration node. */665 PCFGMNODE pNode;666 /** Pointer to device. */667 PPDMDEV pDev;668 /** Init order. */669 uint32_t u32Order;670 /** VBox instance number. */671 uint32_t iInstance;672 } *paDevs = (struct DEVORDER *)alloca(sizeof(paDevs[0]) * (cDevs + 1)); /* (One extra for swapping) */673 Assert(paDevs);674 unsigned i = 0;675 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))676 {677 /* Get the device name. */678 char szName[sizeof(paDevs[0].pDev->pDevReg->szDeviceName)];679 rc = CFGMR3GetName(pCur, szName, sizeof(szName));680 AssertMsgRCReturn(rc, ("Configuration error: device name is too long (or something)! rc=%Vrc\n", rc), rc);681 682 /* Find the device. */683 PPDMDEV pDev = pdmR3DevLookup(pVM, szName);684 AssertMsgReturn(pDev, ("Configuration error: device '%s' not found!\n", szName), VERR_PDM_DEVICE_NOT_FOUND);685 686 /* Configured priority or use default based on device class? */687 uint32_t u32Order;688 rc = CFGMR3QueryU32(pCur, "Priority", &u32Order);689 if (rc == VERR_CFGM_VALUE_NOT_FOUND)690 {691 uint32_t u32 = pDev->pDevReg->fClass;692 for (u32Order = 1; !(u32 & u32Order); u32Order <<= 1)693 /* nop */;694 }695 else696 AssertMsgRCReturn(rc, ("Configuration error: reading \"Priority\" for the '%s' device failed rc=%Vrc!\n", szName, rc), rc);697 698 /* Enumerate the device instances. */699 for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode))700 {701 paDevs[i].pNode = pInstanceNode;702 paDevs[i].pDev = pDev;703 paDevs[i].u32Order = u32Order;704 705 /* Get the instance number. */706 char szInstance[32];707 rc = CFGMR3GetName(pInstanceNode, szInstance, sizeof(szInstance));708 AssertMsgRCReturn(rc, ("Configuration error: instance name is too long (or something)! rc=%Vrc\n", rc), rc);709 char *pszNext = NULL;710 rc = RTStrToUInt32Ex(szInstance, &pszNext, 0, &paDevs[i].iInstance);711 AssertMsgRCReturn(rc, ("Configuration error: RTStrToInt32Ex failed on the instance name '%s'! rc=%Vrc\n", szInstance, rc), rc);712 AssertMsgReturn(!*pszNext, ("Configuration error: the instance name '%s' isn't all digits. (%s)\n", szInstance, pszNext), VERR_INVALID_PARAMETER);713 714 /* next instance */715 i++;716 }717 } /* devices */718 Assert(i == cDevs);719 720 /*721 * Sort the device array ascending on u32Order. (bubble)722 */723 unsigned c = cDevs - 1;724 while (c)725 {726 unsigned j = 0;727 for (i = 0; i < c; i++)728 if (paDevs[i].u32Order > paDevs[i + 1].u32Order)729 {730 paDevs[cDevs] = paDevs[i + 1];731 paDevs[i + 1] = paDevs[i];732 paDevs[i] = paDevs[cDevs];733 j = i;734 }735 c = j;736 }737 738 739 /*740 *741 * Instantiate the devices.742 *743 */744 for (i = 0; i < cDevs; i++)745 {746 /*747 * Gather a bit of config.748 */749 /* trusted */750 bool fTrusted;751 rc = CFGMR3QueryBool(paDevs[i].pNode, "Trusted", &fTrusted);752 if (rc == VERR_CFGM_VALUE_NOT_FOUND)753 fTrusted = false;754 else if (VBOX_FAILURE(rc))755 {756 AssertMsgFailed(("configuration error: failed to query boolean \"Trusted\", rc=%Vrc\n", rc));757 return rc;758 }759 /* config node */760 PCFGMNODE pConfigNode = CFGMR3GetChild(paDevs[i].pNode, "Config");761 if (!pConfigNode)762 {763 rc = CFGMR3InsertNode(paDevs[i].pNode, "Config", &pConfigNode);764 if (VBOX_FAILURE(rc))765 {766 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc));767 return rc;768 }769 }770 CFGMR3SetRestrictedRoot(pConfigNode);771 772 /*773 * Allocate the device instance.774 */775 size_t cb = RT_OFFSETOF(PDMDEVINS, achInstanceData[paDevs[i].pDev->pDevReg->cbInstance]);776 cb = RT_ALIGN_Z(cb, 16);777 PPDMDEVINS pDevIns;778 if (paDevs[i].pDev->pDevReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))779 rc = MMR3HyperAllocOnceNoRel(pVM, cb, 0, MM_TAG_PDM_DEVICE, (void **)&pDevIns);780 else781 rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns);782 if (VBOX_FAILURE(rc))783 {784 AssertMsgFailed(("Failed to allocate %d bytes of instance data for device '%s'. rc=%Vrc\n",785 cb, paDevs[i].pDev->pDevReg->szDeviceName, rc));786 return rc;787 }788 789 /*790 * Initialize it.791 */792 pDevIns->u32Version = PDM_DEVINS_VERSION;793 //pDevIns->Internal.s.pNextR3 = NULL;794 //pDevIns->Internal.s.pPerDeviceNextR3 = NULL;795 pDevIns->Internal.s.pDevR3 = paDevs[i].pDev;796 pDevIns->Internal.s.pVMR3 = pVM;797 pDevIns->Internal.s.pVMR0 = pVM->pVMR0;798 pDevIns->Internal.s.pVMRC = pVM->pVMRC;799 //pDevIns->Internal.s.pLunsR3 = NULL;800 pDevIns->Internal.s.pCfgHandle = paDevs[i].pNode;801 //pDevIns->Internal.s.pPciDeviceR3 = NULL;802 //pDevIns->Internal.s.pPciBusR3 = NULL; /** @todo pci bus selection. (in 2008 perhaps) */803 //pDevIns->Internal.s.pPciDeviceR0 = 0;804 //pDevIns->Internal.s.pPciBusR0 = 0;805 //pDevIns->Internal.s.pPciDeviceRC = 0;806 //pDevIns->Internal.s.pPciBusRC = 0;807 pDevIns->pDevHlpR3 = fTrusted ? &g_pdmR3DevHlpTrusted : &g_pdmR3DevHlpUnTrusted;808 pDevIns->pDevHlpRC = pDevHlpRC;809 pDevIns->pDevHlpR0 = pDevHlpR0;810 pDevIns->pDevReg = paDevs[i].pDev->pDevReg;811 pDevIns->pCfgHandle = pConfigNode;812 pDevIns->iInstance = paDevs[i].iInstance;813 pDevIns->pvInstanceDataR3 = &pDevIns->achInstanceData[0];814 pDevIns->pvInstanceDataRC = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC815 ? MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3) : NIL_RTRCPTR;816 pDevIns->pvInstanceDataR0 = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0817 ? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : NIL_RTR0PTR;818 819 /*820 * Link it into all the lists.821 */822 /* The global instance FIFO. */823 PPDMDEVINS pPrev1 = pVM->pdm.s.pDevInstances;824 if (!pPrev1)825 pVM->pdm.s.pDevInstances = pDevIns;826 else827 {828 while (pPrev1->Internal.s.pNextR3)829 pPrev1 = pPrev1->Internal.s.pNextR3;830 pPrev1->Internal.s.pNextR3 = pDevIns;831 }832 833 /* The per device instance FIFO. */834 PPDMDEVINS pPrev2 = paDevs[i].pDev->pInstances;835 if (!pPrev2)836 paDevs[i].pDev->pInstances = pDevIns;837 else838 {839 while (pPrev2->Internal.s.pPerDeviceNextR3)840 pPrev2 = pPrev2->Internal.s.pPerDeviceNextR3;841 pPrev2->Internal.s.pPerDeviceNextR3 = pDevIns;842 }843 844 /*845 * Call the constructor.846 */847 Log(("PDM: Constructing device '%s' instance %d...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));848 rc = pDevIns->pDevReg->pfnConstruct(pDevIns, pDevIns->iInstance, pDevIns->pCfgHandle);849 if (VBOX_FAILURE(rc))850 {851 LogRel(("PDM: Failed to construct '%s'/%d! %Vra\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));852 /* because we're damn lazy right now, we'll say that the destructor will be called even if the constructor fails. */853 return rc;854 }855 } /* for device instances */856 857 #ifdef VBOX_WITH_USB858 /* ditto for USB Devices. */859 rc = pdmR3UsbInstantiateDevices(pVM);860 if (RT_FAILURE(rc))861 return rc;862 #endif863 864 865 /*866 *867 * PCI BIOS Fake and Init Complete.868 *869 */870 if (pVM->pdm.s.aPciBuses[0].pDevInsR3)871 {872 pdmLock(pVM);873 rc = pVM->pdm.s.aPciBuses[0].pfnFakePCIBIOSR3(pVM->pdm.s.aPciBuses[0].pDevInsR3);874 pdmUnlock(pVM);875 if (VBOX_FAILURE(rc))876 {877 AssertMsgFailed(("PCI BIOS fake failed rc=%Vrc\n", rc));878 return rc;879 }880 }881 882 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)883 {884 if (pDevIns->pDevReg->pfnInitComplete)885 {886 rc = pDevIns->pDevReg->pfnInitComplete(pDevIns);887 if (VBOX_FAILURE(rc))888 {889 AssertMsgFailed(("InitComplete on device '%s'/%d failed with rc=%Vrc\n",890 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));891 return rc;892 }893 }894 }895 896 #ifdef VBOX_WITH_USB897 /* ditto for USB Devices. */898 rc = pdmR3UsbVMInitComplete(pVM);899 if (RT_FAILURE(rc))900 return rc;901 #endif902 903 LogFlow(("pdmR3DevInit: returns %Vrc\n", VINF_SUCCESS));904 return VINF_SUCCESS;905 }906 907 908 /**909 * Lookups a device structure by name.910 * @internal911 */912 PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName)913 {914 RTUINT cchName = strlen(pszName);915 for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext)916 if ( pDev->cchName == cchName917 && !strcmp(pDev->pDevReg->szDeviceName, pszName))918 return pDev;919 return NULL;920 }921 922 923 /**924 * Loads the device modules.925 *926 * @returns VBox status code.927 * @param pVM Pointer to the shared VM structure.928 */929 static int pdmR3DevLoadModules(PVM pVM)930 {931 /*932 * Initialize the callback structure.933 */934 PDMDEVREGCBINT RegCB;935 RegCB.Core.u32Version = PDM_DEVREG_CB_VERSION;936 RegCB.Core.pfnRegister = pdmR3DevReg_Register;937 RegCB.Core.pfnMMHeapAlloc = pdmR3DevReg_MMHeapAlloc;938 RegCB.pVM = pVM;939 940 /*941 * Load the builtin module942 */943 PCFGMNODE pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/Devices");944 bool fLoadBuiltin;945 int rc = CFGMR3QueryBool(pDevicesNode, "LoadBuiltin", &fLoadBuiltin);946 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)947 fLoadBuiltin = true;948 else if (VBOX_FAILURE(rc))949 {950 AssertMsgFailed(("Configuration error: Querying boolean \"LoadBuiltin\" failed with %Vrc\n", rc));951 return rc;952 }953 if (fLoadBuiltin)954 {955 /* make filename */956 char *pszFilename = pdmR3FileR3("VBoxDD", /* fShared = */ true);957 if (!pszFilename)958 return VERR_NO_TMP_MEMORY;959 rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD");960 RTMemTmpFree(pszFilename);961 if (VBOX_FAILURE(rc))962 return rc;963 964 /* make filename */965 pszFilename = pdmR3FileR3("VBoxDD2", /* fShared = */ true);966 if (!pszFilename)967 return VERR_NO_TMP_MEMORY;968 rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD2");969 RTMemTmpFree(pszFilename);970 if (VBOX_FAILURE(rc))971 return rc;972 }973 974 /*975 * Load additional device modules.976 */977 PCFGMNODE pCur;978 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))979 {980 /*981 * Get the name and path.982 */983 char szName[PDMMOD_NAME_LEN];984 rc = CFGMR3GetName(pCur, &szName[0], sizeof(szName));985 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)986 {987 AssertMsgFailed(("configuration error: The module name is too long, cchName=%d.\n", CFGMR3GetNameLen(pCur)));988 return VERR_PDM_MODULE_NAME_TOO_LONG;989 }990 else if (VBOX_FAILURE(rc))991 {992 AssertMsgFailed(("CFGMR3GetName -> %Vrc.\n", rc));993 return rc;994 }995 996 /* the path is optional, if no path the module name + path is used. */997 char szFilename[RTPATH_MAX];998 rc = CFGMR3QueryString(pCur, "Path", &szFilename[0], sizeof(szFilename));999 if (rc == VERR_CFGM_VALUE_NOT_FOUND)1000 strcpy(szFilename, szName);1001 else if (VBOX_FAILURE(rc))1002 {1003 AssertMsgFailed(("configuration error: Failure to query the module path, rc=%Vrc.\n", rc));1004 return rc;1005 }1006 1007 /* prepend path? */1008 if (!RTPathHavePath(szFilename))1009 {1010 char *psz = pdmR3FileR3(szFilename);1011 if (!psz)1012 return VERR_NO_TMP_MEMORY;1013 size_t cch = strlen(psz) + 1;1014 if (cch > sizeof(szFilename))1015 {1016 RTMemTmpFree(psz);1017 AssertMsgFailed(("Filename too long! cch=%d '%s'\n", cch, psz));1018 return VERR_FILENAME_TOO_LONG;1019 }1020 memcpy(szFilename, psz, cch);1021 RTMemTmpFree(psz);1022 }1023 1024 /*1025 * Load the module and register it's devices.1026 */1027 rc = pdmR3DevLoad(pVM, &RegCB, szFilename, szName);1028 if (VBOX_FAILURE(rc))1029 return rc;1030 }1031 1032 return VINF_SUCCESS;1033 }1034 1035 1036 /**1037 * Loads one device module and call the registration entry point.1038 *1039 * @returns VBox status code.1040 * @param pVM VM handle.1041 * @param pRegCB The registration callback stuff.1042 * @param pszFilename Module filename.1043 * @param pszName Module name.1044 */1045 static int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName)1046 {1047 /*1048 * Load it.1049 */1050 int rc = pdmR3LoadR3U(pVM->pUVM, pszFilename, pszName);1051 if (VBOX_SUCCESS(rc))1052 {1053 /*1054 * Get the registration export and call it.1055 */1056 FNPDMVBOXDEVICESREGISTER *pfnVBoxDevicesRegister;1057 rc = PDMR3LdrGetSymbolR3(pVM, pszName, "VBoxDevicesRegister", (void **)&pfnVBoxDevicesRegister);1058 if (VBOX_SUCCESS(rc))1059 {1060 Log(("PDM: Calling VBoxDevicesRegister (%p) of %s (%s)\n", pfnVBoxDevicesRegister, pszName, pszFilename));1061 rc = pfnVBoxDevicesRegister(&pRegCB->Core, VBOX_VERSION);1062 if (VBOX_SUCCESS(rc))1063 Log(("PDM: Successfully loaded device module %s (%s).\n", pszName, pszFilename));1064 else1065 AssertMsgFailed(("VBoxDevicesRegister failed with rc=%Vrc for module %s (%s)\n", rc, pszName, pszFilename));1066 }1067 else1068 {1069 AssertMsgFailed(("Failed to locate 'VBoxDevicesRegister' in %s (%s) rc=%Vrc\n", pszName, pszFilename, rc));1070 if (rc == VERR_SYMBOL_NOT_FOUND)1071 rc = VERR_PDM_NO_REGISTRATION_EXPORT;1072 }1073 }1074 else1075 AssertMsgFailed(("Failed to load %s %s!\n", pszFilename, pszName));1076 return rc;1077 }1078 1079 1080 1081 /**1082 * Registers a device with the current VM instance.1083 *1084 * @returns VBox status code.1085 * @param pCallbacks Pointer to the callback table.1086 * @param pDevReg Pointer to the device registration record.1087 * This data must be permanent and readonly.1088 */1089 static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg)1090 {1091 /*1092 * Validate the registration structure.1093 */1094 Assert(pDevReg);1095 if (pDevReg->u32Version != PDM_DEVREG_VERSION)1096 {1097 AssertMsgFailed(("Unknown struct version %#x!\n", pDevReg->u32Version));1098 return VERR_PDM_UNKNOWN_DEVREG_VERSION;1099 }1100 if ( !pDevReg->szDeviceName[0]1101 || strlen(pDevReg->szDeviceName) >= sizeof(pDevReg->szDeviceName))1102 {1103 AssertMsgFailed(("Invalid name '%s'\n", pDevReg->szDeviceName));1104 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1105 }1106 if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)1107 && ( !pDevReg->szRCMod[0]1108 || strlen(pDevReg->szRCMod) >= sizeof(pDevReg->szRCMod)))1109 {1110 AssertMsgFailed(("Invalid GC module name '%s' - (Device %s)\n", pDevReg->szRCMod, pDevReg->szDeviceName));1111 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1112 }1113 if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)1114 && ( !pDevReg->szR0Mod[0]1115 || strlen(pDevReg->szR0Mod) >= sizeof(pDevReg->szR0Mod)))1116 {1117 AssertMsgFailed(("Invalid R0 module name '%s' - (Device %s)\n", pDevReg->szR0Mod, pDevReg->szDeviceName));1118 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1119 }1120 if ((pDevReg->fFlags & PDM_DEVREG_FLAGS_HOST_BITS_MASK) != PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)1121 {1122 AssertMsgFailed(("Invalid host bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName));1123 return VERR_PDM_INVALID_DEVICE_HOST_BITS;1124 }1125 if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_MASK))1126 {1127 AssertMsgFailed(("Invalid guest bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName));1128 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1129 }1130 if (!pDevReg->fClass)1131 {1132 AssertMsgFailed(("No class! (Device %s)\n", pDevReg->szDeviceName));1133 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1134 }1135 if (pDevReg->cMaxInstances <= 0)1136 {1137 AssertMsgFailed(("Max instances %u! (Device %s)\n", pDevReg->cMaxInstances, pDevReg->szDeviceName));1138 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1139 }1140 if (pDevReg->cbInstance > (RTUINT)(pDevReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0) ? 96 * _1K : _1M))1141 {1142 AssertMsgFailed(("Instance size %d bytes! (Device %s)\n", pDevReg->cbInstance, pDevReg->szDeviceName));1143 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1144 }1145 if (!pDevReg->pfnConstruct)1146 {1147 AssertMsgFailed(("No constructore! (Device %s)\n", pDevReg->szDeviceName));1148 return VERR_PDM_INVALID_DEVICE_REGISTRATION;1149 }1150 /* Check matching guest bits last without any asserting. Enables trial and error registration. */1151 if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT))1152 {1153 Log(("PDM: Rejected device '%s' because it didn't match the guest bits.\n", pDevReg->szDeviceName));1154 return VERR_PDM_INVALID_DEVICE_GUEST_BITS;1155 }1156 AssertLogRelMsg(pDevReg->u32VersionEnd == PDM_DEVREG_VERSION,1157 ("u32VersionEnd=%#x, expected %#x. (szDeviceName=%s)\n",1158 pDevReg->u32VersionEnd, PDM_DEVREG_VERSION, pDevReg->szDeviceName));1159 1160 /*1161 * Check for duplicate and find FIFO entry at the same time.1162 */1163 PCPDMDEVREGCBINT pRegCB = (PCPDMDEVREGCBINT)pCallbacks;1164 PPDMDEV pDevPrev = NULL;1165 PPDMDEV pDev = pRegCB->pVM->pdm.s.pDevs;1166 for (; pDev; pDevPrev = pDev, pDev = pDev->pNext)1167 {1168 if (!strcmp(pDev->pDevReg->szDeviceName, pDevReg->szDeviceName))1169 {1170 AssertMsgFailed(("Device '%s' already exists\n", pDevReg->szDeviceName));1171 return VERR_PDM_DEVICE_NAME_CLASH;1172 }1173 }1174 1175 /*1176 * Allocate new device structure and insert it into the list.1177 */1178 pDev = (PPDMDEV)MMR3HeapAlloc(pRegCB->pVM, MM_TAG_PDM_DEVICE, sizeof(*pDev));1179 if (pDev)1180 {1181 pDev->pNext = NULL;1182 pDev->cInstances = 0;1183 pDev->pInstances = NULL;1184 pDev->pDevReg = pDevReg;1185 pDev->cchName = strlen(pDevReg->szDeviceName);1186 1187 if (pDevPrev)1188 pDevPrev->pNext = pDev;1189 else1190 pRegCB->pVM->pdm.s.pDevs = pDev;1191 Log(("PDM: Registered device '%s'\n", pDevReg->szDeviceName));1192 return VINF_SUCCESS;1193 }1194 return VERR_NO_MEMORY;1195 }1196 1197 1198 /**1199 * Allocate memory which is associated with current VM instance1200 * and automatically freed on it's destruction.1201 *1202 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.1203 * @param pCallbacks Pointer to the callback table.1204 * @param cb Number of bytes to allocate.1205 */1206 static DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb)1207 {1208 Assert(pCallbacks);1209 Assert(pCallbacks->u32Version == PDM_DEVREG_CB_VERSION);1210 1211 void *pv = MMR3HeapAlloc(((PPDMDEVREGCBINT)pCallbacks)->pVM, MM_TAG_PDM_DEVICE_USER, cb);1212 LogFlow(("pdmR3DevReg_MMHeapAlloc(,%#zx): returns %p\n", cb, pv));1213 return pv;1214 }1215 1216 1217 1218 1219 1220 /*1221 *1222 *1223 *1224 *1225 * p d m R 3 D e v H l p1226 * p d m R 3 D e v H l p1227 * p d m R 3 D e v H l p1228 *1229 *1230 *1231 *1232 */1233 1234 3118 1235 3119 /** … … 1241 3125 * @param pItem The item to consume. Upon return this item will be freed. 1242 3126 */ 1243 staticDECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)3127 DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem) 1244 3128 { 1245 3129 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem; … … 1266 3150 } 1267 3151 1268 1269 /** @copydoc PDMDEVHLPR3::pfnIOPortRegister */ 1270 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, 1271 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc) 1272 { 1273 PDMDEV_ASSERT_DEVINS(pDevIns); 1274 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1275 Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc)); 1276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1277 1278 int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc); 1279 1280 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1281 return rc; 1282 } 1283 1284 1285 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterGC */ 1286 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, 1287 const char *pszOut, const char *pszIn, 1288 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 1289 { 1290 PDMDEV_ASSERT_DEVINS(pDevIns); 1291 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1292 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1293 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 1294 1295 /* 1296 * Resolve the functions (one of the can be NULL). 1297 */ 1298 int rc = VINF_SUCCESS; 1299 if ( pDevIns->pDevReg->szRCMod[0] 1300 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 1301 { 1302 RTGCPTR32 GCPtrIn = 0; 1303 if (pszIn) 1304 { 1305 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszIn, &GCPtrIn); 1306 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szRCMod, pszIn)); 1307 } 1308 RTGCPTR32 GCPtrOut = 0; 1309 if (pszOut && VBOX_SUCCESS(rc)) 1310 { 1311 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOut, &GCPtrOut); 1312 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szRCMod, pszOut)); 1313 } 1314 RTGCPTR32 GCPtrInStr = 0; 1315 if (pszInStr && VBOX_SUCCESS(rc)) 1316 { 1317 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszInStr, &GCPtrInStr); 1318 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szRCMod, pszInStr)); 1319 } 1320 RTGCPTR32 GCPtrOutStr = 0; 1321 if (pszOutStr && VBOX_SUCCESS(rc)) 1322 { 1323 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOutStr, &GCPtrOutStr); 1324 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szRCMod, pszOutStr)); 1325 } 1326 1327 if (VBOX_SUCCESS(rc)) 1328 rc = IOMR3IOPortRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc); 1329 } 1330 else 1331 { 1332 AssertMsgFailed(("No GC module for this driver!\n")); 1333 rc = VERR_INVALID_PARAMETER; 1334 } 1335 1336 LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1337 return rc; 1338 } 1339 1340 1341 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0 */ 1342 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, 1343 const char *pszOut, const char *pszIn, 1344 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 1345 { 1346 PDMDEV_ASSERT_DEVINS(pDevIns); 1347 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1348 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1349 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 1350 1351 /* 1352 * Resolve the functions (one of the can be NULL). 1353 */ 1354 int rc = VINF_SUCCESS; 1355 if ( pDevIns->pDevReg->szR0Mod[0] 1356 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 1357 { 1358 R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0; 1359 if (pszIn) 1360 { 1361 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn); 1362 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn)); 1363 } 1364 R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0; 1365 if (pszOut && VBOX_SUCCESS(rc)) 1366 { 1367 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut); 1368 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut)); 1369 } 1370 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0; 1371 if (pszInStr && VBOX_SUCCESS(rc)) 1372 { 1373 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr); 1374 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr)); 1375 } 1376 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0; 1377 if (pszOutStr && VBOX_SUCCESS(rc)) 1378 { 1379 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr); 1380 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr)); 1381 } 1382 1383 if (VBOX_SUCCESS(rc)) 1384 rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc); 1385 } 1386 else 1387 { 1388 AssertMsgFailed(("No R0 module for this driver!\n")); 1389 rc = VERR_INVALID_PARAMETER; 1390 } 1391 1392 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1393 return rc; 1394 } 1395 1396 1397 /** @copydoc PDMDEVHLPR3::pfnIOPortDeregister */ 1398 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts) 1399 { 1400 PDMDEV_ASSERT_DEVINS(pDevIns); 1401 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1402 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1403 Port, cPorts)); 1404 1405 int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts); 1406 1407 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1408 return rc; 1409 } 1410 1411 1412 /** @copydoc PDMDEVHLPR3::pfnMMIORegister */ 1413 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, 1414 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, 1415 const char *pszDesc) 1416 { 1417 PDMDEV_ASSERT_DEVINS(pDevIns); 1418 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1419 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n", 1420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc)); 1421 1422 int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc); 1423 1424 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1425 return rc; 1426 } 1427 1428 1429 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterGC */ 1430 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser, 1431 const char *pszWrite, const char *pszRead, const char *pszFill, 1432 const char *pszDesc) 1433 { 1434 PDMDEV_ASSERT_DEVINS(pDevIns); 1435 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1436 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 1437 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 1438 1439 /* 1440 * Resolve the functions. 1441 * Not all function have to present, leave it to IOM to enforce this. 1442 */ 1443 int rc = VINF_SUCCESS; 1444 if ( pDevIns->pDevReg->szRCMod[0] 1445 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 1446 { 1447 RTGCPTR32 GCPtrWrite = 0; 1448 if (pszWrite) 1449 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszWrite, &GCPtrWrite); 1450 RTGCPTR32 GCPtrRead = 0; 1451 int rc2 = VINF_SUCCESS; 1452 if (pszRead) 1453 rc2 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszRead, &GCPtrRead); 1454 RTGCPTR32 GCPtrFill = 0; 1455 int rc3 = VINF_SUCCESS; 1456 if (pszFill) 1457 rc3 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszFill, &GCPtrFill); 1458 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 1459 rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill); 1460 else 1461 { 1462 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szRCMod, pszWrite)); 1463 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szRCMod, pszRead)); 1464 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szRCMod, pszFill)); 1465 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 1466 rc = rc2; 1467 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 1468 rc = rc3; 1469 } 1470 } 1471 else 1472 { 1473 AssertMsgFailed(("No GC module for this driver!\n")); 1474 rc = VERR_INVALID_PARAMETER; 1475 } 1476 1477 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1478 return rc; 1479 } 1480 1481 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterR0 */ 1482 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser, 1483 const char *pszWrite, const char *pszRead, const char *pszFill, 1484 const char *pszDesc) 1485 { 1486 PDMDEV_ASSERT_DEVINS(pDevIns); 1487 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1488 LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 1489 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 1490 1491 /* 1492 * Resolve the functions. 1493 * Not all function have to present, leave it to IOM to enforce this. 1494 */ 1495 int rc = VINF_SUCCESS; 1496 if ( pDevIns->pDevReg->szR0Mod[0] 1497 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 1498 { 1499 R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0; 1500 if (pszWrite) 1501 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite); 1502 R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0; 1503 int rc2 = VINF_SUCCESS; 1504 if (pszRead) 1505 rc2 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead); 1506 R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0; 1507 int rc3 = VINF_SUCCESS; 1508 if (pszFill) 1509 rc3 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill); 1510 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 1511 rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill); 1512 else 1513 { 1514 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite)); 1515 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead)); 1516 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill)); 1517 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 1518 rc = rc2; 1519 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 1520 rc = rc3; 1521 } 1522 } 1523 else 1524 { 1525 AssertMsgFailed(("No R0 module for this driver!\n")); 1526 rc = VERR_INVALID_PARAMETER; 1527 } 1528 1529 LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1530 return rc; 1531 } 1532 1533 1534 /** @copydoc PDMDEVHLPR3::pfnMMIODeregister */ 1535 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 1536 { 1537 PDMDEV_ASSERT_DEVINS(pDevIns); 1538 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1539 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 1540 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 1541 1542 int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange); 1543 1544 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1545 return rc; 1546 } 1547 1548 1549 /** @copydoc PDMDEVHLPR3::pfnROMRegister */ 1550 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc) 1551 { 1552 PDMDEV_ASSERT_DEVINS(pDevIns); 1553 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1554 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n", 1555 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc)); 1556 1557 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc); 1558 1559 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1560 return rc; 1561 } 1562 1563 1564 /** @copydoc PDMDEVHLPR3::pfnSSMRegister */ 1565 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, 1566 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, 1567 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone) 1568 { 1569 PDMDEV_ASSERT_DEVINS(pDevIns); 1570 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1571 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n", 1572 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone)); 1573 1574 int rc = SSMR3Register(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess, 1575 pfnSavePrep, pfnSaveExec, pfnSaveDone, 1576 pfnLoadPrep, pfnLoadExec, pfnLoadDone); 1577 1578 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1579 return rc; 1580 } 1581 1582 1583 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */ 1584 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer) 1585 { 1586 PDMDEV_ASSERT_DEVINS(pDevIns); 1587 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1588 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n", 1589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer)); 1590 1591 int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer); 1592 1593 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1594 return rc; 1595 } 1596 1597 1598 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreateExternal */ 1599 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc) 1600 { 1601 PDMDEV_ASSERT_DEVINS(pDevIns); 1602 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1603 1604 return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMR3, enmClock, pfnCallback, pvUser, pszDesc); 1605 } 1606 1607 /** @copydoc PDMDEVHLPR3::pfnPCIRegister */ 1608 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev) 1609 { 1610 PDMDEV_ASSERT_DEVINS(pDevIns); 1611 PVM pVM = pDevIns->Internal.s.pVMR3; 1612 VM_ASSERT_EMT(pVM); 1613 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n", 1614 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config)); 1615 1616 /* 1617 * Validate input. 1618 */ 1619 if (!pPciDev) 1620 { 1621 Assert(pPciDev); 1622 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1623 return VERR_INVALID_PARAMETER; 1624 } 1625 if (!pPciDev->config[0] && !pPciDev->config[1]) 1626 { 1627 Assert(pPciDev->config[0] || pPciDev->config[1]); 1628 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1629 return VERR_INVALID_PARAMETER; 1630 } 1631 if (pDevIns->Internal.s.pPciDeviceR3) 1632 { 1633 /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to 1634 * support a PDM device with multiple PCI devices. This might become a problem 1635 * when upgrading the chipset for instance... 1636 */ 1637 AssertMsgFailed(("Only one PCI device per device is currently implemented!\n")); 1638 return VERR_INTERNAL_ERROR; 1639 } 1640 1641 /* 1642 * Choose the PCI bus for the device. 1643 * This is simple. If the device was configured for a particular bus, it'll 1644 * already have one. If not, we'll just take the first one. 1645 */ 1646 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1647 if (!pBus) 1648 pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[0]; 1649 int rc; 1650 if (pBus) 1651 { 1652 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1653 pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3); 1654 else 1655 pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR; 1656 1657 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1658 pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3); 1659 else 1660 pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR; 1661 1662 /* 1663 * Check the configuration for PCI device and function assignment. 1664 */ 1665 int iDev = -1; 1666 uint8_t u8Device; 1667 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device); 1668 if (VBOX_SUCCESS(rc)) 1669 { 1670 if (u8Device > 31) 1671 { 1672 AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n", 1673 u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1674 return VERR_INTERNAL_ERROR; 1675 } 1676 1677 uint8_t u8Function; 1678 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function); 1679 if (VBOX_FAILURE(rc)) 1680 { 1681 AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n", 1682 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1683 return rc; 1684 } 1685 if (u8Function > 7) 1686 { 1687 AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n", 1688 u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1689 return VERR_INTERNAL_ERROR; 1690 } 1691 iDev = (u8Device << 3) | u8Function; 1692 } 1693 else if (rc != VERR_CFGM_VALUE_NOT_FOUND) 1694 { 1695 AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n", 1696 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1697 return rc; 1698 } 1699 1700 /* 1701 * Call the pci bus device to do the actual registration. 1702 */ 1703 pdmLock(pVM); 1704 rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev); 1705 pdmUnlock(pVM); 1706 if (VBOX_SUCCESS(rc)) 1707 { 1708 pPciDev->pDevIns = pDevIns; 1709 1710 pDevIns->Internal.s.pPciDeviceR3 = pPciDev; 1711 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0) 1712 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev); 1713 else 1714 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR; 1715 1716 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1717 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev); 1718 else 1719 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR; 1720 1721 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n", 1722 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus)); 1723 } 1724 } 1725 else 1726 { 1727 AssertMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n")); 1728 rc = VERR_PDM_NO_PCI_BUS; 1729 } 1730 1731 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1732 return rc; 1733 } 1734 1735 1736 /** @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister */ 1737 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback) 1738 { 1739 PDMDEV_ASSERT_DEVINS(pDevIns); 1740 PVM pVM = pDevIns->Internal.s.pVMR3; 1741 VM_ASSERT_EMT(pVM); 1742 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n", 1743 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback)); 1744 1745 /* 1746 * Validate input. 1747 */ 1748 if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS) 1749 { 1750 Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS); 1751 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1752 return VERR_INVALID_PARAMETER; 1753 } 1754 switch (enmType) 1755 { 1756 case PCI_ADDRESS_SPACE_MEM: 1757 case PCI_ADDRESS_SPACE_IO: 1758 case PCI_ADDRESS_SPACE_MEM_PREFETCH: 1759 break; 1760 default: 1761 AssertMsgFailed(("enmType=%#x is unknown\n", enmType)); 1762 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1763 return VERR_INVALID_PARAMETER; 1764 } 1765 if (!pfnCallback) 1766 { 1767 Assert(pfnCallback); 1768 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1769 return VERR_INVALID_PARAMETER; 1770 } 1771 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 1772 1773 /* 1774 * Must have a PCI device registered! 1775 */ 1776 int rc; 1777 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1778 if (pPciDev) 1779 { 1780 /* 1781 * We're currently restricted to page aligned MMIO regions. 1782 */ 1783 if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH) 1784 && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE)) 1785 { 1786 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n", 1787 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE))); 1788 cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE); 1789 } 1790 1791 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1792 Assert(pBus); 1793 pdmLock(pVM); 1794 rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback); 1795 pdmUnlock(pVM); 1796 } 1797 else 1798 { 1799 AssertMsgFailed(("No PCI device registered!\n")); 1800 rc = VERR_PDM_NOT_PCI_DEVICE; 1801 } 1802 1803 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1804 return rc; 1805 } 1806 1807 1808 /** @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks */ 1809 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, 1810 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld) 1811 { 1812 PDMDEV_ASSERT_DEVINS(pDevIns); 1813 PVM pVM = pDevIns->Internal.s.pVMR3; 1814 VM_ASSERT_EMT(pVM); 1815 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n", 1816 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld)); 1817 1818 /* 1819 * Validate input and resolve defaults. 1820 */ 1821 AssertPtr(pfnRead); 1822 AssertPtr(pfnWrite); 1823 AssertPtrNull(ppfnReadOld); 1824 AssertPtrNull(ppfnWriteOld); 1825 AssertPtrNull(pPciDev); 1826 1827 if (!pPciDev) 1828 pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1829 AssertReleaseMsg(pPciDev, ("You must register your device first!\n")); 1830 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1831 AssertRelease(pBus); 1832 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 1833 1834 /* 1835 * Do the job. 1836 */ 1837 pdmLock(pVM); 1838 pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld); 1839 pdmUnlock(pVM); 1840 1841 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1842 } 1843 1844 1845 /** @copydoc PDMDEVHLPR3::pfnPCISetIrq */ 1846 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1847 { 1848 PDMDEV_ASSERT_DEVINS(pDevIns); 1849 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 1850 1851 /* 1852 * Validate input. 1853 */ 1854 /** @todo iIrq and iLevel checks. */ 1855 1856 /* 1857 * Must have a PCI device registered! 1858 */ 1859 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1860 if (pPciDev) 1861 { 1862 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */ 1863 Assert(pBus); 1864 PVM pVM = pDevIns->Internal.s.pVMR3; 1865 pdmLock(pVM); 1866 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel); 1867 pdmUnlock(pVM); 1868 } 1869 else 1870 AssertReleaseMsgFailed(("No PCI device registered!\n")); 1871 1872 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1873 } 1874 1875 1876 /** @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait */ 1877 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1878 { 1879 pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel); 1880 } 1881 1882 1883 /** @copydoc PDMDEVHLPR3::pfnISASetIrq */ 1884 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1885 { 1886 PDMDEV_ASSERT_DEVINS(pDevIns); 1887 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 1888 1889 /* 1890 * Validate input. 1891 */ 1892 /** @todo iIrq and iLevel checks. */ 1893 1894 PVM pVM = pDevIns->Internal.s.pVMR3; 1895 PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */ 1896 1897 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1898 } 1899 1900 1901 /** @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait */ 1902 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1903 { 1904 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel); 1905 } 1906 1907 1908 /** @copydoc PDMDEVHLPR3::pfnDriverAttach */ 1909 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc) 1910 { 1911 PDMDEV_ASSERT_DEVINS(pDevIns); 1912 PVM pVM = pDevIns->Internal.s.pVMR3; 1913 VM_ASSERT_EMT(pVM); 1914 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n", 1915 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc)); 1916 1917 /* 1918 * Lookup the LUN, it might already be registered. 1919 */ 1920 PPDMLUN pLunPrev = NULL; 1921 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; 1922 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext) 1923 if (pLun->iLun == iLun) 1924 break; 1925 1926 /* 1927 * Create the LUN if if wasn't found, else check if driver is already attached to it. 1928 */ 1929 if (!pLun) 1930 { 1931 if ( !pBaseInterface 1932 || !pszDesc 1933 || !*pszDesc) 1934 { 1935 Assert(pBaseInterface); 1936 Assert(pszDesc || *pszDesc); 1937 return VERR_INVALID_PARAMETER; 1938 } 1939 1940 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun)); 1941 if (!pLun) 1942 return VERR_NO_MEMORY; 1943 1944 pLun->iLun = iLun; 1945 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL; 1946 pLun->pTop = NULL; 1947 pLun->pBottom = NULL; 1948 pLun->pDevIns = pDevIns; 1949 pLun->pszDesc = pszDesc; 1950 pLun->pBase = pBaseInterface; 1951 if (!pLunPrev) 1952 pDevIns->Internal.s.pLunsR3 = pLun; 1953 else 1954 pLunPrev->pNext = pLun; 1955 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n", 1956 iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1957 } 1958 else if (pLun->pTop) 1959 { 1960 AssertMsgFailed(("Already attached! The device should keep track of such things!\n")); 1961 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED)); 1962 return VERR_PDM_DRIVER_ALREADY_ATTACHED; 1963 } 1964 Assert(pLun->pBase == pBaseInterface); 1965 1966 1967 /* 1968 * Get the attached driver configuration. 1969 */ 1970 int rc; 1971 char szNode[48]; 1972 RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun); 1973 PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode); 1974 if (pNode) 1975 { 1976 char *pszName; 1977 rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName); 1978 if (VBOX_SUCCESS(rc)) 1979 { 1980 /* 1981 * Find the driver. 1982 */ 1983 PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName); 1984 if (pDrv) 1985 { 1986 /* config node */ 1987 PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config"); 1988 if (!pConfigNode) 1989 rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode); 1990 if (VBOX_SUCCESS(rc)) 1991 { 1992 CFGMR3SetRestrictedRoot(pConfigNode); 1993 1994 /* 1995 * Allocate the driver instance. 1996 */ 1997 size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]); 1998 cb = RT_ALIGN_Z(cb, 16); 1999 PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb); 2000 if (pNew) 2001 { 2002 /* 2003 * Initialize the instance structure (declaration order). 2004 */ 2005 pNew->u32Version = PDM_DRVINS_VERSION; 2006 //pNew->Internal.s.pUp = NULL; 2007 //pNew->Internal.s.pDown = NULL; 2008 pNew->Internal.s.pLun = pLun; 2009 pNew->Internal.s.pDrv = pDrv; 2010 pNew->Internal.s.pVM = pVM; 2011 //pNew->Internal.s.fDetaching = false; 2012 pNew->Internal.s.pCfgHandle = pNode; 2013 pNew->pDrvHlp = &g_pdmR3DrvHlp; 2014 pNew->pDrvReg = pDrv->pDrvReg; 2015 pNew->pCfgHandle = pConfigNode; 2016 pNew->iInstance = pDrv->cInstances++; 2017 pNew->pUpBase = pBaseInterface; 2018 //pNew->pDownBase = NULL; 2019 //pNew->IBase.pfnQueryInterface = NULL; 2020 pNew->pvInstanceData = &pNew->achInstanceData[0]; 2021 2022 /* 2023 * Link with LUN and call the constructor. 2024 */ 2025 pLun->pTop = pLun->pBottom = pNew; 2026 rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle); 2027 if (VBOX_SUCCESS(rc)) 2028 { 2029 MMR3HeapFree(pszName); 2030 *ppBaseInterface = &pNew->IBase; 2031 Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n", 2032 pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2033 LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2034 /* 2035 * Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS) */ 2036 return rc; 2037 } 2038 2039 /* 2040 * Free the driver. 2041 */ 2042 pLun->pTop = pLun->pBottom = NULL; 2043 ASMMemFill32(pNew, cb, 0xdeadd0d0); 2044 MMR3HeapFree(pNew); 2045 pDrv->cInstances--; 2046 } 2047 else 2048 { 2049 AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName)); 2050 rc = VERR_NO_MEMORY; 2051 } 2052 } 2053 else 2054 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc)); 2055 } 2056 else 2057 { 2058 AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName)); 2059 rc = VERR_PDM_DRIVER_NOT_FOUND; 2060 } 2061 MMR3HeapFree(pszName); 2062 } 2063 else 2064 { 2065 AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc)); 2066 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2067 rc = VERR_PDM_CFG_MISSING_DRIVER_NAME; 2068 } 2069 } 2070 else 2071 rc = VERR_PDM_NO_ATTACHED_DRIVER; 2072 2073 2074 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2075 return rc; 2076 } 2077 2078 2079 /** @copydoc PDMDEVHLPR3::pfnMMHeapAlloc */ 2080 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb) 2081 { 2082 PDMDEV_ASSERT_DEVINS(pDevIns); 2083 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 2084 2085 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 2086 2087 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2088 return pv; 2089 } 2090 2091 2092 /** @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ */ 2093 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb) 2094 { 2095 PDMDEV_ASSERT_DEVINS(pDevIns); 2096 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 2097 2098 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 2099 2100 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2101 return pv; 2102 } 2103 2104 2105 /** @copydoc PDMDEVHLPR3::pfnMMHeapFree */ 2106 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv) 2107 { 2108 PDMDEV_ASSERT_DEVINS(pDevIns); 2109 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2110 2111 MMR3HeapFree(pv); 2112 2113 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2114 } 2115 2116 2117 /** @copydoc PDMDEVHLPR3::pfnVMSetError */ 2118 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) 2119 { 2120 PDMDEV_ASSERT_DEVINS(pDevIns); 2121 va_list args; 2122 va_start(args, pszFormat); 2123 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2); 2124 va_end(args); 2125 return rc; 2126 } 2127 2128 2129 /** @copydoc PDMDEVHLPR3::pfnVMSetErrorV */ 2130 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) 2131 { 2132 PDMDEV_ASSERT_DEVINS(pDevIns); 2133 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2); 2134 return rc; 2135 } 2136 2137 2138 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError */ 2139 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...) 2140 { 2141 PDMDEV_ASSERT_DEVINS(pDevIns); 2142 va_list args; 2143 va_start(args, pszFormat); 2144 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, args); 2145 va_end(args); 2146 return rc; 2147 } 2148 2149 2150 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeErrorV */ 2151 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va) 2152 { 2153 PDMDEV_ASSERT_DEVINS(pDevIns); 2154 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, va); 2155 return rc; 2156 } 2157 2158 2159 /** @copydoc PDMDEVHLPR3::pfnAssertEMT */ 2160 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2161 { 2162 PDMDEV_ASSERT_DEVINS(pDevIns); 2163 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 2164 return true; 2165 2166 char szMsg[100]; 2167 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 2168 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 2169 AssertBreakpoint(); 2170 return false; 2171 } 2172 2173 2174 /** @copydoc PDMDEVHLPR3::pfnAssertOther */ 2175 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2176 { 2177 PDMDEV_ASSERT_DEVINS(pDevIns); 2178 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 2179 return true; 2180 2181 char szMsg[100]; 2182 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 2183 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 2184 AssertBreakpoint(); 2185 return false; 2186 } 2187 2188 2189 /** @copydoc PDMDEVHLPR3::pfnDBGFStopV */ 2190 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args) 2191 { 2192 PDMDEV_ASSERT_DEVINS(pDevIns); 2193 #ifdef LOG_ENABLED 2194 va_list va2; 2195 va_copy(va2, args); 2196 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n", 2197 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2)); 2198 va_end(va2); 2199 #endif 2200 2201 PVM pVM = pDevIns->Internal.s.pVMR3; 2202 VM_ASSERT_EMT(pVM); 2203 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args); 2204 2205 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2206 return rc; 2207 } 2208 2209 2210 /** @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister */ 2211 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler) 2212 { 2213 PDMDEV_ASSERT_DEVINS(pDevIns); 2214 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n", 2215 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler)); 2216 2217 PVM pVM = pDevIns->Internal.s.pVMR3; 2218 VM_ASSERT_EMT(pVM); 2219 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns); 2220 2221 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2222 return rc; 2223 } 2224 2225 2226 /** @copydoc PDMDEVHLPR3::pfnSTAMRegister */ 2227 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc) 2228 { 2229 PDMDEV_ASSERT_DEVINS(pDevIns); 2230 PVM pVM = pDevIns->Internal.s.pVMR3; 2231 VM_ASSERT_EMT(pVM); 2232 2233 STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); 2234 NOREF(pVM); 2235 } 2236 2237 2238 2239 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterF */ 2240 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 2241 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...) 2242 { 2243 PDMDEV_ASSERT_DEVINS(pDevIns); 2244 PVM pVM = pDevIns->Internal.s.pVMR3; 2245 VM_ASSERT_EMT(pVM); 2246 2247 va_list args; 2248 va_start(args, pszName); 2249 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 2250 va_end(args); 2251 AssertRC(rc); 2252 2253 NOREF(pVM); 2254 } 2255 2256 2257 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterV */ 2258 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 2259 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args) 2260 { 2261 PDMDEV_ASSERT_DEVINS(pDevIns); 2262 PVM pVM = pDevIns->Internal.s.pVMR3; 2263 VM_ASSERT_EMT(pVM); 2264 2265 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 2266 AssertRC(rc); 2267 2268 NOREF(pVM); 2269 } 2270 2271 2272 /** @copydoc PDMDEVHLPR3::pfnRTCRegister */ 2273 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp) 2274 { 2275 PDMDEV_ASSERT_DEVINS(pDevIns); 2276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2277 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n", 2278 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite, 2279 pRtcReg->pfnWrite, ppRtcHlp)); 2280 2281 /* 2282 * Validate input. 2283 */ 2284 if (pRtcReg->u32Version != PDM_RTCREG_VERSION) 2285 { 2286 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version, 2287 PDM_RTCREG_VERSION)); 2288 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n", 2289 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2290 return VERR_INVALID_PARAMETER; 2291 } 2292 if ( !pRtcReg->pfnWrite 2293 || !pRtcReg->pfnRead) 2294 { 2295 Assert(pRtcReg->pfnWrite); 2296 Assert(pRtcReg->pfnRead); 2297 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 2298 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2299 return VERR_INVALID_PARAMETER; 2300 } 2301 2302 if (!ppRtcHlp) 2303 { 2304 Assert(ppRtcHlp); 2305 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n", 2306 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2307 return VERR_INVALID_PARAMETER; 2308 } 2309 2310 /* 2311 * Only one DMA device. 2312 */ 2313 PVM pVM = pDevIns->Internal.s.pVMR3; 2314 if (pVM->pdm.s.pRtc) 2315 { 2316 AssertMsgFailed(("Only one RTC device is supported!\n")); 2317 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 2318 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2319 return VERR_INVALID_PARAMETER; 2320 } 2321 2322 /* 2323 * Allocate and initialize pci bus structure. 2324 */ 2325 int rc = VINF_SUCCESS; 2326 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc)); 2327 if (pRtc) 2328 { 2329 pRtc->pDevIns = pDevIns; 2330 pRtc->Reg = *pRtcReg; 2331 pVM->pdm.s.pRtc = pRtc; 2332 2333 /* set the helper pointer. */ 2334 *ppRtcHlp = &g_pdmR3DevRtcHlp; 2335 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n", 2336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2337 } 2338 else 2339 rc = VERR_NO_MEMORY; 2340 2341 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 2342 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2343 return rc; 2344 } 2345 2346 2347 /** @copydoc PDMDEVHLPR3::pfnPDMQueueCreate */ 2348 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, 2349 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue) 2350 { 2351 PDMDEV_ASSERT_DEVINS(pDevIns); 2352 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n", 2353 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue)); 2354 2355 PVM pVM = pDevIns->Internal.s.pVMR3; 2356 VM_ASSERT_EMT(pVM); 2357 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue); 2358 2359 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue)); 2360 return rc; 2361 } 2362 2363 2364 /** @copydoc PDMDEVHLPR3::pfnCritSectInit */ 2365 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName) 2366 { 2367 PDMDEV_ASSERT_DEVINS(pDevIns); 2368 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n", 2369 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName)); 2370 2371 PVM pVM = pDevIns->Internal.s.pVMR3; 2372 VM_ASSERT_EMT(pVM); 2373 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName); 2374 2375 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2376 return rc; 2377 } 2378 2379 2380 /** @copydoc PDMDEVHLPR3::pfnUTCNow */ 2381 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime) 2382 { 2383 PDMDEV_ASSERT_DEVINS(pDevIns); 2384 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n", 2385 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime)); 2386 2387 pTime = TMR3UTCNow(pDevIns->Internal.s.pVMR3, pTime); 2388 2389 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime))); 2390 return pTime; 2391 } 2392 2393 2394 /** @copydoc PDMDEVHLPR3::pfnPDMThreadCreate */ 2395 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 2396 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 2397 { 2398 PDMDEV_ASSERT_DEVINS(pDevIns); 2399 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2400 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n", 2401 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName)); 2402 2403 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 2404 2405 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 2406 rc, *ppThread)); 2407 return rc; 2408 } 2409 2410 2411 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 2412 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns) 2413 { 2414 PDMDEV_ASSERT_DEVINS(pDevIns); 2415 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3)); 2416 return pDevIns->Internal.s.pVMR3; 2417 } 2418 2419 2420 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 2421 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 2422 { 2423 PDMDEV_ASSERT_DEVINS(pDevIns); 2424 PVM pVM = pDevIns->Internal.s.pVMR3; 2425 VM_ASSERT_EMT(pVM); 2426 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, " 2427 ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n", 2428 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3, 2429 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3, 2430 pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3)); 2431 2432 /* 2433 * Validate the structure. 2434 */ 2435 if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION) 2436 { 2437 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION)); 2438 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2439 return VERR_INVALID_PARAMETER; 2440 } 2441 if ( !pPciBusReg->pfnRegisterR3 2442 || !pPciBusReg->pfnIORegionRegisterR3 2443 || !pPciBusReg->pfnSetIrqR3 2444 || !pPciBusReg->pfnSaveExecR3 2445 || !pPciBusReg->pfnLoadExecR3 2446 || !pPciBusReg->pfnFakePCIBIOSR3) 2447 { 2448 Assert(pPciBusReg->pfnRegisterR3); 2449 Assert(pPciBusReg->pfnIORegionRegisterR3); 2450 Assert(pPciBusReg->pfnSetIrqR3); 2451 Assert(pPciBusReg->pfnSaveExecR3); 2452 Assert(pPciBusReg->pfnLoadExecR3); 2453 Assert(pPciBusReg->pfnFakePCIBIOSR3); 2454 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2455 return VERR_INVALID_PARAMETER; 2456 } 2457 if ( pPciBusReg->pszSetIrqRC 2458 && !VALID_PTR(pPciBusReg->pszSetIrqRC)) 2459 { 2460 Assert(VALID_PTR(pPciBusReg->pszSetIrqRC)); 2461 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2462 return VERR_INVALID_PARAMETER; 2463 } 2464 if ( pPciBusReg->pszSetIrqR0 2465 && !VALID_PTR(pPciBusReg->pszSetIrqR0)) 2466 { 2467 Assert(VALID_PTR(pPciBusReg->pszSetIrqR0)); 2468 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2469 return VERR_INVALID_PARAMETER; 2470 } 2471 if (!ppPciHlpR3) 2472 { 2473 Assert(ppPciHlpR3); 2474 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2475 return VERR_INVALID_PARAMETER; 2476 } 2477 2478 /* 2479 * Find free PCI bus entry. 2480 */ 2481 unsigned iBus = 0; 2482 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++) 2483 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3) 2484 break; 2485 if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses)) 2486 { 2487 AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses))); 2488 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2489 return VERR_INVALID_PARAMETER; 2490 } 2491 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus]; 2492 2493 /* 2494 * Resolve and init the RC bits. 2495 */ 2496 if (pPciBusReg->pszSetIrqRC) 2497 { 2498 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC); 2499 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, rc)); 2500 if (VBOX_FAILURE(rc)) 2501 { 2502 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2503 return rc; 2504 } 2505 pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2506 } 2507 else 2508 { 2509 pPciBus->pfnSetIrqRC = 0; 2510 pPciBus->pDevInsRC = 0; 2511 } 2512 2513 /* 2514 * Resolve and init the R0 bits. 2515 */ 2516 if (pPciBusReg->pszSetIrqR0) 2517 { 2518 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0); 2519 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc)); 2520 if (VBOX_FAILURE(rc)) 2521 { 2522 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2523 return rc; 2524 } 2525 pPciBus->pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2526 } 2527 else 2528 { 2529 pPciBus->pfnSetIrqR0 = 0; 2530 pPciBus->pDevInsR0 = 0; 2531 } 2532 2533 /* 2534 * Init the R3 bits. 2535 */ 2536 pPciBus->iBus = iBus; 2537 pPciBus->pDevInsR3 = pDevIns; 2538 pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3; 2539 pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3; 2540 pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3; 2541 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3; 2542 pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3; 2543 pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3; 2544 pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3; 2545 2546 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2547 2548 /* set the helper pointer and return. */ 2549 *ppPciHlpR3 = &g_pdmR3DevPciHlp; 2550 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2551 return VINF_SUCCESS; 2552 } 2553 2554 2555 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 2556 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 2557 { 2558 PDMDEV_ASSERT_DEVINS(pDevIns); 2559 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2560 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n", 2561 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3, 2562 pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC, 2563 pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0, 2564 ppPicHlpR3)); 2565 2566 /* 2567 * Validate input. 2568 */ 2569 if (pPicReg->u32Version != PDM_PICREG_VERSION) 2570 { 2571 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION)); 2572 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2573 return VERR_INVALID_PARAMETER; 2574 } 2575 if ( !pPicReg->pfnSetIrqR3 2576 || !pPicReg->pfnGetInterruptR3) 2577 { 2578 Assert(pPicReg->pfnSetIrqR3); 2579 Assert(pPicReg->pfnGetInterruptR3); 2580 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2581 return VERR_INVALID_PARAMETER; 2582 } 2583 if ( ( pPicReg->pszSetIrqRC 2584 || pPicReg->pszGetInterruptRC) 2585 && ( !VALID_PTR(pPicReg->pszSetIrqRC) 2586 || !VALID_PTR(pPicReg->pszGetInterruptRC)) 2587 ) 2588 { 2589 Assert(VALID_PTR(pPicReg->pszSetIrqRC)); 2590 Assert(VALID_PTR(pPicReg->pszGetInterruptRC)); 2591 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2592 return VERR_INVALID_PARAMETER; 2593 } 2594 if ( pPicReg->pszSetIrqRC 2595 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 2596 { 2597 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC); 2598 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2599 return VERR_INVALID_PARAMETER; 2600 } 2601 if ( pPicReg->pszSetIrqR0 2602 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 2603 { 2604 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0); 2605 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2606 return VERR_INVALID_PARAMETER; 2607 } 2608 if (!ppPicHlpR3) 2609 { 2610 Assert(ppPicHlpR3); 2611 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2612 return VERR_INVALID_PARAMETER; 2613 } 2614 2615 /* 2616 * Only one PIC device. 2617 */ 2618 PVM pVM = pDevIns->Internal.s.pVMR3; 2619 if (pVM->pdm.s.Pic.pDevInsR3) 2620 { 2621 AssertMsgFailed(("Only one pic device is supported!\n")); 2622 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2623 return VERR_INVALID_PARAMETER; 2624 } 2625 2626 /* 2627 * RC stuff. 2628 */ 2629 if (pPicReg->pszSetIrqRC) 2630 { 2631 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC); 2632 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, rc)); 2633 if (VBOX_SUCCESS(rc)) 2634 { 2635 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC); 2636 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, rc)); 2637 } 2638 if (VBOX_FAILURE(rc)) 2639 { 2640 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2641 return rc; 2642 } 2643 pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2644 } 2645 else 2646 { 2647 pVM->pdm.s.Pic.pDevInsRC = 0; 2648 pVM->pdm.s.Pic.pfnSetIrqRC = 0; 2649 pVM->pdm.s.Pic.pfnGetInterruptRC = 0; 2650 } 2651 2652 /* 2653 * R0 stuff. 2654 */ 2655 if (pPicReg->pszSetIrqR0) 2656 { 2657 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0); 2658 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc)); 2659 if (VBOX_SUCCESS(rc)) 2660 { 2661 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0); 2662 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc)); 2663 } 2664 if (VBOX_FAILURE(rc)) 2665 { 2666 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2667 return rc; 2668 } 2669 pVM->pdm.s.Pic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2670 Assert(pVM->pdm.s.Pic.pDevInsR0); 2671 } 2672 else 2673 { 2674 pVM->pdm.s.Pic.pfnSetIrqR0 = 0; 2675 pVM->pdm.s.Pic.pfnGetInterruptR0 = 0; 2676 pVM->pdm.s.Pic.pDevInsR0 = 0; 2677 } 2678 2679 /* 2680 * R3 stuff. 2681 */ 2682 pVM->pdm.s.Pic.pDevInsR3 = pDevIns; 2683 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3; 2684 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3; 2685 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2686 2687 /* set the helper pointer and return. */ 2688 *ppPicHlpR3 = &g_pdmR3DevPicHlp; 2689 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2690 return VINF_SUCCESS; 2691 } 2692 2693 2694 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 2695 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 2696 { 2697 PDMDEV_ASSERT_DEVINS(pDevIns); 2698 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2699 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, " 2700 ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, " 2701 ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n", 2702 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3, 2703 pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC, 2704 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC, 2705 pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC, 2706 pApicReg->pszBusDeliverRC, ppApicHlpR3)); 2707 2708 /* 2709 * Validate input. 2710 */ 2711 if (pApicReg->u32Version != PDM_APICREG_VERSION) 2712 { 2713 AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION)); 2714 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2715 return VERR_INVALID_PARAMETER; 2716 } 2717 if ( !pApicReg->pfnGetInterruptR3 2718 || !pApicReg->pfnHasPendingIrqR3 2719 || !pApicReg->pfnSetBaseR3 2720 || !pApicReg->pfnGetBaseR3 2721 || !pApicReg->pfnSetTPRR3 2722 || !pApicReg->pfnGetTPRR3 2723 || !pApicReg->pfnBusDeliverR3) 2724 { 2725 Assert(pApicReg->pfnGetInterruptR3); 2726 Assert(pApicReg->pfnHasPendingIrqR3); 2727 Assert(pApicReg->pfnSetBaseR3); 2728 Assert(pApicReg->pfnGetBaseR3); 2729 Assert(pApicReg->pfnSetTPRR3); 2730 Assert(pApicReg->pfnGetTPRR3); 2731 Assert(pApicReg->pfnBusDeliverR3); 2732 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2733 return VERR_INVALID_PARAMETER; 2734 } 2735 if ( ( pApicReg->pszGetInterruptRC 2736 || pApicReg->pszHasPendingIrqRC 2737 || pApicReg->pszSetBaseRC 2738 || pApicReg->pszGetBaseRC 2739 || pApicReg->pszSetTPRRC 2740 || pApicReg->pszGetTPRRC 2741 || pApicReg->pszBusDeliverRC) 2742 && ( !VALID_PTR(pApicReg->pszGetInterruptRC) 2743 || !VALID_PTR(pApicReg->pszHasPendingIrqRC) 2744 || !VALID_PTR(pApicReg->pszSetBaseRC) 2745 || !VALID_PTR(pApicReg->pszGetBaseRC) 2746 || !VALID_PTR(pApicReg->pszSetTPRRC) 2747 || !VALID_PTR(pApicReg->pszGetTPRRC) 2748 || !VALID_PTR(pApicReg->pszBusDeliverRC)) 2749 ) 2750 { 2751 Assert(VALID_PTR(pApicReg->pszGetInterruptRC)); 2752 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC)); 2753 Assert(VALID_PTR(pApicReg->pszSetBaseRC)); 2754 Assert(VALID_PTR(pApicReg->pszGetBaseRC)); 2755 Assert(VALID_PTR(pApicReg->pszSetTPRRC)); 2756 Assert(VALID_PTR(pApicReg->pszGetTPRRC)); 2757 Assert(VALID_PTR(pApicReg->pszBusDeliverRC)); 2758 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2759 return VERR_INVALID_PARAMETER; 2760 } 2761 if ( ( pApicReg->pszGetInterruptR0 2762 || pApicReg->pszHasPendingIrqR0 2763 || pApicReg->pszSetBaseR0 2764 || pApicReg->pszGetBaseR0 2765 || pApicReg->pszSetTPRR0 2766 || pApicReg->pszGetTPRR0 2767 || pApicReg->pszBusDeliverR0) 2768 && ( !VALID_PTR(pApicReg->pszGetInterruptR0) 2769 || !VALID_PTR(pApicReg->pszHasPendingIrqR0) 2770 || !VALID_PTR(pApicReg->pszSetBaseR0) 2771 || !VALID_PTR(pApicReg->pszGetBaseR0) 2772 || !VALID_PTR(pApicReg->pszSetTPRR0) 2773 || !VALID_PTR(pApicReg->pszGetTPRR0) 2774 || !VALID_PTR(pApicReg->pszBusDeliverR0)) 2775 ) 2776 { 2777 Assert(VALID_PTR(pApicReg->pszGetInterruptR0)); 2778 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0)); 2779 Assert(VALID_PTR(pApicReg->pszSetBaseR0)); 2780 Assert(VALID_PTR(pApicReg->pszGetBaseR0)); 2781 Assert(VALID_PTR(pApicReg->pszSetTPRR0)); 2782 Assert(VALID_PTR(pApicReg->pszGetTPRR0)); 2783 Assert(VALID_PTR(pApicReg->pszBusDeliverR0)); 2784 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2785 return VERR_INVALID_PARAMETER; 2786 } 2787 if (!ppApicHlpR3) 2788 { 2789 Assert(ppApicHlpR3); 2790 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2791 return VERR_INVALID_PARAMETER; 2792 } 2793 2794 /* 2795 * Only one APIC device. (malc: only in UP case actually) 2796 */ 2797 PVM pVM = pDevIns->Internal.s.pVMR3; 2798 if (pVM->pdm.s.Apic.pDevInsR3) 2799 { 2800 AssertMsgFailed(("Only one apic device is supported!\n")); 2801 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2802 return VERR_INVALID_PARAMETER; 2803 } 2804 2805 /* 2806 * Resolve & initialize the RC bits. 2807 */ 2808 if (pApicReg->pszGetInterruptRC) 2809 { 2810 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC); 2811 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, rc)); 2812 if (RT_SUCCESS(rc)) 2813 { 2814 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC); 2815 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc)); 2816 } 2817 if (RT_SUCCESS(rc)) 2818 { 2819 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC); 2820 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, rc)); 2821 } 2822 if (RT_SUCCESS(rc)) 2823 { 2824 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC); 2825 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, rc)); 2826 } 2827 if (RT_SUCCESS(rc)) 2828 { 2829 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC); 2830 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, rc)); 2831 } 2832 if (RT_SUCCESS(rc)) 2833 { 2834 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC); 2835 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc)); 2836 } 2837 if (RT_SUCCESS(rc)) 2838 { 2839 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC); 2840 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc)); 2841 } 2842 if (VBOX_FAILURE(rc)) 2843 { 2844 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2845 return rc; 2846 } 2847 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2848 } 2849 else 2850 { 2851 pVM->pdm.s.Apic.pDevInsRC = 0; 2852 pVM->pdm.s.Apic.pfnGetInterruptRC = 0; 2853 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0; 2854 pVM->pdm.s.Apic.pfnSetBaseRC = 0; 2855 pVM->pdm.s.Apic.pfnGetBaseRC = 0; 2856 pVM->pdm.s.Apic.pfnSetTPRRC = 0; 2857 pVM->pdm.s.Apic.pfnGetTPRRC = 0; 2858 pVM->pdm.s.Apic.pfnBusDeliverRC = 0; 2859 } 2860 2861 /* 2862 * Resolve & initialize the R0 bits. 2863 */ 2864 if (pApicReg->pszGetInterruptR0) 2865 { 2866 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0); 2867 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc)); 2868 if (RT_SUCCESS(rc)) 2869 { 2870 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0); 2871 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc)); 2872 } 2873 if (RT_SUCCESS(rc)) 2874 { 2875 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0); 2876 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc)); 2877 } 2878 if (RT_SUCCESS(rc)) 2879 { 2880 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0); 2881 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc)); 2882 } 2883 if (RT_SUCCESS(rc)) 2884 { 2885 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0); 2886 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc)); 2887 } 2888 if (RT_SUCCESS(rc)) 2889 { 2890 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0); 2891 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc)); 2892 } 2893 if (RT_SUCCESS(rc)) 2894 { 2895 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0); 2896 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc)); 2897 } 2898 if (VBOX_FAILURE(rc)) 2899 { 2900 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2901 return rc; 2902 } 2903 pVM->pdm.s.Apic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2904 Assert(pVM->pdm.s.Apic.pDevInsR0); 2905 } 2906 else 2907 { 2908 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0; 2909 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0; 2910 pVM->pdm.s.Apic.pfnSetBaseR0 = 0; 2911 pVM->pdm.s.Apic.pfnGetBaseR0 = 0; 2912 pVM->pdm.s.Apic.pfnSetTPRR0 = 0; 2913 pVM->pdm.s.Apic.pfnGetTPRR0 = 0; 2914 pVM->pdm.s.Apic.pfnBusDeliverR0 = 0; 2915 pVM->pdm.s.Apic.pDevInsR0 = 0; 2916 } 2917 2918 /* 2919 * Initialize the HC bits. 2920 */ 2921 pVM->pdm.s.Apic.pDevInsR3 = pDevIns; 2922 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3; 2923 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3; 2924 pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3; 2925 pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3; 2926 pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3; 2927 pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3; 2928 pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3; 2929 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2930 2931 /* set the helper pointer and return. */ 2932 *ppApicHlpR3 = &g_pdmR3DevApicHlp; 2933 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2934 return VINF_SUCCESS; 2935 } 2936 2937 2938 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 2939 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 2940 { 2941 PDMDEV_ASSERT_DEVINS(pDevIns); 2942 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2943 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n", 2944 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3, 2945 pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3)); 2946 2947 /* 2948 * Validate input. 2949 */ 2950 if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION) 2951 { 2952 AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION)); 2953 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2954 return VERR_INVALID_PARAMETER; 2955 } 2956 if (!pIoApicReg->pfnSetIrqR3) 2957 { 2958 Assert(pIoApicReg->pfnSetIrqR3); 2959 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2960 return VERR_INVALID_PARAMETER; 2961 } 2962 if ( pIoApicReg->pszSetIrqRC 2963 && !VALID_PTR(pIoApicReg->pszSetIrqRC)) 2964 { 2965 Assert(VALID_PTR(pIoApicReg->pszSetIrqRC)); 2966 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2967 return VERR_INVALID_PARAMETER; 2968 } 2969 if ( pIoApicReg->pszSetIrqR0 2970 && !VALID_PTR(pIoApicReg->pszSetIrqR0)) 2971 { 2972 Assert(VALID_PTR(pIoApicReg->pszSetIrqR0)); 2973 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2974 return VERR_INVALID_PARAMETER; 2975 } 2976 if (!ppIoApicHlpR3) 2977 { 2978 Assert(ppIoApicHlpR3); 2979 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2980 return VERR_INVALID_PARAMETER; 2981 } 2982 2983 /* 2984 * The I/O APIC requires the APIC to be present (hacks++). 2985 * If the I/O APIC does GC stuff so must the APIC. 2986 */ 2987 PVM pVM = pDevIns->Internal.s.pVMR3; 2988 if (!pVM->pdm.s.Apic.pDevInsR3) 2989 { 2990 AssertMsgFailed(("Configuration error / Init order error! No APIC!\n")); 2991 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2992 return VERR_INVALID_PARAMETER; 2993 } 2994 if ( pIoApicReg->pszSetIrqRC 2995 && !pVM->pdm.s.Apic.pDevInsRC) 2996 { 2997 AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n")); 2998 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2999 return VERR_INVALID_PARAMETER; 3000 } 3001 3002 /* 3003 * Only one I/O APIC device. 3004 */ 3005 if (pVM->pdm.s.IoApic.pDevInsR3) 3006 { 3007 AssertMsgFailed(("Only one ioapic device is supported!\n")); 3008 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3009 return VERR_INVALID_PARAMETER; 3010 } 3011 3012 /* 3013 * Resolve & initialize the GC bits. 3014 */ 3015 if (pIoApicReg->pszSetIrqRC) 3016 { 3017 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC); 3018 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, rc)); 3019 if (VBOX_FAILURE(rc)) 3020 { 3021 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3022 return rc; 3023 } 3024 pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 3025 } 3026 else 3027 { 3028 pVM->pdm.s.IoApic.pDevInsRC = 0; 3029 pVM->pdm.s.IoApic.pfnSetIrqRC = 0; 3030 } 3031 3032 /* 3033 * Resolve & initialize the R0 bits. 3034 */ 3035 if (pIoApicReg->pszSetIrqR0) 3036 { 3037 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0); 3038 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc)); 3039 if (VBOX_FAILURE(rc)) 3040 { 3041 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3042 return rc; 3043 } 3044 pVM->pdm.s.IoApic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 3045 Assert(pVM->pdm.s.IoApic.pDevInsR0); 3046 } 3047 else 3048 { 3049 pVM->pdm.s.IoApic.pfnSetIrqR0 = 0; 3050 pVM->pdm.s.IoApic.pDevInsR0 = 0; 3051 } 3052 3053 /* 3054 * Initialize the R3 bits. 3055 */ 3056 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns; 3057 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3; 3058 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 3059 3060 /* set the helper pointer and return. */ 3061 *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp; 3062 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 3063 return VINF_SUCCESS; 3064 } 3065 3066 3067 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 3068 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 3069 { 3070 PDMDEV_ASSERT_DEVINS(pDevIns); 3071 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3072 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n", 3073 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister, 3074 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp)); 3075 3076 /* 3077 * Validate input. 3078 */ 3079 if (pDmacReg->u32Version != PDM_DMACREG_VERSION) 3080 { 3081 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version, 3082 PDM_DMACREG_VERSION)); 3083 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n", 3084 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3085 return VERR_INVALID_PARAMETER; 3086 } 3087 if ( !pDmacReg->pfnRun 3088 || !pDmacReg->pfnRegister 3089 || !pDmacReg->pfnReadMemory 3090 || !pDmacReg->pfnWriteMemory 3091 || !pDmacReg->pfnSetDREQ 3092 || !pDmacReg->pfnGetChannelMode) 3093 { 3094 Assert(pDmacReg->pfnRun); 3095 Assert(pDmacReg->pfnRegister); 3096 Assert(pDmacReg->pfnReadMemory); 3097 Assert(pDmacReg->pfnWriteMemory); 3098 Assert(pDmacReg->pfnSetDREQ); 3099 Assert(pDmacReg->pfnGetChannelMode); 3100 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 3101 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3102 return VERR_INVALID_PARAMETER; 3103 } 3104 3105 if (!ppDmacHlp) 3106 { 3107 Assert(ppDmacHlp); 3108 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n", 3109 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3110 return VERR_INVALID_PARAMETER; 3111 } 3112 3113 /* 3114 * Only one DMA device. 3115 */ 3116 PVM pVM = pDevIns->Internal.s.pVMR3; 3117 if (pVM->pdm.s.pDmac) 3118 { 3119 AssertMsgFailed(("Only one DMA device is supported!\n")); 3120 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 3121 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3122 return VERR_INVALID_PARAMETER; 3123 } 3124 3125 /* 3126 * Allocate and initialize pci bus structure. 3127 */ 3128 int rc = VINF_SUCCESS; 3129 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac)); 3130 if (pDmac) 3131 { 3132 pDmac->pDevIns = pDevIns; 3133 pDmac->Reg = *pDmacReg; 3134 pVM->pdm.s.pDmac = pDmac; 3135 3136 /* set the helper pointer. */ 3137 *ppDmacHlp = &g_pdmR3DevDmacHlp; 3138 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n", 3139 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 3140 } 3141 else 3142 rc = VERR_NO_MEMORY; 3143 3144 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 3145 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3146 return rc; 3147 } 3148 3149 3150 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 3151 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 3152 { 3153 PDMDEV_ASSERT_DEVINS(pDevIns); 3154 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n", 3155 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead)); 3156 3157 /* 3158 * For the convenience of the device we put no thread restriction on this interface. 3159 * That means we'll have to check which thread we're in and choose our path. 3160 */ 3161 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 3162 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3163 #else 3164 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 3165 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3166 else 3167 { 3168 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3169 PVMREQ pReq; 3170 AssertCompileSize(RTGCPHYS, 4); 3171 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 3172 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3173 while (rc == VERR_TIMEOUT) 3174 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 3175 AssertReleaseRC(rc); 3176 VMR3ReqFree(pReq); 3177 } 3178 #endif 3179 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3180 } 3181 3182 3183 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 3184 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 3185 { 3186 PDMDEV_ASSERT_DEVINS(pDevIns); 3187 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n", 3188 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite)); 3189 3190 /* 3191 * For the convenience of the device we put no thread restriction on this interface. 3192 * That means we'll have to check which thread we're in and choose our path. 3193 */ 3194 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 3195 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3196 #else 3197 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 3198 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3199 else 3200 { 3201 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3202 PVMREQ pReq; 3203 AssertCompileSize(RTGCPHYS, 4); 3204 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 3205 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3206 while (rc == VERR_TIMEOUT) 3207 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 3208 AssertReleaseRC(rc); 3209 VMR3ReqFree(pReq); 3210 } 3211 #endif 3212 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3213 } 3214 3215 3216 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 3217 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 3218 { 3219 PDMDEV_ASSERT_DEVINS(pDevIns); 3220 PVM pVM = pDevIns->Internal.s.pVMR3; 3221 VM_ASSERT_EMT(pVM); 3222 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n", 3223 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb)); 3224 3225 if (!VM_IS_EMT(pVM)) 3226 return VERR_ACCESS_DENIED; 3227 3228 int rc = PGMPhysReadGCPtr(pVM, pvDst, GCVirtSrc, cb); 3229 3230 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3231 3232 return rc; 3233 } 3234 3235 3236 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 3237 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 3238 { 3239 PDMDEV_ASSERT_DEVINS(pDevIns); 3240 PVM pVM = pDevIns->Internal.s.pVMR3; 3241 VM_ASSERT_EMT(pVM); 3242 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n", 3243 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb)); 3244 3245 if (!VM_IS_EMT(pVM)) 3246 return VERR_ACCESS_DENIED; 3247 3248 int rc = PGMPhysWriteGCPtr(pVM, GCVirtDst, pvSrc, cb); 3249 3250 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3251 3252 return rc; 3253 } 3254 3255 3256 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 3257 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 3258 { 3259 PDMDEV_ASSERT_DEVINS(pDevIns); 3260 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3261 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n", 3262 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc)); 3263 3264 int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMR3, GCPhys, cbRange, pszDesc); 3265 3266 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3267 3268 return rc; 3269 } 3270 3271 3272 /** @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys */ 3273 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys) 3274 { 3275 PDMDEV_ASSERT_DEVINS(pDevIns); 3276 PVM pVM = pDevIns->Internal.s.pVMR3; 3277 VM_ASSERT_EMT(pVM); 3278 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n", 3279 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys)); 3280 3281 if (!VM_IS_EMT(pVM)) 3282 return VERR_ACCESS_DENIED; 3283 3284 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys); 3285 3286 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys)); 3287 3288 return rc; 3289 } 3290 3291 3292 /** @copydoc PDMDEVHLPR3::pfnVMState */ 3293 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns) 3294 { 3295 PDMDEV_ASSERT_DEVINS(pDevIns); 3296 3297 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3); 3298 3299 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 3300 enmVMState, VMR3GetStateName(enmVMState))); 3301 return enmVMState; 3302 } 3303 3304 3305 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 3306 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns) 3307 { 3308 PDMDEV_ASSERT_DEVINS(pDevIns); 3309 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3310 3311 bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMR3); 3312 3313 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc)); 3314 return fRc; 3315 } 3316 3317 3318 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 3319 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable) 3320 { 3321 PDMDEV_ASSERT_DEVINS(pDevIns); 3322 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3323 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable)); 3324 //Assert(*(unsigned *)&fEnable <= 1); 3325 PGMR3PhysSetA20(pDevIns->Internal.s.pVMR3, fEnable); 3326 } 3327 3328 3329 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 3330 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns) 3331 { 3332 PDMDEV_ASSERT_DEVINS(pDevIns); 3333 PVM pVM = pDevIns->Internal.s.pVMR3; 3334 VM_ASSERT_EMT(pVM); 3335 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n", 3336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET))); 3337 3338 /* 3339 * We postpone this operation because we're likely to be inside a I/O instruction 3340 * and the EIP will be updated when we return. 3341 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation. 3342 */ 3343 bool fHaltOnReset; 3344 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset); 3345 if (VBOX_SUCCESS(rc) && fHaltOnReset) 3346 { 3347 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n")); 3348 rc = VINF_EM_HALT; 3349 } 3350 else 3351 { 3352 VM_FF_SET(pVM, VM_FF_RESET); 3353 rc = VINF_EM_RESET; 3354 } 3355 3356 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3357 return rc; 3358 } 3359 3360 3361 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 3362 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns) 3363 { 3364 PDMDEV_ASSERT_DEVINS(pDevIns); 3365 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3366 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n", 3367 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3368 3369 int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3); 3370 3371 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3372 return rc; 3373 } 3374 3375 3376 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 3377 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns) 3378 { 3379 PDMDEV_ASSERT_DEVINS(pDevIns); 3380 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3381 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n", 3382 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3383 3384 int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3); 3385 3386 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3387 return rc; 3388 } 3389 3390 3391 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 3392 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns) 3393 { 3394 return VMMR3Lock(pDevIns->Internal.s.pVMR3); 3395 } 3396 3397 3398 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 3399 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns) 3400 { 3401 return VMMR3Unlock(pDevIns->Internal.s.pVMR3); 3402 } 3403 3404 3405 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 3406 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 3407 { 3408 PVM pVM = pDevIns->Internal.s.pVMR3; 3409 if (VMMR3LockIsOwner(pVM)) 3410 return true; 3411 3412 RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM); 3413 RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner); 3414 char szMsg[100]; 3415 RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n", 3416 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 3417 NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName()); 3418 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 3419 AssertBreakpoint(); 3420 return false; 3421 } 3422 3423 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 3424 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 3425 { 3426 PDMDEV_ASSERT_DEVINS(pDevIns); 3427 PVM pVM = pDevIns->Internal.s.pVMR3; 3428 VM_ASSERT_EMT(pVM); 3429 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n", 3430 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser)); 3431 int rc = VINF_SUCCESS; 3432 if (pVM->pdm.s.pDmac) 3433 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser); 3434 else 3435 { 3436 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3437 rc = VERR_PDM_NO_DMAC_INSTANCE; 3438 } 3439 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n", 3440 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3441 return rc; 3442 } 3443 3444 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 3445 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 3446 { 3447 PDMDEV_ASSERT_DEVINS(pDevIns); 3448 PVM pVM = pDevIns->Internal.s.pVMR3; 3449 VM_ASSERT_EMT(pVM); 3450 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n", 3451 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead)); 3452 int rc = VINF_SUCCESS; 3453 if (pVM->pdm.s.pDmac) 3454 { 3455 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 3456 if (pcbRead) 3457 *pcbRead = cb; 3458 } 3459 else 3460 { 3461 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3462 rc = VERR_PDM_NO_DMAC_INSTANCE; 3463 } 3464 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n", 3465 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3466 return rc; 3467 } 3468 3469 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 3470 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 3471 { 3472 PDMDEV_ASSERT_DEVINS(pDevIns); 3473 PVM pVM = pDevIns->Internal.s.pVMR3; 3474 VM_ASSERT_EMT(pVM); 3475 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n", 3476 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten)); 3477 int rc = VINF_SUCCESS; 3478 if (pVM->pdm.s.pDmac) 3479 { 3480 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 3481 if (pcbWritten) 3482 *pcbWritten = cb; 3483 } 3484 else 3485 { 3486 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3487 rc = VERR_PDM_NO_DMAC_INSTANCE; 3488 } 3489 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n", 3490 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3491 return rc; 3492 } 3493 3494 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 3495 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 3496 { 3497 PDMDEV_ASSERT_DEVINS(pDevIns); 3498 PVM pVM = pDevIns->Internal.s.pVMR3; 3499 VM_ASSERT_EMT(pVM); 3500 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n", 3501 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel)); 3502 int rc = VINF_SUCCESS; 3503 if (pVM->pdm.s.pDmac) 3504 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel); 3505 else 3506 { 3507 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3508 rc = VERR_PDM_NO_DMAC_INSTANCE; 3509 } 3510 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n", 3511 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3512 return rc; 3513 } 3514 3515 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 3516 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 3517 { 3518 PDMDEV_ASSERT_DEVINS(pDevIns); 3519 PVM pVM = pDevIns->Internal.s.pVMR3; 3520 VM_ASSERT_EMT(pVM); 3521 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n", 3522 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel)); 3523 uint8_t u8Mode; 3524 if (pVM->pdm.s.pDmac) 3525 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel); 3526 else 3527 { 3528 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3529 u8Mode = 3 << 2 /* illegal mode type */; 3530 } 3531 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n", 3532 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode)); 3533 return u8Mode; 3534 } 3535 3536 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 3537 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns) 3538 { 3539 PDMDEV_ASSERT_DEVINS(pDevIns); 3540 PVM pVM = pDevIns->Internal.s.pVMR3; 3541 VM_ASSERT_EMT(pVM); 3542 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n", 3543 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA))); 3544 3545 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3546 VM_FF_SET(pVM, VM_FF_PDM_DMA); 3547 REMR3NotifyDmaPending(pVM); 3548 VMR3NotifyFF(pVM, true); 3549 } 3550 3551 3552 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 3553 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 3554 { 3555 PDMDEV_ASSERT_DEVINS(pDevIns); 3556 PVM pVM = pDevIns->Internal.s.pVMR3; 3557 VM_ASSERT_EMT(pVM); 3558 3559 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n", 3560 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value)); 3561 int rc; 3562 if (pVM->pdm.s.pRtc) 3563 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value); 3564 else 3565 rc = VERR_PDM_NO_RTC_INSTANCE; 3566 3567 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 3568 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3569 return rc; 3570 } 3571 3572 3573 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 3574 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 3575 { 3576 PDMDEV_ASSERT_DEVINS(pDevIns); 3577 PVM pVM = pDevIns->Internal.s.pVMR3; 3578 VM_ASSERT_EMT(pVM); 3579 3580 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n", 3581 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value)); 3582 int rc; 3583 if (pVM->pdm.s.pRtc) 3584 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value); 3585 else 3586 rc = VERR_PDM_NO_RTC_INSTANCE; 3587 3588 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 3589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3590 return rc; 3591 } 3592 3593 3594 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 3595 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 3596 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 3597 { 3598 PDMDEV_ASSERT_DEVINS(pDevIns); 3599 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n", 3600 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx)); 3601 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx); 3602 3603 CPUMGetGuestCpuId(pDevIns->Internal.s.pVMR3, iLeaf, pEax, pEbx, pEcx, pEdx); 3604 3605 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n", 3606 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx)); 3607 } 3608 3609 3610 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 3611 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 3612 { 3613 PDMDEV_ASSERT_DEVINS(pDevIns); 3614 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 3615 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 3616 3617 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange); 3618 3619 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3620 return rc; 3621 } 3622 3623 3624 /** 3625 * @copydoc PDMDEVHLPR3::pfnMMIO2Register 3626 */ 3627 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 3628 { 3629 PDMDEV_ASSERT_DEVINS(pDevIns); 3630 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3631 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n", 3632 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc)); 3633 3634 int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc); 3635 3636 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3637 return rc; 3638 } 3639 3640 3641 /** 3642 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister 3643 */ 3644 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 3645 { 3646 PDMDEV_ASSERT_DEVINS(pDevIns); 3647 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3648 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n", 3649 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion)); 3650 3651 AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER); 3652 3653 int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion); 3654 3655 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3656 return rc; 3657 } 3658 3659 3660 /** 3661 * @copydoc PDMDEVHLPR3::pfnMMIO2Map 3662 */ 3663 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 3664 { 3665 PDMDEV_ASSERT_DEVINS(pDevIns); 3666 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3667 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 3668 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 3669 3670 int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 3671 3672 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3673 return rc; 3674 } 3675 3676 3677 /** 3678 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap 3679 */ 3680 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 3681 { 3682 PDMDEV_ASSERT_DEVINS(pDevIns); 3683 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3684 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 3685 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 3686 3687 int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 3688 3689 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3690 return rc; 3691 } 3692 3693 3694 /** 3695 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 3696 */ 3697 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, 3698 const char *pszDesc, PRTRCPTR pRCPtr) 3699 { 3700 PDMDEV_ASSERT_DEVINS(pDevIns); 3701 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3702 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n", 3703 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr)); 3704 3705 int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, off, cb, pszDesc, pRCPtr); 3706 3707 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr)); 3708 return rc; 3709 } 3710 3711 3712 /** 3713 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap 3714 */ 3715 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 3716 { 3717 PDMDEV_ASSERT_DEVINS(pDevIns); 3718 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3719 3720 int rc = PDMR3RegisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys, pvHeap, cbSize); 3721 return rc; 3722 } 3723 3724 3725 /** 3726 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap 3727 */ 3728 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 3729 { 3730 PDMDEV_ASSERT_DEVINS(pDevIns); 3731 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3732 3733 int rc = PDMR3UnregisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys); 3734 return rc; 3735 } 3736 3737 3738 3739 3740 3741 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 3742 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns) 3743 { 3744 PDMDEV_ASSERT_DEVINS(pDevIns); 3745 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3746 return NULL; 3747 } 3748 3749 3750 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 3751 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 3752 { 3753 PDMDEV_ASSERT_DEVINS(pDevIns); 3754 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3755 NOREF(pPciBusReg); 3756 NOREF(ppPciHlpR3); 3757 return VERR_ACCESS_DENIED; 3758 } 3759 3760 3761 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 3762 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 3763 { 3764 PDMDEV_ASSERT_DEVINS(pDevIns); 3765 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3766 NOREF(pPicReg); 3767 NOREF(ppPicHlpR3); 3768 return VERR_ACCESS_DENIED; 3769 } 3770 3771 3772 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 3773 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 3774 { 3775 PDMDEV_ASSERT_DEVINS(pDevIns); 3776 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3777 NOREF(pApicReg); 3778 NOREF(ppApicHlpR3); 3779 return VERR_ACCESS_DENIED; 3780 } 3781 3782 3783 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 3784 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 3785 { 3786 PDMDEV_ASSERT_DEVINS(pDevIns); 3787 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3788 NOREF(pIoApicReg); 3789 NOREF(ppIoApicHlpR3); 3790 return VERR_ACCESS_DENIED; 3791 } 3792 3793 3794 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 3795 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 3796 { 3797 PDMDEV_ASSERT_DEVINS(pDevIns); 3798 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3799 NOREF(pDmacReg); 3800 NOREF(ppDmacHlp); 3801 return VERR_ACCESS_DENIED; 3802 } 3803 3804 3805 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 3806 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 3807 { 3808 PDMDEV_ASSERT_DEVINS(pDevIns); 3809 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3810 NOREF(GCPhys); 3811 NOREF(pvBuf); 3812 NOREF(cbRead); 3813 } 3814 3815 3816 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 3817 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 3818 { 3819 PDMDEV_ASSERT_DEVINS(pDevIns); 3820 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3821 NOREF(GCPhys); 3822 NOREF(pvBuf); 3823 NOREF(cbWrite); 3824 } 3825 3826 3827 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 3828 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 3829 { 3830 PDMDEV_ASSERT_DEVINS(pDevIns); 3831 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3832 NOREF(pvDst); 3833 NOREF(GCVirtSrc); 3834 NOREF(cb); 3835 return VERR_ACCESS_DENIED; 3836 } 3837 3838 3839 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 3840 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 3841 { 3842 PDMDEV_ASSERT_DEVINS(pDevIns); 3843 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3844 NOREF(GCVirtDst); 3845 NOREF(pvSrc); 3846 NOREF(cb); 3847 return VERR_ACCESS_DENIED; 3848 } 3849 3850 3851 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 3852 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 3853 { 3854 PDMDEV_ASSERT_DEVINS(pDevIns); 3855 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3856 NOREF(GCPhys); 3857 NOREF(cbRange); 3858 return VERR_ACCESS_DENIED; 3859 } 3860 3861 3862 /** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */ 3863 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC) 3864 { 3865 PDMDEV_ASSERT_DEVINS(pDevIns); 3866 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3867 NOREF(GCPhys); 3868 NOREF(cbRange); 3869 NOREF(ppvHC); 3870 return VERR_ACCESS_DENIED; 3871 } 3872 3873 3874 /** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */ 3875 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr) 3876 { 3877 PDMDEV_ASSERT_DEVINS(pDevIns); 3878 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3879 NOREF(GCPtr); 3880 NOREF(pHCPtr); 3881 return VERR_ACCESS_DENIED; 3882 } 3883 3884 3885 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 3886 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns) 3887 { 3888 PDMDEV_ASSERT_DEVINS(pDevIns); 3889 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3890 return false; 3891 } 3892 3893 3894 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 3895 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable) 3896 { 3897 PDMDEV_ASSERT_DEVINS(pDevIns); 3898 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3899 NOREF(fEnable); 3900 } 3901 3902 3903 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 3904 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns) 3905 { 3906 PDMDEV_ASSERT_DEVINS(pDevIns); 3907 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3908 return VERR_ACCESS_DENIED; 3909 } 3910 3911 3912 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 3913 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns) 3914 { 3915 PDMDEV_ASSERT_DEVINS(pDevIns); 3916 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3917 return VERR_ACCESS_DENIED; 3918 } 3919 3920 3921 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 3922 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns) 3923 { 3924 PDMDEV_ASSERT_DEVINS(pDevIns); 3925 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3926 return VERR_ACCESS_DENIED; 3927 } 3928 3929 3930 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 3931 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns) 3932 { 3933 PDMDEV_ASSERT_DEVINS(pDevIns); 3934 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3935 return VERR_ACCESS_DENIED; 3936 } 3937 3938 3939 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 3940 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns) 3941 { 3942 PDMDEV_ASSERT_DEVINS(pDevIns); 3943 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3944 return VERR_ACCESS_DENIED; 3945 } 3946 3947 3948 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 3949 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 3950 { 3951 PDMDEV_ASSERT_DEVINS(pDevIns); 3952 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3953 return false; 3954 } 3955 3956 3957 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 3958 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 3959 { 3960 PDMDEV_ASSERT_DEVINS(pDevIns); 3961 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3962 return VERR_ACCESS_DENIED; 3963 } 3964 3965 3966 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 3967 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 3968 { 3969 PDMDEV_ASSERT_DEVINS(pDevIns); 3970 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3971 if (pcbRead) 3972 *pcbRead = 0; 3973 return VERR_ACCESS_DENIED; 3974 } 3975 3976 3977 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 3978 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 3979 { 3980 PDMDEV_ASSERT_DEVINS(pDevIns); 3981 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3982 if (pcbWritten) 3983 *pcbWritten = 0; 3984 return VERR_ACCESS_DENIED; 3985 } 3986 3987 3988 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 3989 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 3990 { 3991 PDMDEV_ASSERT_DEVINS(pDevIns); 3992 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3993 return VERR_ACCESS_DENIED; 3994 } 3995 3996 3997 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 3998 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 3999 { 4000 PDMDEV_ASSERT_DEVINS(pDevIns); 4001 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4002 return 3 << 2 /* illegal mode type */; 4003 } 4004 4005 4006 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 4007 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns) 4008 { 4009 PDMDEV_ASSERT_DEVINS(pDevIns); 4010 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4011 } 4012 4013 4014 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 4015 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 4016 { 4017 PDMDEV_ASSERT_DEVINS(pDevIns); 4018 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4019 return VERR_ACCESS_DENIED; 4020 } 4021 4022 4023 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 4024 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 4025 { 4026 PDMDEV_ASSERT_DEVINS(pDevIns); 4027 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4028 return VERR_ACCESS_DENIED; 4029 } 4030 4031 4032 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 4033 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 4034 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 4035 { 4036 PDMDEV_ASSERT_DEVINS(pDevIns); 4037 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4038 } 4039 4040 4041 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 4042 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 4043 { 4044 PDMDEV_ASSERT_DEVINS(pDevIns); 4045 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4046 return VERR_ACCESS_DENIED; 4047 } 4048 4049 4050 /** @copydoc PDMDEVHLPR3::pfnMMIO2Register */ 4051 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 4052 { 4053 PDMDEV_ASSERT_DEVINS(pDevIns); 4054 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4055 return VERR_ACCESS_DENIED; 4056 } 4057 4058 4059 /** @copydoc PDMDEVHLPR3::pfnMMIO2Deregister */ 4060 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 4061 { 4062 PDMDEV_ASSERT_DEVINS(pDevIns); 4063 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4064 return VERR_ACCESS_DENIED; 4065 } 4066 4067 4068 /** @copydoc PDMDEVHLPR3::pfnMMIO2Map */ 4069 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 4070 { 4071 PDMDEV_ASSERT_DEVINS(pDevIns); 4072 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4073 return VERR_ACCESS_DENIED; 4074 } 4075 4076 4077 /** @copydoc PDMDEVHLPR3::pfnMMIO2Unmap */ 4078 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 4079 { 4080 PDMDEV_ASSERT_DEVINS(pDevIns); 4081 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4082 return VERR_ACCESS_DENIED; 4083 } 4084 4085 4086 /** @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 */ 4087 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr) 4088 { 4089 PDMDEV_ASSERT_DEVINS(pDevIns); 4090 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4091 return VERR_ACCESS_DENIED; 4092 } 4093 4094 4095 /** @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap */ 4096 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 4097 { 4098 PDMDEV_ASSERT_DEVINS(pDevIns); 4099 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4100 return VERR_ACCESS_DENIED; 4101 } 4102 4103 4104 /** @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap */ 4105 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 4106 { 4107 PDMDEV_ASSERT_DEVINS(pDevIns); 4108 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4109 return VERR_ACCESS_DENIED; 4110 } 4111 4112 4113 4114 4115 4116 /** @copydoc PDMPICHLPR3::pfnSetInterruptFF */ 4117 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns) 4118 { 4119 PDMDEV_ASSERT_DEVINS(pDevIns); 4120 PVM pVM = pDevIns->Internal.s.pVMR3; 4121 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n", 4122 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, 0, VM_FF_INTERRUPT_PIC))); 4123 /* for PIC we always deliver to CPU 0, MP use APIC */ 4124 VMCPU_FF_SET(pVM, 0, VM_FF_INTERRUPT_PIC); 4125 REMR3NotifyInterruptSet(pVM); 4126 VMR3NotifyFF(pVM, true); 4127 } 4128 4129 4130 /** @copydoc PDMPICHLPR3::pfnClearInterruptFF */ 4131 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns) 4132 { 4133 PDMDEV_ASSERT_DEVINS(pDevIns); 4134 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n", 4135 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC))); 4136 /* for PIC we always deliver to CPU 0, MP use APIC */ 4137 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC); 4138 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3); 4139 } 4140 4141 4142 /** @copydoc PDMPICHLPR3::pfnLock */ 4143 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc) 4144 { 4145 PDMDEV_ASSERT_DEVINS(pDevIns); 4146 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 4147 } 4148 4149 4150 /** @copydoc PDMPICHLPR3::pfnUnlock */ 4151 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns) 4152 { 4153 PDMDEV_ASSERT_DEVINS(pDevIns); 4154 pdmUnlock(pDevIns->Internal.s.pVMR3); 4155 } 4156 4157 4158 /** @copydoc PDMPICHLPR3::pfnGetRCHelpers */ 4159 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns) 4160 { 4161 PDMDEV_ASSERT_DEVINS(pDevIns); 4162 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4163 RTRCPTR pRCHelpers = 0; 4164 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers); 4165 AssertReleaseRC(rc); 4166 AssertRelease(pRCHelpers); 4167 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n", 4168 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 4169 return pRCHelpers; 4170 } 4171 4172 4173 /** @copydoc PDMPICHLPR3::pfnGetR0Helpers */ 4174 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns) 4175 { 4176 PDMDEV_ASSERT_DEVINS(pDevIns); 4177 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4178 PCPDMPICHLPR0 pR0Helpers = 0; 4179 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers); 4180 AssertReleaseRC(rc); 4181 AssertRelease(pR0Helpers); 4182 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 4183 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 4184 return pR0Helpers; 4185 } 4186 4187 4188 /** @copydoc PDMAPICHLPR3::pfnSetInterruptFF */ 4189 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu) 4190 { 4191 PDMDEV_ASSERT_DEVINS(pDevIns); 4192 PVM pVM = pDevIns->Internal.s.pVMR3; 4193 LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 1\n", 4194 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, idCpu, VM_FF_INTERRUPT_APIC))); 4195 VMCPU_FF_SET(pVM, idCpu, VM_FF_INTERRUPT_APIC); 4196 REMR3NotifyInterruptSet(pVM); 4197 VMR3NotifyFF(pVM, true); 4198 } 4199 4200 4201 /** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */ 4202 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu) 4203 { 4204 PDMDEV_ASSERT_DEVINS(pDevIns); 4205 LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 0\n", 4206 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC))); 4207 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC); 4208 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3); 4209 } 4210 4211 4212 /** @copydoc PDMAPICHLPR3::pfnChangeFeature */ 4213 static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion) 4214 { 4215 PDMDEV_ASSERT_DEVINS(pDevIns); 4216 LogFlow(("pdmR3ApicHlp_ChangeFeature: caller='%s'/%d: version=%d\n", 4217 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, (int)enmVersion)); 4218 switch (enmVersion) 4219 { 4220 case PDMAPICVERSION_NONE: 4221 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC); 4222 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC); 4223 break; 4224 case PDMAPICVERSION_APIC: 4225 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC); 4226 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC); 4227 break; 4228 case PDMAPICVERSION_X2APIC: 4229 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC); 4230 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC); 4231 break; 4232 default: 4233 AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion)); 4234 } 4235 } 4236 4237 /** @copydoc PDMAPICHLPR3::pfnLock */ 4238 static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc) 4239 { 4240 PDMDEV_ASSERT_DEVINS(pDevIns); 4241 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 4242 } 4243 4244 4245 /** @copydoc PDMAPICHLPR3::pfnUnlock */ 4246 static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns) 4247 { 4248 PDMDEV_ASSERT_DEVINS(pDevIns); 4249 pdmUnlock(pDevIns->Internal.s.pVMR3); 4250 } 4251 4252 4253 /** @copydoc PDMAPICHLPR3::pfnGetCpuId */ 4254 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns) 4255 { 4256 PDMDEV_ASSERT_DEVINS(pDevIns); 4257 return VMMGetCpuId(pDevIns->Internal.s.pVMR3); 4258 } 4259 4260 4261 /** @copydoc PDMAPICHLPR3::pfnGetRCHelpers */ 4262 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns) 4263 { 4264 PDMDEV_ASSERT_DEVINS(pDevIns); 4265 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4266 RTRCPTR pRCHelpers = 0; 4267 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCApicHlp", &pRCHelpers); 4268 AssertReleaseRC(rc); 4269 AssertRelease(pRCHelpers); 4270 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n", 4271 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 4272 return pRCHelpers; 4273 } 4274 4275 4276 /** @copydoc PDMAPICHLPR3::pfnGetR0Helpers */ 4277 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns) 4278 { 4279 PDMDEV_ASSERT_DEVINS(pDevIns); 4280 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4281 PCPDMAPICHLPR0 pR0Helpers = 0; 4282 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0ApicHlp", &pR0Helpers); 4283 AssertReleaseRC(rc); 4284 AssertRelease(pR0Helpers); 4285 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 4286 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 4287 return pR0Helpers; 4288 } 4289 4290 4291 /** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */ 4292 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 4293 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode) 4294 { 4295 PDMDEV_ASSERT_DEVINS(pDevIns); 4296 PVM pVM = pDevIns->Internal.s.pVMR3; 4297 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n", 4298 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode)); 4299 if (pVM->pdm.s.Apic.pfnBusDeliverR3) 4300 pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode); 4301 } 4302 4303 4304 /** @copydoc PDMIOAPICHLPR3::pfnLock */ 4305 static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc) 4306 { 4307 PDMDEV_ASSERT_DEVINS(pDevIns); 4308 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 4309 } 4310 4311 4312 /** @copydoc PDMIOAPICHLPR3::pfnUnlock */ 4313 static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns) 4314 { 4315 PDMDEV_ASSERT_DEVINS(pDevIns); 4316 pdmUnlock(pDevIns->Internal.s.pVMR3); 4317 } 4318 4319 4320 /** @copydoc PDMIOAPICHLPR3::pfnGetRCHelpers */ 4321 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns) 4322 { 4323 PDMDEV_ASSERT_DEVINS(pDevIns); 4324 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4325 RTRCPTR pRCHelpers = 0; 4326 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCIoApicHlp", &pRCHelpers); 4327 AssertReleaseRC(rc); 4328 AssertRelease(pRCHelpers); 4329 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n", 4330 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 4331 return pRCHelpers; 4332 } 4333 4334 4335 /** @copydoc PDMIOAPICHLPR3::pfnGetR0Helpers */ 4336 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns) 4337 { 4338 PDMDEV_ASSERT_DEVINS(pDevIns); 4339 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4340 PCPDMIOAPICHLPR0 pR0Helpers = 0; 4341 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0IoApicHlp", &pR0Helpers); 4342 AssertReleaseRC(rc); 4343 AssertRelease(pR0Helpers); 4344 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 4345 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 4346 return pR0Helpers; 4347 } 4348 4349 4350 /** @copydoc PDMPCIHLPR3::pfnIsaSetIrq */ 4351 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 4352 { 4353 PDMDEV_ASSERT_DEVINS(pDevIns); 4354 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 4355 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel); 4356 } 4357 4358 4359 /** @copydoc PDMPCIHLPR3::pfnIoApicSetIrq */ 4360 static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 4361 { 4362 PDMDEV_ASSERT_DEVINS(pDevIns); 4363 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 4364 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel); 4365 } 4366 4367 4368 /** @copydoc PDMPCIHLPR3::pfnIsMMIO2Base */ 4369 static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys) 4370 { 4371 PDMDEV_ASSERT_DEVINS(pDevIns); 4372 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4373 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys); 4374 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc)); 4375 return fRc; 4376 } 4377 4378 4379 /** @copydoc PDMPCIHLPR3::pfnLock */ 4380 static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc) 4381 { 4382 PDMDEV_ASSERT_DEVINS(pDevIns); 4383 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 4384 } 4385 4386 4387 /** @copydoc PDMPCIHLPR3::pfnUnlock */ 4388 static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns) 4389 { 4390 PDMDEV_ASSERT_DEVINS(pDevIns); 4391 pdmUnlock(pDevIns->Internal.s.pVMR3); 4392 } 4393 4394 4395 /** @copydoc PDMPCIHLPR3::pfnGetRCHelpers */ 4396 static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns) 4397 { 4398 PDMDEV_ASSERT_DEVINS(pDevIns); 4399 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4400 RTRCPTR pRCHelpers = 0; 4401 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciHlp", &pRCHelpers); 4402 AssertReleaseRC(rc); 4403 AssertRelease(pRCHelpers); 4404 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n", 4405 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 4406 return pRCHelpers; 4407 } 4408 4409 4410 /** @copydoc PDMPCIHLPR3::pfnGetR0Helpers */ 4411 static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns) 4412 { 4413 PDMDEV_ASSERT_DEVINS(pDevIns); 4414 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4415 PCPDMPCIHLPR0 pR0Helpers = 0; 4416 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciHlp", &pR0Helpers); 4417 AssertReleaseRC(rc); 4418 AssertRelease(pR0Helpers); 4419 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 4420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 4421 return pR0Helpers; 4422 } 4423 4424 4425 /** 4426 * Locates a LUN. 4427 * 4428 * @returns VBox status code. 4429 * @param pVM VM Handle. 4430 * @param pszDevice Device name. 4431 * @param iInstance Device instance. 4432 * @param iLun The Logical Unit to obtain the interface of. 4433 * @param ppLun Where to store the pointer to the LUN if found. 4434 * @thread Try only do this in EMT... 4435 */ 4436 int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun) 4437 { 4438 /* 4439 * Iterate registered devices looking for the device. 4440 */ 4441 RTUINT cchDevice = strlen(pszDevice); 4442 for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext) 4443 { 4444 if ( pDev->cchName == cchDevice 4445 && !memcmp(pDev->pDevReg->szDeviceName, pszDevice, cchDevice)) 4446 { 4447 /* 4448 * Iterate device instances. 4449 */ 4450 for (PPDMDEVINS pDevIns = pDev->pInstances; pDevIns; pDevIns = pDevIns->Internal.s.pPerDeviceNextR3) 4451 { 4452 if (pDevIns->iInstance == iInstance) 4453 { 4454 /* 4455 * Iterate luns. 4456 */ 4457 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 4458 { 4459 if (pLun->iLun == iLun) 4460 { 4461 *ppLun = pLun; 4462 return VINF_SUCCESS; 4463 } 4464 } 4465 return VERR_PDM_LUN_NOT_FOUND; 4466 } 4467 } 4468 return VERR_PDM_DEVICE_INSTANCE_NOT_FOUND; 4469 } 4470 } 4471 return VERR_PDM_DEVICE_NOT_FOUND; 4472 } 4473 4474 4475 /** 4476 * Attaches a preconfigured driver to an existing device instance. 4477 * 4478 * This is used to change drivers and suchlike at runtime. 4479 * 4480 * @returns VBox status code. 4481 * @param pVM VM Handle. 4482 * @param pszDevice Device name. 4483 * @param iInstance Device instance. 4484 * @param iLun The Logical Unit to obtain the interface of. 4485 * @param ppBase Where to store the base interface pointer. Optional. 4486 * @thread EMT 4487 */ 4488 PDMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase) 4489 { 4490 VM_ASSERT_EMT(pVM); 4491 LogFlow(("PDMR3DeviceAttach: pszDevice=%p:{%s} iInstance=%d iLun=%d ppBase=%p\n", 4492 pszDevice, pszDevice, iInstance, iLun, ppBase)); 4493 4494 /* 4495 * Find the LUN in question. 4496 */ 4497 PPDMLUN pLun; 4498 int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun); 4499 if (VBOX_SUCCESS(rc)) 4500 { 4501 /* 4502 * Can we attach anything at runtime? 4503 */ 4504 PPDMDEVINS pDevIns = pLun->pDevIns; 4505 if (pDevIns->pDevReg->pfnAttach) 4506 { 4507 if (!pLun->pTop) 4508 { 4509 rc = pDevIns->pDevReg->pfnAttach(pDevIns, iLun); 4510 4511 } 4512 else 4513 rc = VERR_PDM_DRIVER_ALREADY_ATTACHED; 4514 } 4515 else 4516 rc = VERR_PDM_DEVICE_NO_RT_ATTACH; 4517 4518 if (ppBase) 4519 *ppBase = pLun->pTop ? &pLun->pTop->IBase : NULL; 4520 } 4521 else if (ppBase) 4522 *ppBase = NULL; 4523 4524 if (ppBase) 4525 LogFlow(("PDMR3DeviceAttach: returns %Vrc *ppBase=%p\n", rc, *ppBase)); 4526 else 4527 LogFlow(("PDMR3DeviceAttach: returns %Vrc\n", rc)); 4528 return rc; 4529 } 4530 4531 4532 /** 4533 * Detaches a driver chain from an existing device instance. 4534 * 4535 * This is used to change drivers and suchlike at runtime. 4536 * 4537 * @returns VBox status code. 4538 * @param pVM VM Handle. 4539 * @param pszDevice Device name. 4540 * @param iInstance Device instance. 4541 * @param iLun The Logical Unit to obtain the interface of. 4542 * @thread EMT 4543 */ 4544 PDMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun) 4545 { 4546 VM_ASSERT_EMT(pVM); 4547 LogFlow(("PDMR3DeviceDetach: pszDevice=%p:{%s} iInstance=%d iLun=%d\n", 4548 pszDevice, pszDevice, iInstance, iLun)); 4549 4550 /* 4551 * Find the LUN in question. 4552 */ 4553 PPDMLUN pLun; 4554 int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun); 4555 if (VBOX_SUCCESS(rc)) 4556 { 4557 /* 4558 * Can we detach anything at runtime? 4559 */ 4560 PPDMDEVINS pDevIns = pLun->pDevIns; 4561 if (pDevIns->pDevReg->pfnDetach) 4562 { 4563 if (pLun->pTop) 4564 rc = pdmR3DrvDetach(pLun->pTop); 4565 else 4566 rc = VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN; 4567 } 4568 else 4569 rc = VERR_PDM_DEVICE_NO_RT_DETACH; 4570 } 4571 4572 LogFlow(("PDMR3DeviceDetach: returns %Vrc\n", rc)); 4573 return rc; 4574 } 4575 3152 /** @} */ 3153 -
trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
r12979 r12980 1 1 /* $Id$ */ 2 2 /** @file 3 * PDM - Pluggable Device and Driver Manager, Device parts.3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers. 4 4 */ 5 5 … … 27 27 #include "PDMInternal.h" 28 28 #include <VBox/pdm.h> 29 #include <VBox/mm.h>30 #include <VBox/pgm.h>31 #include <VBox/iom.h>32 #include <VBox/cfgm.h>33 29 #include <VBox/rem.h> 34 #include <VBox/dbgf.h>35 30 #include <VBox/vm.h> 36 31 #include <VBox/vmm.h> 37 32 38 #include <VBox/version.h>39 33 #include <VBox/log.h> 40 34 #include <VBox/err.h> 41 #include <iprt/alloc.h>42 #include <iprt/alloca.h>43 35 #include <iprt/asm.h> 44 36 #include <iprt/assert.h> 45 #include <iprt/path.h>46 #include <iprt/semaphore.h>47 #include <iprt/string.h>48 37 #include <iprt/thread.h> 49 38 50 51 /*******************************************************************************52 * Structures and Typedefs *53 *******************************************************************************/54 /**55 * Internal callback structure pointer.56 * The main purpose is to define the extra data we associate57 * with PDMDEVREGCB so we can find the VM instance and so on.58 */59 typedef struct PDMDEVREGCBINT60 {61 /** The callback structure. */62 PDMDEVREGCB Core;63 /** A bit of padding. */64 uint32_t u32[4];65 /** VM Handle. */66 PVM pVM;67 } PDMDEVREGCBINT, *PPDMDEVREGCBINT;68 typedef const PDMDEVREGCBINT *PCPDMDEVREGCBINT;69 70 71 /*******************************************************************************72 * Internal Functions *73 *******************************************************************************/74 __BEGIN_DECLS75 static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg);76 static DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb);77 static DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);78 79 /* VSlick regex:80 search : \om/\*\*.+?\*\/\nDECLCALLBACKMEMBER\(([^,]*), *pfn([^)]*)\)\(81 replace: \/\*\* @copydoc PDMDEVHLPR3::pfn\2 \*\/\nstatic DECLCALLBACK\(\1\) pdmR3DevHlp_\2\(82 */83 84 /** @name R3 DevHlp85 * @{86 */87 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc);88 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);89 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);90 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts);91 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,92 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,93 const char *pszDesc);94 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,95 const char *pszWrite, const char *pszRead, const char *pszFill,96 const char *pszDesc);97 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,98 const char *pszWrite, const char *pszRead, const char *pszFill,99 const char *pszDesc);100 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);101 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);102 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,103 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,104 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);105 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);106 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc);107 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev);108 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback);109 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,110 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld);111 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);112 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);113 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);114 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);115 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc);116 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb);117 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb);118 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv);119 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);120 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);121 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);122 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);123 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);124 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);125 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args);126 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler);127 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc);128 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...);129 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args);130 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);131 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime);132 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,133 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);134 135 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns);136 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);137 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);138 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);139 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);140 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);141 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp);142 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue);143 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);144 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);145 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);146 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);147 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);148 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);149 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns);150 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);151 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable);152 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns);153 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns);154 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns);155 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns);156 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns);157 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);158 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);159 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);160 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);161 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);162 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);163 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns);164 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);165 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);166 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,167 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);168 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);169 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);170 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);171 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);172 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);173 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);174 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);175 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);176 177 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns);178 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);179 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);180 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);181 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);182 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);183 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);184 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);185 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);186 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);187 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);188 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC);189 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr);190 191 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns);192 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable);193 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns);194 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns);195 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns);196 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns);197 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns);198 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);199 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);200 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);201 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);202 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);203 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);204 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns);205 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);206 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);207 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,208 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);209 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);210 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);211 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);212 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);213 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);214 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);215 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);216 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);217 /** @} */218 39 219 40 … … 221 42 * @{ 222 43 */ 223 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns); 224 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns); 225 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc); 226 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns); 227 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns); 228 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns); 229 /** @} */ 230 231 232 /** @name HC APIC Helpers 233 * @{ 234 */ 235 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu); 236 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu); 237 static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion); 238 static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc); 239 static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns); 240 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns); 241 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns); 242 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns); 243 /** @} */ 244 245 246 /** @name HC I/O APIC Helpers 247 * @{ 248 */ 249 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 250 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode); 251 static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc); 252 static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns); 253 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns); 254 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns); 255 /** @} */ 256 257 258 /** @name HC PCI Bus Helpers 259 * @{ 260 */ 261 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel); 262 static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel); 263 static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys); 264 static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc); 265 static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns); 266 static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns); 267 static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns); 268 /** @} */ 269 270 /** @def PDMDEV_ASSERT_DEVINS 271 * Asserts the validity of the device instance. 272 */ 273 #ifdef VBOX_STRICT 274 # define PDMDEV_ASSERT_DEVINS(pDevIns) \ 275 do { \ 276 AssertPtr(pDevIns); \ 277 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \ 278 Assert(pDevIns->pvInstanceDataR3 == (void *)&pDevIns->achInstanceData[0]); \ 279 } while (0) 280 #else 281 # define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0) 282 #endif 283 284 static int pdmR3DevLoadModules(PVM pVM); 285 static int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName); 286 287 288 /* 289 * Allow physical read and writes from any thread 290 */ 291 #define PDM_PHYS_READWRITE_FROM_ANY_THREAD 292 293 __END_DECLS 294 295 /******************************************************************************* 296 * Global Variables * 297 *******************************************************************************/ 298 /** 299 * The device helper structure for trusted devices. 300 */ 301 const PDMDEVHLPR3 g_pdmR3DevHlpTrusted = 302 { 303 PDM_DEVHLP_VERSION, 304 pdmR3DevHlp_IOPortRegister, 305 pdmR3DevHlp_IOPortRegisterGC, 306 pdmR3DevHlp_IOPortRegisterR0, 307 pdmR3DevHlp_IOPortDeregister, 308 pdmR3DevHlp_MMIORegister, 309 pdmR3DevHlp_MMIORegisterGC, 310 pdmR3DevHlp_MMIORegisterR0, 311 pdmR3DevHlp_MMIODeregister, 312 pdmR3DevHlp_ROMRegister, 313 pdmR3DevHlp_SSMRegister, 314 pdmR3DevHlp_TMTimerCreate, 315 pdmR3DevHlp_TMTimerCreateExternal, 316 pdmR3DevHlp_PCIRegister, 317 pdmR3DevHlp_PCIIORegionRegister, 318 pdmR3DevHlp_PCISetConfigCallbacks, 319 pdmR3DevHlp_PCISetIrq, 320 pdmR3DevHlp_PCISetIrqNoWait, 321 pdmR3DevHlp_ISASetIrq, 322 pdmR3DevHlp_ISASetIrqNoWait, 323 pdmR3DevHlp_DriverAttach, 324 pdmR3DevHlp_MMHeapAlloc, 325 pdmR3DevHlp_MMHeapAllocZ, 326 pdmR3DevHlp_MMHeapFree, 327 pdmR3DevHlp_VMSetError, 328 pdmR3DevHlp_VMSetErrorV, 329 pdmR3DevHlp_VMSetRuntimeError, 330 pdmR3DevHlp_VMSetRuntimeErrorV, 331 pdmR3DevHlp_AssertEMT, 332 pdmR3DevHlp_AssertOther, 333 pdmR3DevHlp_DBGFStopV, 334 pdmR3DevHlp_DBGFInfoRegister, 335 pdmR3DevHlp_STAMRegister, 336 pdmR3DevHlp_STAMRegisterF, 337 pdmR3DevHlp_STAMRegisterV, 338 pdmR3DevHlp_RTCRegister, 339 pdmR3DevHlp_PDMQueueCreate, 340 pdmR3DevHlp_CritSectInit, 341 pdmR3DevHlp_UTCNow, 342 pdmR3DevHlp_PDMThreadCreate, 343 pdmR3DevHlp_PhysGCPtr2GCPhys, 344 pdmR3DevHlp_VMState, 345 0, 346 0, 347 0, 348 0, 349 0, 350 0, 351 0, 352 pdmR3DevHlp_GetVM, 353 pdmR3DevHlp_PCIBusRegister, 354 pdmR3DevHlp_PICRegister, 355 pdmR3DevHlp_APICRegister, 356 pdmR3DevHlp_IOAPICRegister, 357 pdmR3DevHlp_DMACRegister, 358 pdmR3DevHlp_PhysRead, 359 pdmR3DevHlp_PhysWrite, 360 pdmR3DevHlp_PhysReadGCVirt, 361 pdmR3DevHlp_PhysWriteGCVirt, 362 pdmR3DevHlp_PhysReserve, 363 pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt, 364 pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr, 365 pdmR3DevHlp_A20IsEnabled, 366 pdmR3DevHlp_A20Set, 367 pdmR3DevHlp_VMReset, 368 pdmR3DevHlp_VMSuspend, 369 pdmR3DevHlp_VMPowerOff, 370 pdmR3DevHlp_LockVM, 371 pdmR3DevHlp_UnlockVM, 372 pdmR3DevHlp_AssertVMLock, 373 pdmR3DevHlp_DMARegister, 374 pdmR3DevHlp_DMAReadMemory, 375 pdmR3DevHlp_DMAWriteMemory, 376 pdmR3DevHlp_DMASetDREQ, 377 pdmR3DevHlp_DMAGetChannelMode, 378 pdmR3DevHlp_DMASchedule, 379 pdmR3DevHlp_CMOSWrite, 380 pdmR3DevHlp_CMOSRead, 381 pdmR3DevHlp_GetCpuId, 382 pdmR3DevHlp_ROMProtectShadow, 383 pdmR3DevHlp_MMIO2Register, 384 pdmR3DevHlp_MMIO2Deregister, 385 pdmR3DevHlp_MMIO2Map, 386 pdmR3DevHlp_MMIO2Unmap, 387 pdmR3DevHlp_MMHyperMapMMIO2, 388 pdmR3DevHlp_RegisterVMMDevHeap, 389 pdmR3DevHlp_UnregisterVMMDevHeap, 390 PDM_DEVHLP_VERSION /* the end */ 391 }; 392 393 394 /** 395 * The device helper structure for non-trusted devices. 396 */ 397 const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted = 398 { 399 PDM_DEVHLP_VERSION, 400 pdmR3DevHlp_IOPortRegister, 401 pdmR3DevHlp_IOPortRegisterGC, 402 pdmR3DevHlp_IOPortRegisterR0, 403 pdmR3DevHlp_IOPortDeregister, 404 pdmR3DevHlp_MMIORegister, 405 pdmR3DevHlp_MMIORegisterGC, 406 pdmR3DevHlp_MMIORegisterR0, 407 pdmR3DevHlp_MMIODeregister, 408 pdmR3DevHlp_ROMRegister, 409 pdmR3DevHlp_SSMRegister, 410 pdmR3DevHlp_TMTimerCreate, 411 pdmR3DevHlp_TMTimerCreateExternal, 412 pdmR3DevHlp_PCIRegister, 413 pdmR3DevHlp_PCIIORegionRegister, 414 pdmR3DevHlp_PCISetConfigCallbacks, 415 pdmR3DevHlp_PCISetIrq, 416 pdmR3DevHlp_PCISetIrqNoWait, 417 pdmR3DevHlp_ISASetIrq, 418 pdmR3DevHlp_ISASetIrqNoWait, 419 pdmR3DevHlp_DriverAttach, 420 pdmR3DevHlp_MMHeapAlloc, 421 pdmR3DevHlp_MMHeapAllocZ, 422 pdmR3DevHlp_MMHeapFree, 423 pdmR3DevHlp_VMSetError, 424 pdmR3DevHlp_VMSetErrorV, 425 pdmR3DevHlp_VMSetRuntimeError, 426 pdmR3DevHlp_VMSetRuntimeErrorV, 427 pdmR3DevHlp_AssertEMT, 428 pdmR3DevHlp_AssertOther, 429 pdmR3DevHlp_DBGFStopV, 430 pdmR3DevHlp_DBGFInfoRegister, 431 pdmR3DevHlp_STAMRegister, 432 pdmR3DevHlp_STAMRegisterF, 433 pdmR3DevHlp_STAMRegisterV, 434 pdmR3DevHlp_RTCRegister, 435 pdmR3DevHlp_PDMQueueCreate, 436 pdmR3DevHlp_CritSectInit, 437 pdmR3DevHlp_UTCNow, 438 pdmR3DevHlp_PDMThreadCreate, 439 pdmR3DevHlp_PhysGCPtr2GCPhys, 440 pdmR3DevHlp_VMState, 441 0, 442 0, 443 0, 444 0, 445 0, 446 0, 447 0, 448 pdmR3DevHlp_Untrusted_GetVM, 449 pdmR3DevHlp_Untrusted_PCIBusRegister, 450 pdmR3DevHlp_Untrusted_PICRegister, 451 pdmR3DevHlp_Untrusted_APICRegister, 452 pdmR3DevHlp_Untrusted_IOAPICRegister, 453 pdmR3DevHlp_Untrusted_DMACRegister, 454 pdmR3DevHlp_Untrusted_PhysRead, 455 pdmR3DevHlp_Untrusted_PhysWrite, 456 pdmR3DevHlp_Untrusted_PhysReadGCVirt, 457 pdmR3DevHlp_Untrusted_PhysWriteGCVirt, 458 pdmR3DevHlp_Untrusted_PhysReserve, 459 pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt, 460 pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr, 461 pdmR3DevHlp_Untrusted_A20IsEnabled, 462 pdmR3DevHlp_Untrusted_A20Set, 463 pdmR3DevHlp_Untrusted_VMReset, 464 pdmR3DevHlp_Untrusted_VMSuspend, 465 pdmR3DevHlp_Untrusted_VMPowerOff, 466 pdmR3DevHlp_Untrusted_LockVM, 467 pdmR3DevHlp_Untrusted_UnlockVM, 468 pdmR3DevHlp_Untrusted_AssertVMLock, 469 pdmR3DevHlp_Untrusted_DMARegister, 470 pdmR3DevHlp_Untrusted_DMAReadMemory, 471 pdmR3DevHlp_Untrusted_DMAWriteMemory, 472 pdmR3DevHlp_Untrusted_DMASetDREQ, 473 pdmR3DevHlp_Untrusted_DMAGetChannelMode, 474 pdmR3DevHlp_Untrusted_DMASchedule, 475 pdmR3DevHlp_Untrusted_CMOSWrite, 476 pdmR3DevHlp_Untrusted_CMOSRead, 477 pdmR3DevHlp_Untrusted_GetCpuId, 478 pdmR3DevHlp_Untrusted_ROMProtectShadow, 479 pdmR3DevHlp_Untrusted_MMIO2Register, 480 pdmR3DevHlp_Untrusted_MMIO2Deregister, 481 pdmR3DevHlp_Untrusted_MMIO2Map, 482 pdmR3DevHlp_Untrusted_MMIO2Unmap, 483 pdmR3DevHlp_Untrusted_MMHyperMapMMIO2, 484 pdmR3DevHlp_Untrusted_RegisterVMMDevHeap, 485 pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap, 486 PDM_DEVHLP_VERSION /* the end */ 487 }; 44 45 /** @copydoc PDMPICHLPR3::pfnSetInterruptFF */ 46 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns) 47 { 48 PDMDEV_ASSERT_DEVINS(pDevIns); 49 PVM pVM = pDevIns->Internal.s.pVMR3; 50 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n", 51 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, 0, VM_FF_INTERRUPT_PIC))); 52 /* for PIC we always deliver to CPU 0, MP use APIC */ 53 VMCPU_FF_SET(pVM, 0, VM_FF_INTERRUPT_PIC); 54 REMR3NotifyInterruptSet(pVM); 55 VMR3NotifyFF(pVM, true); 56 } 57 58 59 /** @copydoc PDMPICHLPR3::pfnClearInterruptFF */ 60 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns) 61 { 62 PDMDEV_ASSERT_DEVINS(pDevIns); 63 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n", 64 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC))); 65 /* for PIC we always deliver to CPU 0, MP use APIC */ 66 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC); 67 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3); 68 } 69 70 71 /** @copydoc PDMPICHLPR3::pfnLock */ 72 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc) 73 { 74 PDMDEV_ASSERT_DEVINS(pDevIns); 75 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 76 } 77 78 79 /** @copydoc PDMPICHLPR3::pfnUnlock */ 80 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns) 81 { 82 PDMDEV_ASSERT_DEVINS(pDevIns); 83 pdmUnlock(pDevIns->Internal.s.pVMR3); 84 } 85 86 87 /** @copydoc PDMPICHLPR3::pfnGetRCHelpers */ 88 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns) 89 { 90 PDMDEV_ASSERT_DEVINS(pDevIns); 91 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 92 RTRCPTR pRCHelpers = 0; 93 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers); 94 AssertReleaseRC(rc); 95 AssertRelease(pRCHelpers); 96 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n", 97 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 98 return pRCHelpers; 99 } 100 101 102 /** @copydoc PDMPICHLPR3::pfnGetR0Helpers */ 103 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns) 104 { 105 PDMDEV_ASSERT_DEVINS(pDevIns); 106 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 107 PCPDMPICHLPR0 pR0Helpers = 0; 108 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers); 109 AssertReleaseRC(rc); 110 AssertRelease(pR0Helpers); 111 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 112 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 113 return pR0Helpers; 114 } 488 115 489 116 … … 503 130 }; 504 131 505 506 /** 507 * APIC Device Helpers. 508 */ 509 const PDMAPICHLPR3 g_pdmR3DevApicHlp = 510 { 511 PDM_APICHLPR3_VERSION, 512 pdmR3ApicHlp_SetInterruptFF, 513 pdmR3ApicHlp_ClearInterruptFF, 514 pdmR3ApicHlp_ChangeFeature, 515 pdmR3ApicHlp_Lock, 516 pdmR3ApicHlp_Unlock, 517 pdmR3ApicHlp_GetCpuId, 518 pdmR3ApicHlp_GetRCHelpers, 519 pdmR3ApicHlp_GetR0Helpers, 520 PDM_APICHLPR3_VERSION /* the end */ 521 }; 522 523 524 /** 525 * I/O APIC Device Helpers. 526 */ 527 const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp = 528 { 529 PDM_IOAPICHLPR3_VERSION, 530 pdmR3IoApicHlp_ApicBusDeliver, 531 pdmR3IoApicHlp_Lock, 532 pdmR3IoApicHlp_Unlock, 533 pdmR3IoApicHlp_GetRCHelpers, 534 pdmR3IoApicHlp_GetR0Helpers, 535 PDM_IOAPICHLPR3_VERSION /* the end */ 536 }; 537 538 539 /** 540 * PCI Bus Device Helpers. 541 */ 542 const PDMPCIHLPR3 g_pdmR3DevPciHlp = 543 { 544 PDM_PCIHLPR3_VERSION, 545 pdmR3PciHlp_IsaSetIrq, 546 pdmR3PciHlp_IoApicSetIrq, 547 pdmR3PciHlp_IsMMIO2Base, 548 pdmR3PciHlp_GetRCHelpers, 549 pdmR3PciHlp_GetR0Helpers, 550 pdmR3PciHlp_Lock, 551 pdmR3PciHlp_Unlock, 552 PDM_PCIHLPR3_VERSION, /* the end */ 553 }; 554 555 556 /** 557 * DMAC Device Helpers. 558 */ 559 const PDMDMACHLP g_pdmR3DevDmacHlp = 560 { 561 PDM_DMACHLP_VERSION 562 }; 563 564 565 /** 566 * RTC Device Helpers. 567 */ 568 const PDMRTCHLP g_pdmR3DevRtcHlp = 569 { 570 PDM_RTCHLP_VERSION 571 }; 572 573 574 575 /** 576 * This function will initialize the devices for this VM instance. 577 * 578 * 579 * First of all this mean loading the builtin device and letting them 580 * register themselves. Beyond that any additional device modules are 581 * loaded and called for registration. 582 * 583 * Then the device configuration is enumerated, the instantiation order 584 * is determined, and finally they are instantiated. 585 * 586 * After all device have been successfully instantiated the the primary 587 * PCI Bus device is called to emulate the PCI BIOS, i.e. making the 588 * resource assignments. If there is no PCI device, this step is of course 589 * skipped. 590 * 591 * Finally the init completion routines of the instantiated devices 592 * are called. 593 * 594 * @returns VBox status code. 595 * @param pVM VM Handle. 596 */ 597 int pdmR3DevInit(PVM pVM) 598 { 599 LogFlow(("pdmR3DevInit:\n")); 600 601 AssertRelease(!(RT_OFFSETOF(PDMDEVINS, achInstanceData) & 15)); 602 AssertRelease(sizeof(pVM->pdm.s.pDevInstances->Internal.s) <= sizeof(pVM->pdm.s.pDevInstances->Internal.padding)); 603 604 /* 605 * Load device modules. 606 */ 607 int rc = pdmR3DevLoadModules(pVM); 608 if (RT_FAILURE(rc)) 609 return rc; 610 611 #ifdef VBOX_WITH_USB 612 /* ditto for USB Devices. */ 613 rc = pdmR3UsbLoadModules(pVM); 614 if (RT_FAILURE(rc)) 615 return rc; 616 #endif 617 618 /* 619 * Get the RC & R0 devhlps and create the devhlp R3 task queue. 620 */ 621 PCPDMDEVHLPRC pDevHlpRC; 622 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCDevHlp", &pDevHlpRC); 623 AssertReleaseRCReturn(rc, rc); 624 625 PCPDMDEVHLPR0 pDevHlpR0; 626 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0DevHlp", &pDevHlpR0); 627 AssertReleaseRCReturn(rc, rc); 628 629 rc = PDMR3QueueCreateInternal(pVM, sizeof(PDMDEVHLPTASK), 8, 0, pdmR3DevHlpQueueConsumer, true, &pVM->pdm.s.pDevHlpQueueHC); 630 AssertRCReturn(rc, rc); 631 pVM->pdm.s.pDevHlpQueueGC = PDMQueueGCPtr(pVM->pdm.s.pDevHlpQueueHC); 632 633 634 /* 635 * 636 * Enumerate the device instance configurations 637 * and come up with a instantiation order. 638 * 639 */ 640 /* Switch to /Devices, which contains the device instantiations. */ 641 PCFGMNODE pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices"); 642 643 /* 644 * Count the device instances. 645 */ 646 PCFGMNODE pCur; 647 PCFGMNODE pInstanceNode; 648 unsigned cDevs = 0; 649 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur)) 650 for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode)) 651 cDevs++; 652 if (!cDevs) 653 { 654 Log(("PDM: No devices were configured!\n")); 655 return VINF_SUCCESS; 656 } 657 Log2(("PDM: cDevs=%d!\n", cDevs)); 658 659 /* 660 * Collect info on each device instance. 661 */ 662 struct DEVORDER 663 { 664 /** Configuration node. */ 665 PCFGMNODE pNode; 666 /** Pointer to device. */ 667 PPDMDEV pDev; 668 /** Init order. */ 669 uint32_t u32Order; 670 /** VBox instance number. */ 671 uint32_t iInstance; 672 } *paDevs = (struct DEVORDER *)alloca(sizeof(paDevs[0]) * (cDevs + 1)); /* (One extra for swapping) */ 673 Assert(paDevs); 674 unsigned i = 0; 675 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur)) 676 { 677 /* Get the device name. */ 678 char szName[sizeof(paDevs[0].pDev->pDevReg->szDeviceName)]; 679 rc = CFGMR3GetName(pCur, szName, sizeof(szName)); 680 AssertMsgRCReturn(rc, ("Configuration error: device name is too long (or something)! rc=%Vrc\n", rc), rc); 681 682 /* Find the device. */ 683 PPDMDEV pDev = pdmR3DevLookup(pVM, szName); 684 AssertMsgReturn(pDev, ("Configuration error: device '%s' not found!\n", szName), VERR_PDM_DEVICE_NOT_FOUND); 685 686 /* Configured priority or use default based on device class? */ 687 uint32_t u32Order; 688 rc = CFGMR3QueryU32(pCur, "Priority", &u32Order); 689 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 690 { 691 uint32_t u32 = pDev->pDevReg->fClass; 692 for (u32Order = 1; !(u32 & u32Order); u32Order <<= 1) 693 /* nop */; 694 } 695 else 696 AssertMsgRCReturn(rc, ("Configuration error: reading \"Priority\" for the '%s' device failed rc=%Vrc!\n", szName, rc), rc); 697 698 /* Enumerate the device instances. */ 699 for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode)) 700 { 701 paDevs[i].pNode = pInstanceNode; 702 paDevs[i].pDev = pDev; 703 paDevs[i].u32Order = u32Order; 704 705 /* Get the instance number. */ 706 char szInstance[32]; 707 rc = CFGMR3GetName(pInstanceNode, szInstance, sizeof(szInstance)); 708 AssertMsgRCReturn(rc, ("Configuration error: instance name is too long (or something)! rc=%Vrc\n", rc), rc); 709 char *pszNext = NULL; 710 rc = RTStrToUInt32Ex(szInstance, &pszNext, 0, &paDevs[i].iInstance); 711 AssertMsgRCReturn(rc, ("Configuration error: RTStrToInt32Ex failed on the instance name '%s'! rc=%Vrc\n", szInstance, rc), rc); 712 AssertMsgReturn(!*pszNext, ("Configuration error: the instance name '%s' isn't all digits. (%s)\n", szInstance, pszNext), VERR_INVALID_PARAMETER); 713 714 /* next instance */ 715 i++; 716 } 717 } /* devices */ 718 Assert(i == cDevs); 719 720 /* 721 * Sort the device array ascending on u32Order. (bubble) 722 */ 723 unsigned c = cDevs - 1; 724 while (c) 725 { 726 unsigned j = 0; 727 for (i = 0; i < c; i++) 728 if (paDevs[i].u32Order > paDevs[i + 1].u32Order) 729 { 730 paDevs[cDevs] = paDevs[i + 1]; 731 paDevs[i + 1] = paDevs[i]; 732 paDevs[i] = paDevs[cDevs]; 733 j = i; 734 } 735 c = j; 736 } 737 738 739 /* 740 * 741 * Instantiate the devices. 742 * 743 */ 744 for (i = 0; i < cDevs; i++) 745 { 746 /* 747 * Gather a bit of config. 748 */ 749 /* trusted */ 750 bool fTrusted; 751 rc = CFGMR3QueryBool(paDevs[i].pNode, "Trusted", &fTrusted); 752 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 753 fTrusted = false; 754 else if (VBOX_FAILURE(rc)) 755 { 756 AssertMsgFailed(("configuration error: failed to query boolean \"Trusted\", rc=%Vrc\n", rc)); 757 return rc; 758 } 759 /* config node */ 760 PCFGMNODE pConfigNode = CFGMR3GetChild(paDevs[i].pNode, "Config"); 761 if (!pConfigNode) 762 { 763 rc = CFGMR3InsertNode(paDevs[i].pNode, "Config", &pConfigNode); 764 if (VBOX_FAILURE(rc)) 765 { 766 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc)); 767 return rc; 768 } 769 } 770 CFGMR3SetRestrictedRoot(pConfigNode); 771 772 /* 773 * Allocate the device instance. 774 */ 775 size_t cb = RT_OFFSETOF(PDMDEVINS, achInstanceData[paDevs[i].pDev->pDevReg->cbInstance]); 776 cb = RT_ALIGN_Z(cb, 16); 777 PPDMDEVINS pDevIns; 778 if (paDevs[i].pDev->pDevReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0)) 779 rc = MMR3HyperAllocOnceNoRel(pVM, cb, 0, MM_TAG_PDM_DEVICE, (void **)&pDevIns); 780 else 781 rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns); 782 if (VBOX_FAILURE(rc)) 783 { 784 AssertMsgFailed(("Failed to allocate %d bytes of instance data for device '%s'. rc=%Vrc\n", 785 cb, paDevs[i].pDev->pDevReg->szDeviceName, rc)); 786 return rc; 787 } 788 789 /* 790 * Initialize it. 791 */ 792 pDevIns->u32Version = PDM_DEVINS_VERSION; 793 //pDevIns->Internal.s.pNextR3 = NULL; 794 //pDevIns->Internal.s.pPerDeviceNextR3 = NULL; 795 pDevIns->Internal.s.pDevR3 = paDevs[i].pDev; 796 pDevIns->Internal.s.pVMR3 = pVM; 797 pDevIns->Internal.s.pVMR0 = pVM->pVMR0; 798 pDevIns->Internal.s.pVMRC = pVM->pVMRC; 799 //pDevIns->Internal.s.pLunsR3 = NULL; 800 pDevIns->Internal.s.pCfgHandle = paDevs[i].pNode; 801 //pDevIns->Internal.s.pPciDeviceR3 = NULL; 802 //pDevIns->Internal.s.pPciBusR3 = NULL; /** @todo pci bus selection. (in 2008 perhaps) */ 803 //pDevIns->Internal.s.pPciDeviceR0 = 0; 804 //pDevIns->Internal.s.pPciBusR0 = 0; 805 //pDevIns->Internal.s.pPciDeviceRC = 0; 806 //pDevIns->Internal.s.pPciBusRC = 0; 807 pDevIns->pDevHlpR3 = fTrusted ? &g_pdmR3DevHlpTrusted : &g_pdmR3DevHlpUnTrusted; 808 pDevIns->pDevHlpRC = pDevHlpRC; 809 pDevIns->pDevHlpR0 = pDevHlpR0; 810 pDevIns->pDevReg = paDevs[i].pDev->pDevReg; 811 pDevIns->pCfgHandle = pConfigNode; 812 pDevIns->iInstance = paDevs[i].iInstance; 813 pDevIns->pvInstanceDataR3 = &pDevIns->achInstanceData[0]; 814 pDevIns->pvInstanceDataRC = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC 815 ? MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3) : NIL_RTRCPTR; 816 pDevIns->pvInstanceDataR0 = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0 817 ? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : NIL_RTR0PTR; 818 819 /* 820 * Link it into all the lists. 821 */ 822 /* The global instance FIFO. */ 823 PPDMDEVINS pPrev1 = pVM->pdm.s.pDevInstances; 824 if (!pPrev1) 825 pVM->pdm.s.pDevInstances = pDevIns; 826 else 827 { 828 while (pPrev1->Internal.s.pNextR3) 829 pPrev1 = pPrev1->Internal.s.pNextR3; 830 pPrev1->Internal.s.pNextR3 = pDevIns; 831 } 832 833 /* The per device instance FIFO. */ 834 PPDMDEVINS pPrev2 = paDevs[i].pDev->pInstances; 835 if (!pPrev2) 836 paDevs[i].pDev->pInstances = pDevIns; 837 else 838 { 839 while (pPrev2->Internal.s.pPerDeviceNextR3) 840 pPrev2 = pPrev2->Internal.s.pPerDeviceNextR3; 841 pPrev2->Internal.s.pPerDeviceNextR3 = pDevIns; 842 } 843 844 /* 845 * Call the constructor. 846 */ 847 Log(("PDM: Constructing device '%s' instance %d...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 848 rc = pDevIns->pDevReg->pfnConstruct(pDevIns, pDevIns->iInstance, pDevIns->pCfgHandle); 849 if (VBOX_FAILURE(rc)) 850 { 851 LogRel(("PDM: Failed to construct '%s'/%d! %Vra\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 852 /* because we're damn lazy right now, we'll say that the destructor will be called even if the constructor fails. */ 853 return rc; 854 } 855 } /* for device instances */ 856 857 #ifdef VBOX_WITH_USB 858 /* ditto for USB Devices. */ 859 rc = pdmR3UsbInstantiateDevices(pVM); 860 if (RT_FAILURE(rc)) 861 return rc; 862 #endif 863 864 865 /* 866 * 867 * PCI BIOS Fake and Init Complete. 868 * 869 */ 870 if (pVM->pdm.s.aPciBuses[0].pDevInsR3) 871 { 872 pdmLock(pVM); 873 rc = pVM->pdm.s.aPciBuses[0].pfnFakePCIBIOSR3(pVM->pdm.s.aPciBuses[0].pDevInsR3); 874 pdmUnlock(pVM); 875 if (VBOX_FAILURE(rc)) 876 { 877 AssertMsgFailed(("PCI BIOS fake failed rc=%Vrc\n", rc)); 878 return rc; 879 } 880 } 881 882 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 883 { 884 if (pDevIns->pDevReg->pfnInitComplete) 885 { 886 rc = pDevIns->pDevReg->pfnInitComplete(pDevIns); 887 if (VBOX_FAILURE(rc)) 888 { 889 AssertMsgFailed(("InitComplete on device '%s'/%d failed with rc=%Vrc\n", 890 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 891 return rc; 892 } 893 } 894 } 895 896 #ifdef VBOX_WITH_USB 897 /* ditto for USB Devices. */ 898 rc = pdmR3UsbVMInitComplete(pVM); 899 if (RT_FAILURE(rc)) 900 return rc; 901 #endif 902 903 LogFlow(("pdmR3DevInit: returns %Vrc\n", VINF_SUCCESS)); 904 return VINF_SUCCESS; 905 } 906 907 908 /** 909 * Lookups a device structure by name. 910 * @internal 911 */ 912 PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName) 913 { 914 RTUINT cchName = strlen(pszName); 915 for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext) 916 if ( pDev->cchName == cchName 917 && !strcmp(pDev->pDevReg->szDeviceName, pszName)) 918 return pDev; 919 return NULL; 920 } 921 922 923 /** 924 * Loads the device modules. 925 * 926 * @returns VBox status code. 927 * @param pVM Pointer to the shared VM structure. 928 */ 929 static int pdmR3DevLoadModules(PVM pVM) 930 { 931 /* 932 * Initialize the callback structure. 933 */ 934 PDMDEVREGCBINT RegCB; 935 RegCB.Core.u32Version = PDM_DEVREG_CB_VERSION; 936 RegCB.Core.pfnRegister = pdmR3DevReg_Register; 937 RegCB.Core.pfnMMHeapAlloc = pdmR3DevReg_MMHeapAlloc; 938 RegCB.pVM = pVM; 939 940 /* 941 * Load the builtin module 942 */ 943 PCFGMNODE pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/Devices"); 944 bool fLoadBuiltin; 945 int rc = CFGMR3QueryBool(pDevicesNode, "LoadBuiltin", &fLoadBuiltin); 946 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT) 947 fLoadBuiltin = true; 948 else if (VBOX_FAILURE(rc)) 949 { 950 AssertMsgFailed(("Configuration error: Querying boolean \"LoadBuiltin\" failed with %Vrc\n", rc)); 951 return rc; 952 } 953 if (fLoadBuiltin) 954 { 955 /* make filename */ 956 char *pszFilename = pdmR3FileR3("VBoxDD", /* fShared = */ true); 957 if (!pszFilename) 958 return VERR_NO_TMP_MEMORY; 959 rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD"); 960 RTMemTmpFree(pszFilename); 961 if (VBOX_FAILURE(rc)) 962 return rc; 963 964 /* make filename */ 965 pszFilename = pdmR3FileR3("VBoxDD2", /* fShared = */ true); 966 if (!pszFilename) 967 return VERR_NO_TMP_MEMORY; 968 rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD2"); 969 RTMemTmpFree(pszFilename); 970 if (VBOX_FAILURE(rc)) 971 return rc; 972 } 973 974 /* 975 * Load additional device modules. 976 */ 977 PCFGMNODE pCur; 978 for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur)) 979 { 980 /* 981 * Get the name and path. 982 */ 983 char szName[PDMMOD_NAME_LEN]; 984 rc = CFGMR3GetName(pCur, &szName[0], sizeof(szName)); 985 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE) 986 { 987 AssertMsgFailed(("configuration error: The module name is too long, cchName=%d.\n", CFGMR3GetNameLen(pCur))); 988 return VERR_PDM_MODULE_NAME_TOO_LONG; 989 } 990 else if (VBOX_FAILURE(rc)) 991 { 992 AssertMsgFailed(("CFGMR3GetName -> %Vrc.\n", rc)); 993 return rc; 994 } 995 996 /* the path is optional, if no path the module name + path is used. */ 997 char szFilename[RTPATH_MAX]; 998 rc = CFGMR3QueryString(pCur, "Path", &szFilename[0], sizeof(szFilename)); 999 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 1000 strcpy(szFilename, szName); 1001 else if (VBOX_FAILURE(rc)) 1002 { 1003 AssertMsgFailed(("configuration error: Failure to query the module path, rc=%Vrc.\n", rc)); 1004 return rc; 1005 } 1006 1007 /* prepend path? */ 1008 if (!RTPathHavePath(szFilename)) 1009 { 1010 char *psz = pdmR3FileR3(szFilename); 1011 if (!psz) 1012 return VERR_NO_TMP_MEMORY; 1013 size_t cch = strlen(psz) + 1; 1014 if (cch > sizeof(szFilename)) 1015 { 1016 RTMemTmpFree(psz); 1017 AssertMsgFailed(("Filename too long! cch=%d '%s'\n", cch, psz)); 1018 return VERR_FILENAME_TOO_LONG; 1019 } 1020 memcpy(szFilename, psz, cch); 1021 RTMemTmpFree(psz); 1022 } 1023 1024 /* 1025 * Load the module and register it's devices. 1026 */ 1027 rc = pdmR3DevLoad(pVM, &RegCB, szFilename, szName); 1028 if (VBOX_FAILURE(rc)) 1029 return rc; 1030 } 1031 1032 return VINF_SUCCESS; 1033 } 1034 1035 1036 /** 1037 * Loads one device module and call the registration entry point. 1038 * 1039 * @returns VBox status code. 1040 * @param pVM VM handle. 1041 * @param pRegCB The registration callback stuff. 1042 * @param pszFilename Module filename. 1043 * @param pszName Module name. 1044 */ 1045 static int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName) 1046 { 1047 /* 1048 * Load it. 1049 */ 1050 int rc = pdmR3LoadR3U(pVM->pUVM, pszFilename, pszName); 1051 if (VBOX_SUCCESS(rc)) 1052 { 1053 /* 1054 * Get the registration export and call it. 1055 */ 1056 FNPDMVBOXDEVICESREGISTER *pfnVBoxDevicesRegister; 1057 rc = PDMR3LdrGetSymbolR3(pVM, pszName, "VBoxDevicesRegister", (void **)&pfnVBoxDevicesRegister); 1058 if (VBOX_SUCCESS(rc)) 1059 { 1060 Log(("PDM: Calling VBoxDevicesRegister (%p) of %s (%s)\n", pfnVBoxDevicesRegister, pszName, pszFilename)); 1061 rc = pfnVBoxDevicesRegister(&pRegCB->Core, VBOX_VERSION); 1062 if (VBOX_SUCCESS(rc)) 1063 Log(("PDM: Successfully loaded device module %s (%s).\n", pszName, pszFilename)); 1064 else 1065 AssertMsgFailed(("VBoxDevicesRegister failed with rc=%Vrc for module %s (%s)\n", rc, pszName, pszFilename)); 1066 } 1067 else 1068 { 1069 AssertMsgFailed(("Failed to locate 'VBoxDevicesRegister' in %s (%s) rc=%Vrc\n", pszName, pszFilename, rc)); 1070 if (rc == VERR_SYMBOL_NOT_FOUND) 1071 rc = VERR_PDM_NO_REGISTRATION_EXPORT; 1072 } 1073 } 1074 else 1075 AssertMsgFailed(("Failed to load %s %s!\n", pszFilename, pszName)); 1076 return rc; 1077 } 1078 1079 1080 1081 /** 1082 * Registers a device with the current VM instance. 1083 * 1084 * @returns VBox status code. 1085 * @param pCallbacks Pointer to the callback table. 1086 * @param pDevReg Pointer to the device registration record. 1087 * This data must be permanent and readonly. 1088 */ 1089 static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg) 1090 { 1091 /* 1092 * Validate the registration structure. 1093 */ 1094 Assert(pDevReg); 1095 if (pDevReg->u32Version != PDM_DEVREG_VERSION) 1096 { 1097 AssertMsgFailed(("Unknown struct version %#x!\n", pDevReg->u32Version)); 1098 return VERR_PDM_UNKNOWN_DEVREG_VERSION; 1099 } 1100 if ( !pDevReg->szDeviceName[0] 1101 || strlen(pDevReg->szDeviceName) >= sizeof(pDevReg->szDeviceName)) 1102 { 1103 AssertMsgFailed(("Invalid name '%s'\n", pDevReg->szDeviceName)); 1104 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1105 } 1106 if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1107 && ( !pDevReg->szRCMod[0] 1108 || strlen(pDevReg->szRCMod) >= sizeof(pDevReg->szRCMod))) 1109 { 1110 AssertMsgFailed(("Invalid GC module name '%s' - (Device %s)\n", pDevReg->szRCMod, pDevReg->szDeviceName)); 1111 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1112 } 1113 if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_R0) 1114 && ( !pDevReg->szR0Mod[0] 1115 || strlen(pDevReg->szR0Mod) >= sizeof(pDevReg->szR0Mod))) 1116 { 1117 AssertMsgFailed(("Invalid R0 module name '%s' - (Device %s)\n", pDevReg->szR0Mod, pDevReg->szDeviceName)); 1118 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1119 } 1120 if ((pDevReg->fFlags & PDM_DEVREG_FLAGS_HOST_BITS_MASK) != PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT) 1121 { 1122 AssertMsgFailed(("Invalid host bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName)); 1123 return VERR_PDM_INVALID_DEVICE_HOST_BITS; 1124 } 1125 if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_MASK)) 1126 { 1127 AssertMsgFailed(("Invalid guest bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName)); 1128 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1129 } 1130 if (!pDevReg->fClass) 1131 { 1132 AssertMsgFailed(("No class! (Device %s)\n", pDevReg->szDeviceName)); 1133 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1134 } 1135 if (pDevReg->cMaxInstances <= 0) 1136 { 1137 AssertMsgFailed(("Max instances %u! (Device %s)\n", pDevReg->cMaxInstances, pDevReg->szDeviceName)); 1138 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1139 } 1140 if (pDevReg->cbInstance > (RTUINT)(pDevReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0) ? 96 * _1K : _1M)) 1141 { 1142 AssertMsgFailed(("Instance size %d bytes! (Device %s)\n", pDevReg->cbInstance, pDevReg->szDeviceName)); 1143 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1144 } 1145 if (!pDevReg->pfnConstruct) 1146 { 1147 AssertMsgFailed(("No constructore! (Device %s)\n", pDevReg->szDeviceName)); 1148 return VERR_PDM_INVALID_DEVICE_REGISTRATION; 1149 } 1150 /* Check matching guest bits last without any asserting. Enables trial and error registration. */ 1151 if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT)) 1152 { 1153 Log(("PDM: Rejected device '%s' because it didn't match the guest bits.\n", pDevReg->szDeviceName)); 1154 return VERR_PDM_INVALID_DEVICE_GUEST_BITS; 1155 } 1156 AssertLogRelMsg(pDevReg->u32VersionEnd == PDM_DEVREG_VERSION, 1157 ("u32VersionEnd=%#x, expected %#x. (szDeviceName=%s)\n", 1158 pDevReg->u32VersionEnd, PDM_DEVREG_VERSION, pDevReg->szDeviceName)); 1159 1160 /* 1161 * Check for duplicate and find FIFO entry at the same time. 1162 */ 1163 PCPDMDEVREGCBINT pRegCB = (PCPDMDEVREGCBINT)pCallbacks; 1164 PPDMDEV pDevPrev = NULL; 1165 PPDMDEV pDev = pRegCB->pVM->pdm.s.pDevs; 1166 for (; pDev; pDevPrev = pDev, pDev = pDev->pNext) 1167 { 1168 if (!strcmp(pDev->pDevReg->szDeviceName, pDevReg->szDeviceName)) 1169 { 1170 AssertMsgFailed(("Device '%s' already exists\n", pDevReg->szDeviceName)); 1171 return VERR_PDM_DEVICE_NAME_CLASH; 1172 } 1173 } 1174 1175 /* 1176 * Allocate new device structure and insert it into the list. 1177 */ 1178 pDev = (PPDMDEV)MMR3HeapAlloc(pRegCB->pVM, MM_TAG_PDM_DEVICE, sizeof(*pDev)); 1179 if (pDev) 1180 { 1181 pDev->pNext = NULL; 1182 pDev->cInstances = 0; 1183 pDev->pInstances = NULL; 1184 pDev->pDevReg = pDevReg; 1185 pDev->cchName = strlen(pDevReg->szDeviceName); 1186 1187 if (pDevPrev) 1188 pDevPrev->pNext = pDev; 1189 else 1190 pRegCB->pVM->pdm.s.pDevs = pDev; 1191 Log(("PDM: Registered device '%s'\n", pDevReg->szDeviceName)); 1192 return VINF_SUCCESS; 1193 } 1194 return VERR_NO_MEMORY; 1195 } 1196 1197 1198 /** 1199 * Allocate memory which is associated with current VM instance 1200 * and automatically freed on it's destruction. 1201 * 1202 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed. 1203 * @param pCallbacks Pointer to the callback table. 1204 * @param cb Number of bytes to allocate. 1205 */ 1206 static DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb) 1207 { 1208 Assert(pCallbacks); 1209 Assert(pCallbacks->u32Version == PDM_DEVREG_CB_VERSION); 1210 1211 void *pv = MMR3HeapAlloc(((PPDMDEVREGCBINT)pCallbacks)->pVM, MM_TAG_PDM_DEVICE_USER, cb); 1212 LogFlow(("pdmR3DevReg_MMHeapAlloc(,%#zx): returns %p\n", cb, pv)); 1213 return pv; 1214 } 1215 1216 1217 1218 1219 1220 /* 1221 * 1222 * 1223 * 1224 * 1225 * p d m R 3 D e v H l p 1226 * p d m R 3 D e v H l p 1227 * p d m R 3 D e v H l p 1228 * 1229 * 1230 * 1231 * 1232 */ 1233 1234 1235 /** 1236 * Queue consumer callback for internal component. 1237 * 1238 * @returns Success indicator. 1239 * If false the item will not be removed and the flushing will stop. 1240 * @param pVM The VM handle. 1241 * @param pItem The item to consume. Upon return this item will be freed. 1242 */ 1243 static DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem) 1244 { 1245 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem; 1246 LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsHC)); 1247 switch (pTask->enmOp) 1248 { 1249 case PDMDEVHLPTASKOP_ISA_SET_IRQ: 1250 PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel); 1251 break; 1252 1253 case PDMDEVHLPTASKOP_PCI_SET_IRQ: 1254 pdmR3DevHlp_PCISetIrq(pTask->pDevInsHC, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel); 1255 break; 1256 1257 case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ: 1258 PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel); 1259 break; 1260 1261 default: 1262 AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp)); 1263 break; 1264 } 1265 return true; 1266 } 1267 1268 1269 /** @copydoc PDMDEVHLPR3::pfnIOPortRegister */ 1270 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, 1271 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc) 1272 { 1273 PDMDEV_ASSERT_DEVINS(pDevIns); 1274 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1275 Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc)); 1276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1277 1278 int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc); 1279 1280 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1281 return rc; 1282 } 1283 1284 1285 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterGC */ 1286 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, 1287 const char *pszOut, const char *pszIn, 1288 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 1289 { 1290 PDMDEV_ASSERT_DEVINS(pDevIns); 1291 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1292 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1293 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 1294 1295 /* 1296 * Resolve the functions (one of the can be NULL). 1297 */ 1298 int rc = VINF_SUCCESS; 1299 if ( pDevIns->pDevReg->szRCMod[0] 1300 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 1301 { 1302 RTGCPTR32 GCPtrIn = 0; 1303 if (pszIn) 1304 { 1305 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszIn, &GCPtrIn); 1306 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szRCMod, pszIn)); 1307 } 1308 RTGCPTR32 GCPtrOut = 0; 1309 if (pszOut && VBOX_SUCCESS(rc)) 1310 { 1311 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOut, &GCPtrOut); 1312 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szRCMod, pszOut)); 1313 } 1314 RTGCPTR32 GCPtrInStr = 0; 1315 if (pszInStr && VBOX_SUCCESS(rc)) 1316 { 1317 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszInStr, &GCPtrInStr); 1318 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szRCMod, pszInStr)); 1319 } 1320 RTGCPTR32 GCPtrOutStr = 0; 1321 if (pszOutStr && VBOX_SUCCESS(rc)) 1322 { 1323 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOutStr, &GCPtrOutStr); 1324 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szRCMod, pszOutStr)); 1325 } 1326 1327 if (VBOX_SUCCESS(rc)) 1328 rc = IOMR3IOPortRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc); 1329 } 1330 else 1331 { 1332 AssertMsgFailed(("No GC module for this driver!\n")); 1333 rc = VERR_INVALID_PARAMETER; 1334 } 1335 1336 LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1337 return rc; 1338 } 1339 1340 1341 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0 */ 1342 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, 1343 const char *pszOut, const char *pszIn, 1344 const char *pszOutStr, const char *pszInStr, const char *pszDesc) 1345 { 1346 PDMDEV_ASSERT_DEVINS(pDevIns); 1347 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1348 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1349 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc)); 1350 1351 /* 1352 * Resolve the functions (one of the can be NULL). 1353 */ 1354 int rc = VINF_SUCCESS; 1355 if ( pDevIns->pDevReg->szR0Mod[0] 1356 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 1357 { 1358 R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0; 1359 if (pszIn) 1360 { 1361 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn); 1362 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn)); 1363 } 1364 R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0; 1365 if (pszOut && VBOX_SUCCESS(rc)) 1366 { 1367 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut); 1368 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut)); 1369 } 1370 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0; 1371 if (pszInStr && VBOX_SUCCESS(rc)) 1372 { 1373 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr); 1374 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr)); 1375 } 1376 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0; 1377 if (pszOutStr && VBOX_SUCCESS(rc)) 1378 { 1379 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr); 1380 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr)); 1381 } 1382 1383 if (VBOX_SUCCESS(rc)) 1384 rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc); 1385 } 1386 else 1387 { 1388 AssertMsgFailed(("No R0 module for this driver!\n")); 1389 rc = VERR_INVALID_PARAMETER; 1390 } 1391 1392 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1393 return rc; 1394 } 1395 1396 1397 /** @copydoc PDMDEVHLPR3::pfnIOPortDeregister */ 1398 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts) 1399 { 1400 PDMDEV_ASSERT_DEVINS(pDevIns); 1401 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1402 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 1403 Port, cPorts)); 1404 1405 int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts); 1406 1407 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1408 return rc; 1409 } 1410 1411 1412 /** @copydoc PDMDEVHLPR3::pfnMMIORegister */ 1413 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, 1414 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, 1415 const char *pszDesc) 1416 { 1417 PDMDEV_ASSERT_DEVINS(pDevIns); 1418 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1419 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n", 1420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc)); 1421 1422 int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc); 1423 1424 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1425 return rc; 1426 } 1427 1428 1429 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterGC */ 1430 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser, 1431 const char *pszWrite, const char *pszRead, const char *pszFill, 1432 const char *pszDesc) 1433 { 1434 PDMDEV_ASSERT_DEVINS(pDevIns); 1435 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1436 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 1437 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 1438 1439 /* 1440 * Resolve the functions. 1441 * Not all function have to present, leave it to IOM to enforce this. 1442 */ 1443 int rc = VINF_SUCCESS; 1444 if ( pDevIns->pDevReg->szRCMod[0] 1445 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 1446 { 1447 RTGCPTR32 GCPtrWrite = 0; 1448 if (pszWrite) 1449 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszWrite, &GCPtrWrite); 1450 RTGCPTR32 GCPtrRead = 0; 1451 int rc2 = VINF_SUCCESS; 1452 if (pszRead) 1453 rc2 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszRead, &GCPtrRead); 1454 RTGCPTR32 GCPtrFill = 0; 1455 int rc3 = VINF_SUCCESS; 1456 if (pszFill) 1457 rc3 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszFill, &GCPtrFill); 1458 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 1459 rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill); 1460 else 1461 { 1462 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szRCMod, pszWrite)); 1463 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szRCMod, pszRead)); 1464 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szRCMod, pszFill)); 1465 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 1466 rc = rc2; 1467 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 1468 rc = rc3; 1469 } 1470 } 1471 else 1472 { 1473 AssertMsgFailed(("No GC module for this driver!\n")); 1474 rc = VERR_INVALID_PARAMETER; 1475 } 1476 1477 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1478 return rc; 1479 } 1480 1481 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterR0 */ 1482 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser, 1483 const char *pszWrite, const char *pszRead, const char *pszFill, 1484 const char *pszDesc) 1485 { 1486 PDMDEV_ASSERT_DEVINS(pDevIns); 1487 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1488 LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n", 1489 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill)); 1490 1491 /* 1492 * Resolve the functions. 1493 * Not all function have to present, leave it to IOM to enforce this. 1494 */ 1495 int rc = VINF_SUCCESS; 1496 if ( pDevIns->pDevReg->szR0Mod[0] 1497 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 1498 { 1499 R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0; 1500 if (pszWrite) 1501 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite); 1502 R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0; 1503 int rc2 = VINF_SUCCESS; 1504 if (pszRead) 1505 rc2 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead); 1506 R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0; 1507 int rc3 = VINF_SUCCESS; 1508 if (pszFill) 1509 rc3 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill); 1510 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3)) 1511 rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill); 1512 else 1513 { 1514 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite)); 1515 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead)); 1516 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill)); 1517 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc)) 1518 rc = rc2; 1519 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc)) 1520 rc = rc3; 1521 } 1522 } 1523 else 1524 { 1525 AssertMsgFailed(("No R0 module for this driver!\n")); 1526 rc = VERR_INVALID_PARAMETER; 1527 } 1528 1529 LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1530 return rc; 1531 } 1532 1533 1534 /** @copydoc PDMDEVHLPR3::pfnMMIODeregister */ 1535 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 1536 { 1537 PDMDEV_ASSERT_DEVINS(pDevIns); 1538 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1539 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 1540 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 1541 1542 int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange); 1543 1544 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1545 return rc; 1546 } 1547 1548 1549 /** @copydoc PDMDEVHLPR3::pfnROMRegister */ 1550 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc) 1551 { 1552 PDMDEV_ASSERT_DEVINS(pDevIns); 1553 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1554 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n", 1555 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc)); 1556 1557 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc); 1558 1559 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1560 return rc; 1561 } 1562 1563 1564 /** @copydoc PDMDEVHLPR3::pfnSSMRegister */ 1565 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, 1566 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, 1567 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone) 1568 { 1569 PDMDEV_ASSERT_DEVINS(pDevIns); 1570 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1571 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n", 1572 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone)); 1573 1574 int rc = SSMR3Register(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess, 1575 pfnSavePrep, pfnSaveExec, pfnSaveDone, 1576 pfnLoadPrep, pfnLoadExec, pfnLoadDone); 1577 1578 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1579 return rc; 1580 } 1581 1582 1583 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */ 1584 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer) 1585 { 1586 PDMDEV_ASSERT_DEVINS(pDevIns); 1587 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1588 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n", 1589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer)); 1590 1591 int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer); 1592 1593 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1594 return rc; 1595 } 1596 1597 1598 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreateExternal */ 1599 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc) 1600 { 1601 PDMDEV_ASSERT_DEVINS(pDevIns); 1602 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 1603 1604 return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMR3, enmClock, pfnCallback, pvUser, pszDesc); 1605 } 1606 1607 /** @copydoc PDMDEVHLPR3::pfnPCIRegister */ 1608 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev) 1609 { 1610 PDMDEV_ASSERT_DEVINS(pDevIns); 1611 PVM pVM = pDevIns->Internal.s.pVMR3; 1612 VM_ASSERT_EMT(pVM); 1613 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n", 1614 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config)); 1615 1616 /* 1617 * Validate input. 1618 */ 1619 if (!pPciDev) 1620 { 1621 Assert(pPciDev); 1622 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1623 return VERR_INVALID_PARAMETER; 1624 } 1625 if (!pPciDev->config[0] && !pPciDev->config[1]) 1626 { 1627 Assert(pPciDev->config[0] || pPciDev->config[1]); 1628 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1629 return VERR_INVALID_PARAMETER; 1630 } 1631 if (pDevIns->Internal.s.pPciDeviceR3) 1632 { 1633 /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to 1634 * support a PDM device with multiple PCI devices. This might become a problem 1635 * when upgrading the chipset for instance... 1636 */ 1637 AssertMsgFailed(("Only one PCI device per device is currently implemented!\n")); 1638 return VERR_INTERNAL_ERROR; 1639 } 1640 1641 /* 1642 * Choose the PCI bus for the device. 1643 * This is simple. If the device was configured for a particular bus, it'll 1644 * already have one. If not, we'll just take the first one. 1645 */ 1646 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1647 if (!pBus) 1648 pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[0]; 1649 int rc; 1650 if (pBus) 1651 { 1652 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1653 pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3); 1654 else 1655 pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR; 1656 1657 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1658 pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3); 1659 else 1660 pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR; 1661 1662 /* 1663 * Check the configuration for PCI device and function assignment. 1664 */ 1665 int iDev = -1; 1666 uint8_t u8Device; 1667 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device); 1668 if (VBOX_SUCCESS(rc)) 1669 { 1670 if (u8Device > 31) 1671 { 1672 AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n", 1673 u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1674 return VERR_INTERNAL_ERROR; 1675 } 1676 1677 uint8_t u8Function; 1678 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function); 1679 if (VBOX_FAILURE(rc)) 1680 { 1681 AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n", 1682 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1683 return rc; 1684 } 1685 if (u8Function > 7) 1686 { 1687 AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n", 1688 u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1689 return VERR_INTERNAL_ERROR; 1690 } 1691 iDev = (u8Device << 3) | u8Function; 1692 } 1693 else if (rc != VERR_CFGM_VALUE_NOT_FOUND) 1694 { 1695 AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n", 1696 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1697 return rc; 1698 } 1699 1700 /* 1701 * Call the pci bus device to do the actual registration. 1702 */ 1703 pdmLock(pVM); 1704 rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev); 1705 pdmUnlock(pVM); 1706 if (VBOX_SUCCESS(rc)) 1707 { 1708 pPciDev->pDevIns = pDevIns; 1709 1710 pDevIns->Internal.s.pPciDeviceR3 = pPciDev; 1711 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0) 1712 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev); 1713 else 1714 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR; 1715 1716 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC) 1717 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev); 1718 else 1719 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR; 1720 1721 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n", 1722 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus)); 1723 } 1724 } 1725 else 1726 { 1727 AssertMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n")); 1728 rc = VERR_PDM_NO_PCI_BUS; 1729 } 1730 1731 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1732 return rc; 1733 } 1734 1735 1736 /** @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister */ 1737 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback) 1738 { 1739 PDMDEV_ASSERT_DEVINS(pDevIns); 1740 PVM pVM = pDevIns->Internal.s.pVMR3; 1741 VM_ASSERT_EMT(pVM); 1742 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n", 1743 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback)); 1744 1745 /* 1746 * Validate input. 1747 */ 1748 if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS) 1749 { 1750 Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS); 1751 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1752 return VERR_INVALID_PARAMETER; 1753 } 1754 switch (enmType) 1755 { 1756 case PCI_ADDRESS_SPACE_MEM: 1757 case PCI_ADDRESS_SPACE_IO: 1758 case PCI_ADDRESS_SPACE_MEM_PREFETCH: 1759 break; 1760 default: 1761 AssertMsgFailed(("enmType=%#x is unknown\n", enmType)); 1762 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1763 return VERR_INVALID_PARAMETER; 1764 } 1765 if (!pfnCallback) 1766 { 1767 Assert(pfnCallback); 1768 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 1769 return VERR_INVALID_PARAMETER; 1770 } 1771 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 1772 1773 /* 1774 * Must have a PCI device registered! 1775 */ 1776 int rc; 1777 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1778 if (pPciDev) 1779 { 1780 /* 1781 * We're currently restricted to page aligned MMIO regions. 1782 */ 1783 if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH) 1784 && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE)) 1785 { 1786 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n", 1787 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE))); 1788 cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE); 1789 } 1790 1791 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1792 Assert(pBus); 1793 pdmLock(pVM); 1794 rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback); 1795 pdmUnlock(pVM); 1796 } 1797 else 1798 { 1799 AssertMsgFailed(("No PCI device registered!\n")); 1800 rc = VERR_PDM_NOT_PCI_DEVICE; 1801 } 1802 1803 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 1804 return rc; 1805 } 1806 1807 1808 /** @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks */ 1809 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, 1810 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld) 1811 { 1812 PDMDEV_ASSERT_DEVINS(pDevIns); 1813 PVM pVM = pDevIns->Internal.s.pVMR3; 1814 VM_ASSERT_EMT(pVM); 1815 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n", 1816 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld)); 1817 1818 /* 1819 * Validate input and resolve defaults. 1820 */ 1821 AssertPtr(pfnRead); 1822 AssertPtr(pfnWrite); 1823 AssertPtrNull(ppfnReadOld); 1824 AssertPtrNull(ppfnWriteOld); 1825 AssertPtrNull(pPciDev); 1826 1827 if (!pPciDev) 1828 pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1829 AssertReleaseMsg(pPciDev, ("You must register your device first!\n")); 1830 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; 1831 AssertRelease(pBus); 1832 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING); 1833 1834 /* 1835 * Do the job. 1836 */ 1837 pdmLock(pVM); 1838 pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld); 1839 pdmUnlock(pVM); 1840 1841 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1842 } 1843 1844 1845 /** @copydoc PDMDEVHLPR3::pfnPCISetIrq */ 1846 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1847 { 1848 PDMDEV_ASSERT_DEVINS(pDevIns); 1849 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 1850 1851 /* 1852 * Validate input. 1853 */ 1854 /** @todo iIrq and iLevel checks. */ 1855 1856 /* 1857 * Must have a PCI device registered! 1858 */ 1859 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3; 1860 if (pPciDev) 1861 { 1862 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */ 1863 Assert(pBus); 1864 PVM pVM = pDevIns->Internal.s.pVMR3; 1865 pdmLock(pVM); 1866 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel); 1867 pdmUnlock(pVM); 1868 } 1869 else 1870 AssertReleaseMsgFailed(("No PCI device registered!\n")); 1871 1872 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1873 } 1874 1875 1876 /** @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait */ 1877 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1878 { 1879 pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel); 1880 } 1881 1882 1883 /** @copydoc PDMDEVHLPR3::pfnISASetIrq */ 1884 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1885 { 1886 PDMDEV_ASSERT_DEVINS(pDevIns); 1887 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel)); 1888 1889 /* 1890 * Validate input. 1891 */ 1892 /** @todo iIrq and iLevel checks. */ 1893 1894 PVM pVM = pDevIns->Internal.s.pVMR3; 1895 PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */ 1896 1897 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1898 } 1899 1900 1901 /** @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait */ 1902 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel) 1903 { 1904 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel); 1905 } 1906 1907 1908 /** @copydoc PDMDEVHLPR3::pfnDriverAttach */ 1909 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc) 1910 { 1911 PDMDEV_ASSERT_DEVINS(pDevIns); 1912 PVM pVM = pDevIns->Internal.s.pVMR3; 1913 VM_ASSERT_EMT(pVM); 1914 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n", 1915 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc)); 1916 1917 /* 1918 * Lookup the LUN, it might already be registered. 1919 */ 1920 PPDMLUN pLunPrev = NULL; 1921 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; 1922 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext) 1923 if (pLun->iLun == iLun) 1924 break; 1925 1926 /* 1927 * Create the LUN if if wasn't found, else check if driver is already attached to it. 1928 */ 1929 if (!pLun) 1930 { 1931 if ( !pBaseInterface 1932 || !pszDesc 1933 || !*pszDesc) 1934 { 1935 Assert(pBaseInterface); 1936 Assert(pszDesc || *pszDesc); 1937 return VERR_INVALID_PARAMETER; 1938 } 1939 1940 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun)); 1941 if (!pLun) 1942 return VERR_NO_MEMORY; 1943 1944 pLun->iLun = iLun; 1945 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL; 1946 pLun->pTop = NULL; 1947 pLun->pBottom = NULL; 1948 pLun->pDevIns = pDevIns; 1949 pLun->pszDesc = pszDesc; 1950 pLun->pBase = pBaseInterface; 1951 if (!pLunPrev) 1952 pDevIns->Internal.s.pLunsR3 = pLun; 1953 else 1954 pLunPrev->pNext = pLun; 1955 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n", 1956 iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1957 } 1958 else if (pLun->pTop) 1959 { 1960 AssertMsgFailed(("Already attached! The device should keep track of such things!\n")); 1961 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED)); 1962 return VERR_PDM_DRIVER_ALREADY_ATTACHED; 1963 } 1964 Assert(pLun->pBase == pBaseInterface); 1965 1966 1967 /* 1968 * Get the attached driver configuration. 1969 */ 1970 int rc; 1971 char szNode[48]; 1972 RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun); 1973 PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode); 1974 if (pNode) 1975 { 1976 char *pszName; 1977 rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName); 1978 if (VBOX_SUCCESS(rc)) 1979 { 1980 /* 1981 * Find the driver. 1982 */ 1983 PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName); 1984 if (pDrv) 1985 { 1986 /* config node */ 1987 PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config"); 1988 if (!pConfigNode) 1989 rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode); 1990 if (VBOX_SUCCESS(rc)) 1991 { 1992 CFGMR3SetRestrictedRoot(pConfigNode); 1993 1994 /* 1995 * Allocate the driver instance. 1996 */ 1997 size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]); 1998 cb = RT_ALIGN_Z(cb, 16); 1999 PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb); 2000 if (pNew) 2001 { 2002 /* 2003 * Initialize the instance structure (declaration order). 2004 */ 2005 pNew->u32Version = PDM_DRVINS_VERSION; 2006 //pNew->Internal.s.pUp = NULL; 2007 //pNew->Internal.s.pDown = NULL; 2008 pNew->Internal.s.pLun = pLun; 2009 pNew->Internal.s.pDrv = pDrv; 2010 pNew->Internal.s.pVM = pVM; 2011 //pNew->Internal.s.fDetaching = false; 2012 pNew->Internal.s.pCfgHandle = pNode; 2013 pNew->pDrvHlp = &g_pdmR3DrvHlp; 2014 pNew->pDrvReg = pDrv->pDrvReg; 2015 pNew->pCfgHandle = pConfigNode; 2016 pNew->iInstance = pDrv->cInstances++; 2017 pNew->pUpBase = pBaseInterface; 2018 //pNew->pDownBase = NULL; 2019 //pNew->IBase.pfnQueryInterface = NULL; 2020 pNew->pvInstanceData = &pNew->achInstanceData[0]; 2021 2022 /* 2023 * Link with LUN and call the constructor. 2024 */ 2025 pLun->pTop = pLun->pBottom = pNew; 2026 rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle); 2027 if (VBOX_SUCCESS(rc)) 2028 { 2029 MMR3HeapFree(pszName); 2030 *ppBaseInterface = &pNew->IBase; 2031 Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n", 2032 pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2033 LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2034 /* 2035 * Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS) */ 2036 return rc; 2037 } 2038 2039 /* 2040 * Free the driver. 2041 */ 2042 pLun->pTop = pLun->pBottom = NULL; 2043 ASMMemFill32(pNew, cb, 0xdeadd0d0); 2044 MMR3HeapFree(pNew); 2045 pDrv->cInstances--; 2046 } 2047 else 2048 { 2049 AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName)); 2050 rc = VERR_NO_MEMORY; 2051 } 2052 } 2053 else 2054 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc)); 2055 } 2056 else 2057 { 2058 AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName)); 2059 rc = VERR_PDM_DRIVER_NOT_FOUND; 2060 } 2061 MMR3HeapFree(pszName); 2062 } 2063 else 2064 { 2065 AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc)); 2066 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2067 rc = VERR_PDM_CFG_MISSING_DRIVER_NAME; 2068 } 2069 } 2070 else 2071 rc = VERR_PDM_NO_ATTACHED_DRIVER; 2072 2073 2074 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2075 return rc; 2076 } 2077 2078 2079 /** @copydoc PDMDEVHLPR3::pfnMMHeapAlloc */ 2080 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb) 2081 { 2082 PDMDEV_ASSERT_DEVINS(pDevIns); 2083 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 2084 2085 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 2086 2087 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2088 return pv; 2089 } 2090 2091 2092 /** @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ */ 2093 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb) 2094 { 2095 PDMDEV_ASSERT_DEVINS(pDevIns); 2096 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb)); 2097 2098 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb); 2099 2100 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2101 return pv; 2102 } 2103 2104 2105 /** @copydoc PDMDEVHLPR3::pfnMMHeapFree */ 2106 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv) 2107 { 2108 PDMDEV_ASSERT_DEVINS(pDevIns); 2109 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv)); 2110 2111 MMR3HeapFree(pv); 2112 2113 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2114 } 2115 2116 2117 /** @copydoc PDMDEVHLPR3::pfnVMSetError */ 2118 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) 2119 { 2120 PDMDEV_ASSERT_DEVINS(pDevIns); 2121 va_list args; 2122 va_start(args, pszFormat); 2123 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2); 2124 va_end(args); 2125 return rc; 2126 } 2127 2128 2129 /** @copydoc PDMDEVHLPR3::pfnVMSetErrorV */ 2130 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) 2131 { 2132 PDMDEV_ASSERT_DEVINS(pDevIns); 2133 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2); 2134 return rc; 2135 } 2136 2137 2138 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError */ 2139 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...) 2140 { 2141 PDMDEV_ASSERT_DEVINS(pDevIns); 2142 va_list args; 2143 va_start(args, pszFormat); 2144 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, args); 2145 va_end(args); 2146 return rc; 2147 } 2148 2149 2150 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeErrorV */ 2151 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va) 2152 { 2153 PDMDEV_ASSERT_DEVINS(pDevIns); 2154 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, va); 2155 return rc; 2156 } 2157 2158 2159 /** @copydoc PDMDEVHLPR3::pfnAssertEMT */ 2160 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2161 { 2162 PDMDEV_ASSERT_DEVINS(pDevIns); 2163 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 2164 return true; 2165 2166 char szMsg[100]; 2167 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 2168 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 2169 AssertBreakpoint(); 2170 return false; 2171 } 2172 2173 2174 /** @copydoc PDMDEVHLPR3::pfnAssertOther */ 2175 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 2176 { 2177 PDMDEV_ASSERT_DEVINS(pDevIns); 2178 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3)) 2179 return true; 2180 2181 char szMsg[100]; 2182 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance); 2183 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 2184 AssertBreakpoint(); 2185 return false; 2186 } 2187 2188 2189 /** @copydoc PDMDEVHLPR3::pfnDBGFStopV */ 2190 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args) 2191 { 2192 PDMDEV_ASSERT_DEVINS(pDevIns); 2193 #ifdef LOG_ENABLED 2194 va_list va2; 2195 va_copy(va2, args); 2196 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n", 2197 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2)); 2198 va_end(va2); 2199 #endif 2200 2201 PVM pVM = pDevIns->Internal.s.pVMR3; 2202 VM_ASSERT_EMT(pVM); 2203 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args); 2204 2205 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2206 return rc; 2207 } 2208 2209 2210 /** @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister */ 2211 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler) 2212 { 2213 PDMDEV_ASSERT_DEVINS(pDevIns); 2214 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n", 2215 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler)); 2216 2217 PVM pVM = pDevIns->Internal.s.pVMR3; 2218 VM_ASSERT_EMT(pVM); 2219 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns); 2220 2221 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2222 return rc; 2223 } 2224 2225 2226 /** @copydoc PDMDEVHLPR3::pfnSTAMRegister */ 2227 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc) 2228 { 2229 PDMDEV_ASSERT_DEVINS(pDevIns); 2230 PVM pVM = pDevIns->Internal.s.pVMR3; 2231 VM_ASSERT_EMT(pVM); 2232 2233 STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); 2234 NOREF(pVM); 2235 } 2236 2237 2238 2239 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterF */ 2240 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 2241 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...) 2242 { 2243 PDMDEV_ASSERT_DEVINS(pDevIns); 2244 PVM pVM = pDevIns->Internal.s.pVMR3; 2245 VM_ASSERT_EMT(pVM); 2246 2247 va_list args; 2248 va_start(args, pszName); 2249 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 2250 va_end(args); 2251 AssertRC(rc); 2252 2253 NOREF(pVM); 2254 } 2255 2256 2257 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterV */ 2258 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, 2259 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args) 2260 { 2261 PDMDEV_ASSERT_DEVINS(pDevIns); 2262 PVM pVM = pDevIns->Internal.s.pVMR3; 2263 VM_ASSERT_EMT(pVM); 2264 2265 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 2266 AssertRC(rc); 2267 2268 NOREF(pVM); 2269 } 2270 2271 2272 /** @copydoc PDMDEVHLPR3::pfnRTCRegister */ 2273 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp) 2274 { 2275 PDMDEV_ASSERT_DEVINS(pDevIns); 2276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2277 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n", 2278 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite, 2279 pRtcReg->pfnWrite, ppRtcHlp)); 2280 2281 /* 2282 * Validate input. 2283 */ 2284 if (pRtcReg->u32Version != PDM_RTCREG_VERSION) 2285 { 2286 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version, 2287 PDM_RTCREG_VERSION)); 2288 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n", 2289 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2290 return VERR_INVALID_PARAMETER; 2291 } 2292 if ( !pRtcReg->pfnWrite 2293 || !pRtcReg->pfnRead) 2294 { 2295 Assert(pRtcReg->pfnWrite); 2296 Assert(pRtcReg->pfnRead); 2297 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 2298 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2299 return VERR_INVALID_PARAMETER; 2300 } 2301 2302 if (!ppRtcHlp) 2303 { 2304 Assert(ppRtcHlp); 2305 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n", 2306 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2307 return VERR_INVALID_PARAMETER; 2308 } 2309 2310 /* 2311 * Only one DMA device. 2312 */ 2313 PVM pVM = pDevIns->Internal.s.pVMR3; 2314 if (pVM->pdm.s.pRtc) 2315 { 2316 AssertMsgFailed(("Only one RTC device is supported!\n")); 2317 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 2318 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2319 return VERR_INVALID_PARAMETER; 2320 } 2321 2322 /* 2323 * Allocate and initialize pci bus structure. 2324 */ 2325 int rc = VINF_SUCCESS; 2326 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc)); 2327 if (pRtc) 2328 { 2329 pRtc->pDevIns = pDevIns; 2330 pRtc->Reg = *pRtcReg; 2331 pVM->pdm.s.pRtc = pRtc; 2332 2333 /* set the helper pointer. */ 2334 *ppRtcHlp = &g_pdmR3DevRtcHlp; 2335 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n", 2336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2337 } 2338 else 2339 rc = VERR_NO_MEMORY; 2340 2341 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n", 2342 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2343 return rc; 2344 } 2345 2346 2347 /** @copydoc PDMDEVHLPR3::pfnPDMQueueCreate */ 2348 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, 2349 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue) 2350 { 2351 PDMDEV_ASSERT_DEVINS(pDevIns); 2352 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n", 2353 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue)); 2354 2355 PVM pVM = pDevIns->Internal.s.pVMR3; 2356 VM_ASSERT_EMT(pVM); 2357 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue); 2358 2359 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue)); 2360 return rc; 2361 } 2362 2363 2364 /** @copydoc PDMDEVHLPR3::pfnCritSectInit */ 2365 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName) 2366 { 2367 PDMDEV_ASSERT_DEVINS(pDevIns); 2368 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n", 2369 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName)); 2370 2371 PVM pVM = pDevIns->Internal.s.pVMR3; 2372 VM_ASSERT_EMT(pVM); 2373 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName); 2374 2375 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2376 return rc; 2377 } 2378 2379 2380 /** @copydoc PDMDEVHLPR3::pfnUTCNow */ 2381 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime) 2382 { 2383 PDMDEV_ASSERT_DEVINS(pDevIns); 2384 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n", 2385 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime)); 2386 2387 pTime = TMR3UTCNow(pDevIns->Internal.s.pVMR3, pTime); 2388 2389 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime))); 2390 return pTime; 2391 } 2392 2393 2394 /** @copydoc PDMDEVHLPR3::pfnPDMThreadCreate */ 2395 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 2396 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 2397 { 2398 PDMDEV_ASSERT_DEVINS(pDevIns); 2399 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2400 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n", 2401 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName)); 2402 2403 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 2404 2405 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 2406 rc, *ppThread)); 2407 return rc; 2408 } 2409 2410 2411 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 2412 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns) 2413 { 2414 PDMDEV_ASSERT_DEVINS(pDevIns); 2415 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3)); 2416 return pDevIns->Internal.s.pVMR3; 2417 } 2418 2419 2420 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 2421 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 2422 { 2423 PDMDEV_ASSERT_DEVINS(pDevIns); 2424 PVM pVM = pDevIns->Internal.s.pVMR3; 2425 VM_ASSERT_EMT(pVM); 2426 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, " 2427 ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n", 2428 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3, 2429 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3, 2430 pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3)); 2431 2432 /* 2433 * Validate the structure. 2434 */ 2435 if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION) 2436 { 2437 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION)); 2438 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2439 return VERR_INVALID_PARAMETER; 2440 } 2441 if ( !pPciBusReg->pfnRegisterR3 2442 || !pPciBusReg->pfnIORegionRegisterR3 2443 || !pPciBusReg->pfnSetIrqR3 2444 || !pPciBusReg->pfnSaveExecR3 2445 || !pPciBusReg->pfnLoadExecR3 2446 || !pPciBusReg->pfnFakePCIBIOSR3) 2447 { 2448 Assert(pPciBusReg->pfnRegisterR3); 2449 Assert(pPciBusReg->pfnIORegionRegisterR3); 2450 Assert(pPciBusReg->pfnSetIrqR3); 2451 Assert(pPciBusReg->pfnSaveExecR3); 2452 Assert(pPciBusReg->pfnLoadExecR3); 2453 Assert(pPciBusReg->pfnFakePCIBIOSR3); 2454 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2455 return VERR_INVALID_PARAMETER; 2456 } 2457 if ( pPciBusReg->pszSetIrqRC 2458 && !VALID_PTR(pPciBusReg->pszSetIrqRC)) 2459 { 2460 Assert(VALID_PTR(pPciBusReg->pszSetIrqRC)); 2461 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2462 return VERR_INVALID_PARAMETER; 2463 } 2464 if ( pPciBusReg->pszSetIrqR0 2465 && !VALID_PTR(pPciBusReg->pszSetIrqR0)) 2466 { 2467 Assert(VALID_PTR(pPciBusReg->pszSetIrqR0)); 2468 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2469 return VERR_INVALID_PARAMETER; 2470 } 2471 if (!ppPciHlpR3) 2472 { 2473 Assert(ppPciHlpR3); 2474 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2475 return VERR_INVALID_PARAMETER; 2476 } 2477 2478 /* 2479 * Find free PCI bus entry. 2480 */ 2481 unsigned iBus = 0; 2482 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++) 2483 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3) 2484 break; 2485 if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses)) 2486 { 2487 AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses))); 2488 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2489 return VERR_INVALID_PARAMETER; 2490 } 2491 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus]; 2492 2493 /* 2494 * Resolve and init the RC bits. 2495 */ 2496 if (pPciBusReg->pszSetIrqRC) 2497 { 2498 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC); 2499 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, rc)); 2500 if (VBOX_FAILURE(rc)) 2501 { 2502 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2503 return rc; 2504 } 2505 pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2506 } 2507 else 2508 { 2509 pPciBus->pfnSetIrqRC = 0; 2510 pPciBus->pDevInsRC = 0; 2511 } 2512 2513 /* 2514 * Resolve and init the R0 bits. 2515 */ 2516 if (pPciBusReg->pszSetIrqR0) 2517 { 2518 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0); 2519 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc)); 2520 if (VBOX_FAILURE(rc)) 2521 { 2522 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2523 return rc; 2524 } 2525 pPciBus->pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2526 } 2527 else 2528 { 2529 pPciBus->pfnSetIrqR0 = 0; 2530 pPciBus->pDevInsR0 = 0; 2531 } 2532 2533 /* 2534 * Init the R3 bits. 2535 */ 2536 pPciBus->iBus = iBus; 2537 pPciBus->pDevInsR3 = pDevIns; 2538 pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3; 2539 pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3; 2540 pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3; 2541 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3; 2542 pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3; 2543 pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3; 2544 pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3; 2545 2546 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2547 2548 /* set the helper pointer and return. */ 2549 *ppPciHlpR3 = &g_pdmR3DevPciHlp; 2550 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2551 return VINF_SUCCESS; 2552 } 2553 2554 2555 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 2556 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 2557 { 2558 PDMDEV_ASSERT_DEVINS(pDevIns); 2559 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2560 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n", 2561 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3, 2562 pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC, 2563 pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0, 2564 ppPicHlpR3)); 2565 2566 /* 2567 * Validate input. 2568 */ 2569 if (pPicReg->u32Version != PDM_PICREG_VERSION) 2570 { 2571 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION)); 2572 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2573 return VERR_INVALID_PARAMETER; 2574 } 2575 if ( !pPicReg->pfnSetIrqR3 2576 || !pPicReg->pfnGetInterruptR3) 2577 { 2578 Assert(pPicReg->pfnSetIrqR3); 2579 Assert(pPicReg->pfnGetInterruptR3); 2580 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2581 return VERR_INVALID_PARAMETER; 2582 } 2583 if ( ( pPicReg->pszSetIrqRC 2584 || pPicReg->pszGetInterruptRC) 2585 && ( !VALID_PTR(pPicReg->pszSetIrqRC) 2586 || !VALID_PTR(pPicReg->pszGetInterruptRC)) 2587 ) 2588 { 2589 Assert(VALID_PTR(pPicReg->pszSetIrqRC)); 2590 Assert(VALID_PTR(pPicReg->pszGetInterruptRC)); 2591 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2592 return VERR_INVALID_PARAMETER; 2593 } 2594 if ( pPicReg->pszSetIrqRC 2595 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)) 2596 { 2597 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC); 2598 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2599 return VERR_INVALID_PARAMETER; 2600 } 2601 if ( pPicReg->pszSetIrqR0 2602 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)) 2603 { 2604 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0); 2605 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2606 return VERR_INVALID_PARAMETER; 2607 } 2608 if (!ppPicHlpR3) 2609 { 2610 Assert(ppPicHlpR3); 2611 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2612 return VERR_INVALID_PARAMETER; 2613 } 2614 2615 /* 2616 * Only one PIC device. 2617 */ 2618 PVM pVM = pDevIns->Internal.s.pVMR3; 2619 if (pVM->pdm.s.Pic.pDevInsR3) 2620 { 2621 AssertMsgFailed(("Only one pic device is supported!\n")); 2622 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2623 return VERR_INVALID_PARAMETER; 2624 } 2625 2626 /* 2627 * RC stuff. 2628 */ 2629 if (pPicReg->pszSetIrqRC) 2630 { 2631 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC); 2632 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, rc)); 2633 if (VBOX_SUCCESS(rc)) 2634 { 2635 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC); 2636 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, rc)); 2637 } 2638 if (VBOX_FAILURE(rc)) 2639 { 2640 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2641 return rc; 2642 } 2643 pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2644 } 2645 else 2646 { 2647 pVM->pdm.s.Pic.pDevInsRC = 0; 2648 pVM->pdm.s.Pic.pfnSetIrqRC = 0; 2649 pVM->pdm.s.Pic.pfnGetInterruptRC = 0; 2650 } 2651 2652 /* 2653 * R0 stuff. 2654 */ 2655 if (pPicReg->pszSetIrqR0) 2656 { 2657 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0); 2658 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc)); 2659 if (VBOX_SUCCESS(rc)) 2660 { 2661 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0); 2662 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc)); 2663 } 2664 if (VBOX_FAILURE(rc)) 2665 { 2666 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2667 return rc; 2668 } 2669 pVM->pdm.s.Pic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2670 Assert(pVM->pdm.s.Pic.pDevInsR0); 2671 } 2672 else 2673 { 2674 pVM->pdm.s.Pic.pfnSetIrqR0 = 0; 2675 pVM->pdm.s.Pic.pfnGetInterruptR0 = 0; 2676 pVM->pdm.s.Pic.pDevInsR0 = 0; 2677 } 2678 2679 /* 2680 * R3 stuff. 2681 */ 2682 pVM->pdm.s.Pic.pDevInsR3 = pDevIns; 2683 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3; 2684 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3; 2685 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2686 2687 /* set the helper pointer and return. */ 2688 *ppPicHlpR3 = &g_pdmR3DevPicHlp; 2689 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2690 return VINF_SUCCESS; 2691 } 2692 2693 2694 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 2695 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 2696 { 2697 PDMDEV_ASSERT_DEVINS(pDevIns); 2698 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2699 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, " 2700 ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, " 2701 ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n", 2702 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3, 2703 pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC, 2704 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC, 2705 pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC, 2706 pApicReg->pszBusDeliverRC, ppApicHlpR3)); 2707 2708 /* 2709 * Validate input. 2710 */ 2711 if (pApicReg->u32Version != PDM_APICREG_VERSION) 2712 { 2713 AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION)); 2714 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2715 return VERR_INVALID_PARAMETER; 2716 } 2717 if ( !pApicReg->pfnGetInterruptR3 2718 || !pApicReg->pfnHasPendingIrqR3 2719 || !pApicReg->pfnSetBaseR3 2720 || !pApicReg->pfnGetBaseR3 2721 || !pApicReg->pfnSetTPRR3 2722 || !pApicReg->pfnGetTPRR3 2723 || !pApicReg->pfnBusDeliverR3) 2724 { 2725 Assert(pApicReg->pfnGetInterruptR3); 2726 Assert(pApicReg->pfnHasPendingIrqR3); 2727 Assert(pApicReg->pfnSetBaseR3); 2728 Assert(pApicReg->pfnGetBaseR3); 2729 Assert(pApicReg->pfnSetTPRR3); 2730 Assert(pApicReg->pfnGetTPRR3); 2731 Assert(pApicReg->pfnBusDeliverR3); 2732 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2733 return VERR_INVALID_PARAMETER; 2734 } 2735 if ( ( pApicReg->pszGetInterruptRC 2736 || pApicReg->pszHasPendingIrqRC 2737 || pApicReg->pszSetBaseRC 2738 || pApicReg->pszGetBaseRC 2739 || pApicReg->pszSetTPRRC 2740 || pApicReg->pszGetTPRRC 2741 || pApicReg->pszBusDeliverRC) 2742 && ( !VALID_PTR(pApicReg->pszGetInterruptRC) 2743 || !VALID_PTR(pApicReg->pszHasPendingIrqRC) 2744 || !VALID_PTR(pApicReg->pszSetBaseRC) 2745 || !VALID_PTR(pApicReg->pszGetBaseRC) 2746 || !VALID_PTR(pApicReg->pszSetTPRRC) 2747 || !VALID_PTR(pApicReg->pszGetTPRRC) 2748 || !VALID_PTR(pApicReg->pszBusDeliverRC)) 2749 ) 2750 { 2751 Assert(VALID_PTR(pApicReg->pszGetInterruptRC)); 2752 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC)); 2753 Assert(VALID_PTR(pApicReg->pszSetBaseRC)); 2754 Assert(VALID_PTR(pApicReg->pszGetBaseRC)); 2755 Assert(VALID_PTR(pApicReg->pszSetTPRRC)); 2756 Assert(VALID_PTR(pApicReg->pszGetTPRRC)); 2757 Assert(VALID_PTR(pApicReg->pszBusDeliverRC)); 2758 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2759 return VERR_INVALID_PARAMETER; 2760 } 2761 if ( ( pApicReg->pszGetInterruptR0 2762 || pApicReg->pszHasPendingIrqR0 2763 || pApicReg->pszSetBaseR0 2764 || pApicReg->pszGetBaseR0 2765 || pApicReg->pszSetTPRR0 2766 || pApicReg->pszGetTPRR0 2767 || pApicReg->pszBusDeliverR0) 2768 && ( !VALID_PTR(pApicReg->pszGetInterruptR0) 2769 || !VALID_PTR(pApicReg->pszHasPendingIrqR0) 2770 || !VALID_PTR(pApicReg->pszSetBaseR0) 2771 || !VALID_PTR(pApicReg->pszGetBaseR0) 2772 || !VALID_PTR(pApicReg->pszSetTPRR0) 2773 || !VALID_PTR(pApicReg->pszGetTPRR0) 2774 || !VALID_PTR(pApicReg->pszBusDeliverR0)) 2775 ) 2776 { 2777 Assert(VALID_PTR(pApicReg->pszGetInterruptR0)); 2778 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0)); 2779 Assert(VALID_PTR(pApicReg->pszSetBaseR0)); 2780 Assert(VALID_PTR(pApicReg->pszGetBaseR0)); 2781 Assert(VALID_PTR(pApicReg->pszSetTPRR0)); 2782 Assert(VALID_PTR(pApicReg->pszGetTPRR0)); 2783 Assert(VALID_PTR(pApicReg->pszBusDeliverR0)); 2784 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2785 return VERR_INVALID_PARAMETER; 2786 } 2787 if (!ppApicHlpR3) 2788 { 2789 Assert(ppApicHlpR3); 2790 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2791 return VERR_INVALID_PARAMETER; 2792 } 2793 2794 /* 2795 * Only one APIC device. (malc: only in UP case actually) 2796 */ 2797 PVM pVM = pDevIns->Internal.s.pVMR3; 2798 if (pVM->pdm.s.Apic.pDevInsR3) 2799 { 2800 AssertMsgFailed(("Only one apic device is supported!\n")); 2801 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2802 return VERR_INVALID_PARAMETER; 2803 } 2804 2805 /* 2806 * Resolve & initialize the RC bits. 2807 */ 2808 if (pApicReg->pszGetInterruptRC) 2809 { 2810 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC); 2811 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, rc)); 2812 if (RT_SUCCESS(rc)) 2813 { 2814 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC); 2815 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc)); 2816 } 2817 if (RT_SUCCESS(rc)) 2818 { 2819 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC); 2820 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, rc)); 2821 } 2822 if (RT_SUCCESS(rc)) 2823 { 2824 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC); 2825 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, rc)); 2826 } 2827 if (RT_SUCCESS(rc)) 2828 { 2829 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC); 2830 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, rc)); 2831 } 2832 if (RT_SUCCESS(rc)) 2833 { 2834 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC); 2835 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc)); 2836 } 2837 if (RT_SUCCESS(rc)) 2838 { 2839 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC); 2840 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc)); 2841 } 2842 if (VBOX_FAILURE(rc)) 2843 { 2844 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2845 return rc; 2846 } 2847 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2848 } 2849 else 2850 { 2851 pVM->pdm.s.Apic.pDevInsRC = 0; 2852 pVM->pdm.s.Apic.pfnGetInterruptRC = 0; 2853 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0; 2854 pVM->pdm.s.Apic.pfnSetBaseRC = 0; 2855 pVM->pdm.s.Apic.pfnGetBaseRC = 0; 2856 pVM->pdm.s.Apic.pfnSetTPRRC = 0; 2857 pVM->pdm.s.Apic.pfnGetTPRRC = 0; 2858 pVM->pdm.s.Apic.pfnBusDeliverRC = 0; 2859 } 2860 2861 /* 2862 * Resolve & initialize the R0 bits. 2863 */ 2864 if (pApicReg->pszGetInterruptR0) 2865 { 2866 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0); 2867 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc)); 2868 if (RT_SUCCESS(rc)) 2869 { 2870 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0); 2871 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc)); 2872 } 2873 if (RT_SUCCESS(rc)) 2874 { 2875 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0); 2876 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc)); 2877 } 2878 if (RT_SUCCESS(rc)) 2879 { 2880 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0); 2881 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc)); 2882 } 2883 if (RT_SUCCESS(rc)) 2884 { 2885 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0); 2886 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc)); 2887 } 2888 if (RT_SUCCESS(rc)) 2889 { 2890 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0); 2891 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc)); 2892 } 2893 if (RT_SUCCESS(rc)) 2894 { 2895 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0); 2896 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc)); 2897 } 2898 if (VBOX_FAILURE(rc)) 2899 { 2900 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2901 return rc; 2902 } 2903 pVM->pdm.s.Apic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 2904 Assert(pVM->pdm.s.Apic.pDevInsR0); 2905 } 2906 else 2907 { 2908 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0; 2909 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0; 2910 pVM->pdm.s.Apic.pfnSetBaseR0 = 0; 2911 pVM->pdm.s.Apic.pfnGetBaseR0 = 0; 2912 pVM->pdm.s.Apic.pfnSetTPRR0 = 0; 2913 pVM->pdm.s.Apic.pfnGetTPRR0 = 0; 2914 pVM->pdm.s.Apic.pfnBusDeliverR0 = 0; 2915 pVM->pdm.s.Apic.pDevInsR0 = 0; 2916 } 2917 2918 /* 2919 * Initialize the HC bits. 2920 */ 2921 pVM->pdm.s.Apic.pDevInsR3 = pDevIns; 2922 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3; 2923 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3; 2924 pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3; 2925 pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3; 2926 pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3; 2927 pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3; 2928 pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3; 2929 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 2930 2931 /* set the helper pointer and return. */ 2932 *ppApicHlpR3 = &g_pdmR3DevApicHlp; 2933 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 2934 return VINF_SUCCESS; 2935 } 2936 2937 2938 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 2939 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 2940 { 2941 PDMDEV_ASSERT_DEVINS(pDevIns); 2942 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 2943 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n", 2944 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3, 2945 pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3)); 2946 2947 /* 2948 * Validate input. 2949 */ 2950 if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION) 2951 { 2952 AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION)); 2953 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2954 return VERR_INVALID_PARAMETER; 2955 } 2956 if (!pIoApicReg->pfnSetIrqR3) 2957 { 2958 Assert(pIoApicReg->pfnSetIrqR3); 2959 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2960 return VERR_INVALID_PARAMETER; 2961 } 2962 if ( pIoApicReg->pszSetIrqRC 2963 && !VALID_PTR(pIoApicReg->pszSetIrqRC)) 2964 { 2965 Assert(VALID_PTR(pIoApicReg->pszSetIrqRC)); 2966 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2967 return VERR_INVALID_PARAMETER; 2968 } 2969 if ( pIoApicReg->pszSetIrqR0 2970 && !VALID_PTR(pIoApicReg->pszSetIrqR0)) 2971 { 2972 Assert(VALID_PTR(pIoApicReg->pszSetIrqR0)); 2973 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2974 return VERR_INVALID_PARAMETER; 2975 } 2976 if (!ppIoApicHlpR3) 2977 { 2978 Assert(ppIoApicHlpR3); 2979 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2980 return VERR_INVALID_PARAMETER; 2981 } 2982 2983 /* 2984 * The I/O APIC requires the APIC to be present (hacks++). 2985 * If the I/O APIC does GC stuff so must the APIC. 2986 */ 2987 PVM pVM = pDevIns->Internal.s.pVMR3; 2988 if (!pVM->pdm.s.Apic.pDevInsR3) 2989 { 2990 AssertMsgFailed(("Configuration error / Init order error! No APIC!\n")); 2991 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2992 return VERR_INVALID_PARAMETER; 2993 } 2994 if ( pIoApicReg->pszSetIrqRC 2995 && !pVM->pdm.s.Apic.pDevInsRC) 2996 { 2997 AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n")); 2998 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 2999 return VERR_INVALID_PARAMETER; 3000 } 3001 3002 /* 3003 * Only one I/O APIC device. 3004 */ 3005 if (pVM->pdm.s.IoApic.pDevInsR3) 3006 { 3007 AssertMsgFailed(("Only one ioapic device is supported!\n")); 3008 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3009 return VERR_INVALID_PARAMETER; 3010 } 3011 3012 /* 3013 * Resolve & initialize the GC bits. 3014 */ 3015 if (pIoApicReg->pszSetIrqRC) 3016 { 3017 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC); 3018 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, rc)); 3019 if (VBOX_FAILURE(rc)) 3020 { 3021 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3022 return rc; 3023 } 3024 pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 3025 } 3026 else 3027 { 3028 pVM->pdm.s.IoApic.pDevInsRC = 0; 3029 pVM->pdm.s.IoApic.pfnSetIrqRC = 0; 3030 } 3031 3032 /* 3033 * Resolve & initialize the R0 bits. 3034 */ 3035 if (pIoApicReg->pszSetIrqR0) 3036 { 3037 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0); 3038 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc)); 3039 if (VBOX_FAILURE(rc)) 3040 { 3041 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3042 return rc; 3043 } 3044 pVM->pdm.s.IoApic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns); 3045 Assert(pVM->pdm.s.IoApic.pDevInsR0); 3046 } 3047 else 3048 { 3049 pVM->pdm.s.IoApic.pfnSetIrqR0 = 0; 3050 pVM->pdm.s.IoApic.pDevInsR0 = 0; 3051 } 3052 3053 /* 3054 * Initialize the R3 bits. 3055 */ 3056 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns; 3057 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3; 3058 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 3059 3060 /* set the helper pointer and return. */ 3061 *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp; 3062 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS)); 3063 return VINF_SUCCESS; 3064 } 3065 3066 3067 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 3068 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 3069 { 3070 PDMDEV_ASSERT_DEVINS(pDevIns); 3071 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3072 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n", 3073 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister, 3074 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp)); 3075 3076 /* 3077 * Validate input. 3078 */ 3079 if (pDmacReg->u32Version != PDM_DMACREG_VERSION) 3080 { 3081 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version, 3082 PDM_DMACREG_VERSION)); 3083 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n", 3084 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3085 return VERR_INVALID_PARAMETER; 3086 } 3087 if ( !pDmacReg->pfnRun 3088 || !pDmacReg->pfnRegister 3089 || !pDmacReg->pfnReadMemory 3090 || !pDmacReg->pfnWriteMemory 3091 || !pDmacReg->pfnSetDREQ 3092 || !pDmacReg->pfnGetChannelMode) 3093 { 3094 Assert(pDmacReg->pfnRun); 3095 Assert(pDmacReg->pfnRegister); 3096 Assert(pDmacReg->pfnReadMemory); 3097 Assert(pDmacReg->pfnWriteMemory); 3098 Assert(pDmacReg->pfnSetDREQ); 3099 Assert(pDmacReg->pfnGetChannelMode); 3100 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n", 3101 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3102 return VERR_INVALID_PARAMETER; 3103 } 3104 3105 if (!ppDmacHlp) 3106 { 3107 Assert(ppDmacHlp); 3108 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n", 3109 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3110 return VERR_INVALID_PARAMETER; 3111 } 3112 3113 /* 3114 * Only one DMA device. 3115 */ 3116 PVM pVM = pDevIns->Internal.s.pVMR3; 3117 if (pVM->pdm.s.pDmac) 3118 { 3119 AssertMsgFailed(("Only one DMA device is supported!\n")); 3120 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 3121 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER)); 3122 return VERR_INVALID_PARAMETER; 3123 } 3124 3125 /* 3126 * Allocate and initialize pci bus structure. 3127 */ 3128 int rc = VINF_SUCCESS; 3129 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac)); 3130 if (pDmac) 3131 { 3132 pDmac->pDevIns = pDevIns; 3133 pDmac->Reg = *pDmacReg; 3134 pVM->pdm.s.pDmac = pDmac; 3135 3136 /* set the helper pointer. */ 3137 *ppDmacHlp = &g_pdmR3DevDmacHlp; 3138 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n", 3139 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns)); 3140 } 3141 else 3142 rc = VERR_NO_MEMORY; 3143 3144 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n", 3145 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3146 return rc; 3147 } 3148 3149 3150 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 3151 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 3152 { 3153 PDMDEV_ASSERT_DEVINS(pDevIns); 3154 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n", 3155 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead)); 3156 3157 /* 3158 * For the convenience of the device we put no thread restriction on this interface. 3159 * That means we'll have to check which thread we're in and choose our path. 3160 */ 3161 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 3162 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3163 #else 3164 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 3165 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3166 else 3167 { 3168 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3169 PVMREQ pReq; 3170 AssertCompileSize(RTGCPHYS, 4); 3171 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 3172 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 3173 while (rc == VERR_TIMEOUT) 3174 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 3175 AssertReleaseRC(rc); 3176 VMR3ReqFree(pReq); 3177 } 3178 #endif 3179 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3180 } 3181 3182 3183 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 3184 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 3185 { 3186 PDMDEV_ASSERT_DEVINS(pDevIns); 3187 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n", 3188 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite)); 3189 3190 /* 3191 * For the convenience of the device we put no thread restriction on this interface. 3192 * That means we'll have to check which thread we're in and choose our path. 3193 */ 3194 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 3195 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3196 #else 3197 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 3198 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3199 else 3200 { 3201 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3202 PVMREQ pReq; 3203 AssertCompileSize(RTGCPHYS, 4); 3204 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT, 3205 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 3206 while (rc == VERR_TIMEOUT) 3207 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 3208 AssertReleaseRC(rc); 3209 VMR3ReqFree(pReq); 3210 } 3211 #endif 3212 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3213 } 3214 3215 3216 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 3217 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 3218 { 3219 PDMDEV_ASSERT_DEVINS(pDevIns); 3220 PVM pVM = pDevIns->Internal.s.pVMR3; 3221 VM_ASSERT_EMT(pVM); 3222 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n", 3223 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb)); 3224 3225 if (!VM_IS_EMT(pVM)) 3226 return VERR_ACCESS_DENIED; 3227 3228 int rc = PGMPhysReadGCPtr(pVM, pvDst, GCVirtSrc, cb); 3229 3230 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3231 3232 return rc; 3233 } 3234 3235 3236 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 3237 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 3238 { 3239 PDMDEV_ASSERT_DEVINS(pDevIns); 3240 PVM pVM = pDevIns->Internal.s.pVMR3; 3241 VM_ASSERT_EMT(pVM); 3242 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n", 3243 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb)); 3244 3245 if (!VM_IS_EMT(pVM)) 3246 return VERR_ACCESS_DENIED; 3247 3248 int rc = PGMPhysWriteGCPtr(pVM, GCVirtDst, pvSrc, cb); 3249 3250 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3251 3252 return rc; 3253 } 3254 3255 3256 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 3257 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 3258 { 3259 PDMDEV_ASSERT_DEVINS(pDevIns); 3260 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3261 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n", 3262 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc)); 3263 3264 int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMR3, GCPhys, cbRange, pszDesc); 3265 3266 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3267 3268 return rc; 3269 } 3270 3271 3272 /** @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys */ 3273 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys) 3274 { 3275 PDMDEV_ASSERT_DEVINS(pDevIns); 3276 PVM pVM = pDevIns->Internal.s.pVMR3; 3277 VM_ASSERT_EMT(pVM); 3278 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n", 3279 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys)); 3280 3281 if (!VM_IS_EMT(pVM)) 3282 return VERR_ACCESS_DENIED; 3283 3284 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys); 3285 3286 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys)); 3287 3288 return rc; 3289 } 3290 3291 3292 /** @copydoc PDMDEVHLPR3::pfnVMState */ 3293 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns) 3294 { 3295 PDMDEV_ASSERT_DEVINS(pDevIns); 3296 3297 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3); 3298 3299 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 3300 enmVMState, VMR3GetStateName(enmVMState))); 3301 return enmVMState; 3302 } 3303 3304 3305 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 3306 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns) 3307 { 3308 PDMDEV_ASSERT_DEVINS(pDevIns); 3309 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3310 3311 bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMR3); 3312 3313 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc)); 3314 return fRc; 3315 } 3316 3317 3318 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 3319 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable) 3320 { 3321 PDMDEV_ASSERT_DEVINS(pDevIns); 3322 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3323 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable)); 3324 //Assert(*(unsigned *)&fEnable <= 1); 3325 PGMR3PhysSetA20(pDevIns->Internal.s.pVMR3, fEnable); 3326 } 3327 3328 3329 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 3330 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns) 3331 { 3332 PDMDEV_ASSERT_DEVINS(pDevIns); 3333 PVM pVM = pDevIns->Internal.s.pVMR3; 3334 VM_ASSERT_EMT(pVM); 3335 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n", 3336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET))); 3337 3338 /* 3339 * We postpone this operation because we're likely to be inside a I/O instruction 3340 * and the EIP will be updated when we return. 3341 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation. 3342 */ 3343 bool fHaltOnReset; 3344 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset); 3345 if (VBOX_SUCCESS(rc) && fHaltOnReset) 3346 { 3347 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n")); 3348 rc = VINF_EM_HALT; 3349 } 3350 else 3351 { 3352 VM_FF_SET(pVM, VM_FF_RESET); 3353 rc = VINF_EM_RESET; 3354 } 3355 3356 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3357 return rc; 3358 } 3359 3360 3361 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 3362 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns) 3363 { 3364 PDMDEV_ASSERT_DEVINS(pDevIns); 3365 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3366 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n", 3367 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3368 3369 int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3); 3370 3371 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3372 return rc; 3373 } 3374 3375 3376 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 3377 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns) 3378 { 3379 PDMDEV_ASSERT_DEVINS(pDevIns); 3380 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3381 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n", 3382 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3383 3384 int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3); 3385 3386 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3387 return rc; 3388 } 3389 3390 3391 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 3392 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns) 3393 { 3394 return VMMR3Lock(pDevIns->Internal.s.pVMR3); 3395 } 3396 3397 3398 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 3399 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns) 3400 { 3401 return VMMR3Unlock(pDevIns->Internal.s.pVMR3); 3402 } 3403 3404 3405 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 3406 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 3407 { 3408 PVM pVM = pDevIns->Internal.s.pVMR3; 3409 if (VMMR3LockIsOwner(pVM)) 3410 return true; 3411 3412 RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM); 3413 RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner); 3414 char szMsg[100]; 3415 RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n", 3416 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 3417 NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName()); 3418 AssertMsg1(szMsg, iLine, pszFile, pszFunction); 3419 AssertBreakpoint(); 3420 return false; 3421 } 3422 3423 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 3424 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 3425 { 3426 PDMDEV_ASSERT_DEVINS(pDevIns); 3427 PVM pVM = pDevIns->Internal.s.pVMR3; 3428 VM_ASSERT_EMT(pVM); 3429 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n", 3430 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser)); 3431 int rc = VINF_SUCCESS; 3432 if (pVM->pdm.s.pDmac) 3433 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser); 3434 else 3435 { 3436 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3437 rc = VERR_PDM_NO_DMAC_INSTANCE; 3438 } 3439 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n", 3440 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3441 return rc; 3442 } 3443 3444 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 3445 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 3446 { 3447 PDMDEV_ASSERT_DEVINS(pDevIns); 3448 PVM pVM = pDevIns->Internal.s.pVMR3; 3449 VM_ASSERT_EMT(pVM); 3450 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n", 3451 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead)); 3452 int rc = VINF_SUCCESS; 3453 if (pVM->pdm.s.pDmac) 3454 { 3455 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 3456 if (pcbRead) 3457 *pcbRead = cb; 3458 } 3459 else 3460 { 3461 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3462 rc = VERR_PDM_NO_DMAC_INSTANCE; 3463 } 3464 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n", 3465 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3466 return rc; 3467 } 3468 3469 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 3470 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 3471 { 3472 PDMDEV_ASSERT_DEVINS(pDevIns); 3473 PVM pVM = pDevIns->Internal.s.pVMR3; 3474 VM_ASSERT_EMT(pVM); 3475 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n", 3476 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten)); 3477 int rc = VINF_SUCCESS; 3478 if (pVM->pdm.s.pDmac) 3479 { 3480 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock); 3481 if (pcbWritten) 3482 *pcbWritten = cb; 3483 } 3484 else 3485 { 3486 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3487 rc = VERR_PDM_NO_DMAC_INSTANCE; 3488 } 3489 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n", 3490 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3491 return rc; 3492 } 3493 3494 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 3495 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 3496 { 3497 PDMDEV_ASSERT_DEVINS(pDevIns); 3498 PVM pVM = pDevIns->Internal.s.pVMR3; 3499 VM_ASSERT_EMT(pVM); 3500 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n", 3501 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel)); 3502 int rc = VINF_SUCCESS; 3503 if (pVM->pdm.s.pDmac) 3504 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel); 3505 else 3506 { 3507 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3508 rc = VERR_PDM_NO_DMAC_INSTANCE; 3509 } 3510 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n", 3511 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3512 return rc; 3513 } 3514 3515 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 3516 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 3517 { 3518 PDMDEV_ASSERT_DEVINS(pDevIns); 3519 PVM pVM = pDevIns->Internal.s.pVMR3; 3520 VM_ASSERT_EMT(pVM); 3521 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n", 3522 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel)); 3523 uint8_t u8Mode; 3524 if (pVM->pdm.s.pDmac) 3525 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel); 3526 else 3527 { 3528 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3529 u8Mode = 3 << 2 /* illegal mode type */; 3530 } 3531 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n", 3532 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode)); 3533 return u8Mode; 3534 } 3535 3536 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 3537 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns) 3538 { 3539 PDMDEV_ASSERT_DEVINS(pDevIns); 3540 PVM pVM = pDevIns->Internal.s.pVMR3; 3541 VM_ASSERT_EMT(pVM); 3542 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n", 3543 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA))); 3544 3545 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n")); 3546 VM_FF_SET(pVM, VM_FF_PDM_DMA); 3547 REMR3NotifyDmaPending(pVM); 3548 VMR3NotifyFF(pVM, true); 3549 } 3550 3551 3552 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 3553 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 3554 { 3555 PDMDEV_ASSERT_DEVINS(pDevIns); 3556 PVM pVM = pDevIns->Internal.s.pVMR3; 3557 VM_ASSERT_EMT(pVM); 3558 3559 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n", 3560 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value)); 3561 int rc; 3562 if (pVM->pdm.s.pRtc) 3563 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value); 3564 else 3565 rc = VERR_PDM_NO_RTC_INSTANCE; 3566 3567 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 3568 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3569 return rc; 3570 } 3571 3572 3573 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 3574 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 3575 { 3576 PDMDEV_ASSERT_DEVINS(pDevIns); 3577 PVM pVM = pDevIns->Internal.s.pVMR3; 3578 VM_ASSERT_EMT(pVM); 3579 3580 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n", 3581 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value)); 3582 int rc; 3583 if (pVM->pdm.s.pRtc) 3584 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value); 3585 else 3586 rc = VERR_PDM_NO_RTC_INSTANCE; 3587 3588 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n", 3589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3590 return rc; 3591 } 3592 3593 3594 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 3595 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 3596 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 3597 { 3598 PDMDEV_ASSERT_DEVINS(pDevIns); 3599 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n", 3600 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx)); 3601 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx); 3602 3603 CPUMGetGuestCpuId(pDevIns->Internal.s.pVMR3, iLeaf, pEax, pEbx, pEcx, pEdx); 3604 3605 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n", 3606 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx)); 3607 } 3608 3609 3610 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 3611 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 3612 { 3613 PDMDEV_ASSERT_DEVINS(pDevIns); 3614 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n", 3615 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 3616 3617 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange); 3618 3619 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3620 return rc; 3621 } 3622 3623 3624 /** 3625 * @copydoc PDMDEVHLPR3::pfnMMIO2Register 3626 */ 3627 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 3628 { 3629 PDMDEV_ASSERT_DEVINS(pDevIns); 3630 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3631 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n", 3632 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc)); 3633 3634 int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc); 3635 3636 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3637 return rc; 3638 } 3639 3640 3641 /** 3642 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister 3643 */ 3644 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 3645 { 3646 PDMDEV_ASSERT_DEVINS(pDevIns); 3647 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3648 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n", 3649 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion)); 3650 3651 AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER); 3652 3653 int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion); 3654 3655 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3656 return rc; 3657 } 3658 3659 3660 /** 3661 * @copydoc PDMDEVHLPR3::pfnMMIO2Map 3662 */ 3663 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 3664 { 3665 PDMDEV_ASSERT_DEVINS(pDevIns); 3666 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3667 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 3668 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 3669 3670 int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 3671 3672 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3673 return rc; 3674 } 3675 3676 3677 /** 3678 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap 3679 */ 3680 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 3681 { 3682 PDMDEV_ASSERT_DEVINS(pDevIns); 3683 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3684 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n", 3685 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys)); 3686 3687 int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys); 3688 3689 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 3690 return rc; 3691 } 3692 3693 3694 /** 3695 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 3696 */ 3697 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, 3698 const char *pszDesc, PRTRCPTR pRCPtr) 3699 { 3700 PDMDEV_ASSERT_DEVINS(pDevIns); 3701 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3702 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n", 3703 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr)); 3704 3705 int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, off, cb, pszDesc, pRCPtr); 3706 3707 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr)); 3708 return rc; 3709 } 3710 3711 3712 /** 3713 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap 3714 */ 3715 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 3716 { 3717 PDMDEV_ASSERT_DEVINS(pDevIns); 3718 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3719 3720 int rc = PDMR3RegisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys, pvHeap, cbSize); 3721 return rc; 3722 } 3723 3724 3725 /** 3726 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap 3727 */ 3728 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 3729 { 3730 PDMDEV_ASSERT_DEVINS(pDevIns); 3731 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 3732 3733 int rc = PDMR3UnregisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys); 3734 return rc; 3735 } 3736 3737 3738 3739 3740 3741 /** @copydoc PDMDEVHLPR3::pfnGetVM */ 3742 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns) 3743 { 3744 PDMDEV_ASSERT_DEVINS(pDevIns); 3745 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3746 return NULL; 3747 } 3748 3749 3750 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */ 3751 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3) 3752 { 3753 PDMDEV_ASSERT_DEVINS(pDevIns); 3754 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3755 NOREF(pPciBusReg); 3756 NOREF(ppPciHlpR3); 3757 return VERR_ACCESS_DENIED; 3758 } 3759 3760 3761 /** @copydoc PDMDEVHLPR3::pfnPICRegister */ 3762 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3) 3763 { 3764 PDMDEV_ASSERT_DEVINS(pDevIns); 3765 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3766 NOREF(pPicReg); 3767 NOREF(ppPicHlpR3); 3768 return VERR_ACCESS_DENIED; 3769 } 3770 3771 3772 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */ 3773 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3) 3774 { 3775 PDMDEV_ASSERT_DEVINS(pDevIns); 3776 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3777 NOREF(pApicReg); 3778 NOREF(ppApicHlpR3); 3779 return VERR_ACCESS_DENIED; 3780 } 3781 3782 3783 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */ 3784 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3) 3785 { 3786 PDMDEV_ASSERT_DEVINS(pDevIns); 3787 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3788 NOREF(pIoApicReg); 3789 NOREF(ppIoApicHlpR3); 3790 return VERR_ACCESS_DENIED; 3791 } 3792 3793 3794 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */ 3795 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp) 3796 { 3797 PDMDEV_ASSERT_DEVINS(pDevIns); 3798 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3799 NOREF(pDmacReg); 3800 NOREF(ppDmacHlp); 3801 return VERR_ACCESS_DENIED; 3802 } 3803 3804 3805 /** @copydoc PDMDEVHLPR3::pfnPhysRead */ 3806 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 3807 { 3808 PDMDEV_ASSERT_DEVINS(pDevIns); 3809 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3810 NOREF(GCPhys); 3811 NOREF(pvBuf); 3812 NOREF(cbRead); 3813 } 3814 3815 3816 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */ 3817 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 3818 { 3819 PDMDEV_ASSERT_DEVINS(pDevIns); 3820 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3821 NOREF(GCPhys); 3822 NOREF(pvBuf); 3823 NOREF(cbWrite); 3824 } 3825 3826 3827 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */ 3828 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb) 3829 { 3830 PDMDEV_ASSERT_DEVINS(pDevIns); 3831 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3832 NOREF(pvDst); 3833 NOREF(GCVirtSrc); 3834 NOREF(cb); 3835 return VERR_ACCESS_DENIED; 3836 } 3837 3838 3839 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */ 3840 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb) 3841 { 3842 PDMDEV_ASSERT_DEVINS(pDevIns); 3843 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3844 NOREF(GCVirtDst); 3845 NOREF(pvSrc); 3846 NOREF(cb); 3847 return VERR_ACCESS_DENIED; 3848 } 3849 3850 3851 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */ 3852 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc) 3853 { 3854 PDMDEV_ASSERT_DEVINS(pDevIns); 3855 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3856 NOREF(GCPhys); 3857 NOREF(cbRange); 3858 return VERR_ACCESS_DENIED; 3859 } 3860 3861 3862 /** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */ 3863 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC) 3864 { 3865 PDMDEV_ASSERT_DEVINS(pDevIns); 3866 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3867 NOREF(GCPhys); 3868 NOREF(cbRange); 3869 NOREF(ppvHC); 3870 return VERR_ACCESS_DENIED; 3871 } 3872 3873 3874 /** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */ 3875 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr) 3876 { 3877 PDMDEV_ASSERT_DEVINS(pDevIns); 3878 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3879 NOREF(GCPtr); 3880 NOREF(pHCPtr); 3881 return VERR_ACCESS_DENIED; 3882 } 3883 3884 3885 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */ 3886 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns) 3887 { 3888 PDMDEV_ASSERT_DEVINS(pDevIns); 3889 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3890 return false; 3891 } 3892 3893 3894 /** @copydoc PDMDEVHLPR3::pfnA20Set */ 3895 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable) 3896 { 3897 PDMDEV_ASSERT_DEVINS(pDevIns); 3898 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3899 NOREF(fEnable); 3900 } 3901 3902 3903 /** @copydoc PDMDEVHLPR3::pfnVMReset */ 3904 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns) 3905 { 3906 PDMDEV_ASSERT_DEVINS(pDevIns); 3907 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3908 return VERR_ACCESS_DENIED; 3909 } 3910 3911 3912 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */ 3913 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns) 3914 { 3915 PDMDEV_ASSERT_DEVINS(pDevIns); 3916 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3917 return VERR_ACCESS_DENIED; 3918 } 3919 3920 3921 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */ 3922 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns) 3923 { 3924 PDMDEV_ASSERT_DEVINS(pDevIns); 3925 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3926 return VERR_ACCESS_DENIED; 3927 } 3928 3929 3930 /** @copydoc PDMDEVHLPR3::pfnLockVM */ 3931 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns) 3932 { 3933 PDMDEV_ASSERT_DEVINS(pDevIns); 3934 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3935 return VERR_ACCESS_DENIED; 3936 } 3937 3938 3939 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */ 3940 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns) 3941 { 3942 PDMDEV_ASSERT_DEVINS(pDevIns); 3943 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3944 return VERR_ACCESS_DENIED; 3945 } 3946 3947 3948 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */ 3949 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction) 3950 { 3951 PDMDEV_ASSERT_DEVINS(pDevIns); 3952 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3953 return false; 3954 } 3955 3956 3957 /** @copydoc PDMDEVHLPR3::pfnDMARegister */ 3958 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 3959 { 3960 PDMDEV_ASSERT_DEVINS(pDevIns); 3961 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3962 return VERR_ACCESS_DENIED; 3963 } 3964 3965 3966 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */ 3967 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead) 3968 { 3969 PDMDEV_ASSERT_DEVINS(pDevIns); 3970 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3971 if (pcbRead) 3972 *pcbRead = 0; 3973 return VERR_ACCESS_DENIED; 3974 } 3975 3976 3977 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */ 3978 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten) 3979 { 3980 PDMDEV_ASSERT_DEVINS(pDevIns); 3981 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3982 if (pcbWritten) 3983 *pcbWritten = 0; 3984 return VERR_ACCESS_DENIED; 3985 } 3986 3987 3988 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */ 3989 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 3990 { 3991 PDMDEV_ASSERT_DEVINS(pDevIns); 3992 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 3993 return VERR_ACCESS_DENIED; 3994 } 3995 3996 3997 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */ 3998 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 3999 { 4000 PDMDEV_ASSERT_DEVINS(pDevIns); 4001 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4002 return 3 << 2 /* illegal mode type */; 4003 } 4004 4005 4006 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */ 4007 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns) 4008 { 4009 PDMDEV_ASSERT_DEVINS(pDevIns); 4010 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4011 } 4012 4013 4014 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */ 4015 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value) 4016 { 4017 PDMDEV_ASSERT_DEVINS(pDevIns); 4018 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4019 return VERR_ACCESS_DENIED; 4020 } 4021 4022 4023 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */ 4024 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value) 4025 { 4026 PDMDEV_ASSERT_DEVINS(pDevIns); 4027 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4028 return VERR_ACCESS_DENIED; 4029 } 4030 4031 4032 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */ 4033 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, 4034 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx) 4035 { 4036 PDMDEV_ASSERT_DEVINS(pDevIns); 4037 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4038 } 4039 4040 4041 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */ 4042 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange) 4043 { 4044 PDMDEV_ASSERT_DEVINS(pDevIns); 4045 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4046 return VERR_ACCESS_DENIED; 4047 } 4048 4049 4050 /** @copydoc PDMDEVHLPR3::pfnMMIO2Register */ 4051 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc) 4052 { 4053 PDMDEV_ASSERT_DEVINS(pDevIns); 4054 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4055 return VERR_ACCESS_DENIED; 4056 } 4057 4058 4059 /** @copydoc PDMDEVHLPR3::pfnMMIO2Deregister */ 4060 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion) 4061 { 4062 PDMDEV_ASSERT_DEVINS(pDevIns); 4063 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4064 return VERR_ACCESS_DENIED; 4065 } 4066 4067 4068 /** @copydoc PDMDEVHLPR3::pfnMMIO2Map */ 4069 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 4070 { 4071 PDMDEV_ASSERT_DEVINS(pDevIns); 4072 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4073 return VERR_ACCESS_DENIED; 4074 } 4075 4076 4077 /** @copydoc PDMDEVHLPR3::pfnMMIO2Unmap */ 4078 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys) 4079 { 4080 PDMDEV_ASSERT_DEVINS(pDevIns); 4081 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4082 return VERR_ACCESS_DENIED; 4083 } 4084 4085 4086 /** @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 */ 4087 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr) 4088 { 4089 PDMDEV_ASSERT_DEVINS(pDevIns); 4090 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4091 return VERR_ACCESS_DENIED; 4092 } 4093 4094 4095 /** @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap */ 4096 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize) 4097 { 4098 PDMDEV_ASSERT_DEVINS(pDevIns); 4099 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4100 return VERR_ACCESS_DENIED; 4101 } 4102 4103 4104 /** @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap */ 4105 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys) 4106 { 4107 PDMDEV_ASSERT_DEVINS(pDevIns); 4108 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 4109 return VERR_ACCESS_DENIED; 4110 } 4111 4112 4113 4114 4115 4116 /** @copydoc PDMPICHLPR3::pfnSetInterruptFF */ 4117 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns) 4118 { 4119 PDMDEV_ASSERT_DEVINS(pDevIns); 4120 PVM pVM = pDevIns->Internal.s.pVMR3; 4121 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n", 4122 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, 0, VM_FF_INTERRUPT_PIC))); 4123 /* for PIC we always deliver to CPU 0, MP use APIC */ 4124 VMCPU_FF_SET(pVM, 0, VM_FF_INTERRUPT_PIC); 4125 REMR3NotifyInterruptSet(pVM); 4126 VMR3NotifyFF(pVM, true); 4127 } 4128 4129 4130 /** @copydoc PDMPICHLPR3::pfnClearInterruptFF */ 4131 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns) 4132 { 4133 PDMDEV_ASSERT_DEVINS(pDevIns); 4134 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n", 4135 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC))); 4136 /* for PIC we always deliver to CPU 0, MP use APIC */ 4137 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC); 4138 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3); 4139 } 4140 4141 4142 /** @copydoc PDMPICHLPR3::pfnLock */ 4143 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc) 4144 { 4145 PDMDEV_ASSERT_DEVINS(pDevIns); 4146 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 4147 } 4148 4149 4150 /** @copydoc PDMPICHLPR3::pfnUnlock */ 4151 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns) 4152 { 4153 PDMDEV_ASSERT_DEVINS(pDevIns); 4154 pdmUnlock(pDevIns->Internal.s.pVMR3); 4155 } 4156 4157 4158 /** @copydoc PDMPICHLPR3::pfnGetRCHelpers */ 4159 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns) 4160 { 4161 PDMDEV_ASSERT_DEVINS(pDevIns); 4162 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4163 RTRCPTR pRCHelpers = 0; 4164 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers); 4165 AssertReleaseRC(rc); 4166 AssertRelease(pRCHelpers); 4167 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n", 4168 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers)); 4169 return pRCHelpers; 4170 } 4171 4172 4173 /** @copydoc PDMPICHLPR3::pfnGetR0Helpers */ 4174 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns) 4175 { 4176 PDMDEV_ASSERT_DEVINS(pDevIns); 4177 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 4178 PCPDMPICHLPR0 pR0Helpers = 0; 4179 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers); 4180 AssertReleaseRC(rc); 4181 AssertRelease(pR0Helpers); 4182 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n", 4183 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers)); 4184 return pR0Helpers; 4185 } 4186 132 /** @} */ 133 134 135 136 137 /** @name HC APIC Helpers 138 * @{ 139 */ 4187 140 4188 141 /** @copydoc PDMAPICHLPR3::pfnSetInterruptFF */ … … 4289 242 4290 243 244 /** 245 * APIC Device Helpers. 246 */ 247 const PDMAPICHLPR3 g_pdmR3DevApicHlp = 248 { 249 PDM_APICHLPR3_VERSION, 250 pdmR3ApicHlp_SetInterruptFF, 251 pdmR3ApicHlp_ClearInterruptFF, 252 pdmR3ApicHlp_ChangeFeature, 253 pdmR3ApicHlp_Lock, 254 pdmR3ApicHlp_Unlock, 255 pdmR3ApicHlp_GetCpuId, 256 pdmR3ApicHlp_GetRCHelpers, 257 pdmR3ApicHlp_GetR0Helpers, 258 PDM_APICHLPR3_VERSION /* the end */ 259 }; 260 261 /** @} */ 262 263 264 265 266 /** @name HC I/O APIC Helpers 267 * @{ 268 */ 269 4291 270 /** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */ 4292 271 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, … … 4348 327 4349 328 329 /** 330 * I/O APIC Device Helpers. 331 */ 332 const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp = 333 { 334 PDM_IOAPICHLPR3_VERSION, 335 pdmR3IoApicHlp_ApicBusDeliver, 336 pdmR3IoApicHlp_Lock, 337 pdmR3IoApicHlp_Unlock, 338 pdmR3IoApicHlp_GetRCHelpers, 339 pdmR3IoApicHlp_GetR0Helpers, 340 PDM_IOAPICHLPR3_VERSION /* the end */ 341 }; 342 343 /** @} */ 344 345 346 347 348 /** @name HC PCI Bus Helpers 349 * @{ 350 */ 351 4350 352 /** @copydoc PDMPCIHLPR3::pfnIsaSetIrq */ 4351 353 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) … … 4424 426 4425 427 /** 4426 * Locates a LUN. 4427 * 4428 * @returns VBox status code. 4429 * @param pVM VM Handle. 4430 * @param pszDevice Device name. 4431 * @param iInstance Device instance. 4432 * @param iLun The Logical Unit to obtain the interface of. 4433 * @param ppLun Where to store the pointer to the LUN if found. 4434 * @thread Try only do this in EMT... 4435 */ 4436 int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun) 4437 { 4438 /* 4439 * Iterate registered devices looking for the device. 4440 */ 4441 RTUINT cchDevice = strlen(pszDevice); 4442 for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext) 4443 { 4444 if ( pDev->cchName == cchDevice 4445 && !memcmp(pDev->pDevReg->szDeviceName, pszDevice, cchDevice)) 4446 { 4447 /* 4448 * Iterate device instances. 4449 */ 4450 for (PPDMDEVINS pDevIns = pDev->pInstances; pDevIns; pDevIns = pDevIns->Internal.s.pPerDeviceNextR3) 4451 { 4452 if (pDevIns->iInstance == iInstance) 4453 { 4454 /* 4455 * Iterate luns. 4456 */ 4457 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 4458 { 4459 if (pLun->iLun == iLun) 4460 { 4461 *ppLun = pLun; 4462 return VINF_SUCCESS; 4463 } 4464 } 4465 return VERR_PDM_LUN_NOT_FOUND; 4466 } 4467 } 4468 return VERR_PDM_DEVICE_INSTANCE_NOT_FOUND; 4469 } 4470 } 4471 return VERR_PDM_DEVICE_NOT_FOUND; 4472 } 4473 4474 4475 /** 4476 * Attaches a preconfigured driver to an existing device instance. 4477 * 4478 * This is used to change drivers and suchlike at runtime. 4479 * 4480 * @returns VBox status code. 4481 * @param pVM VM Handle. 4482 * @param pszDevice Device name. 4483 * @param iInstance Device instance. 4484 * @param iLun The Logical Unit to obtain the interface of. 4485 * @param ppBase Where to store the base interface pointer. Optional. 4486 * @thread EMT 4487 */ 4488 PDMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase) 4489 { 4490 VM_ASSERT_EMT(pVM); 4491 LogFlow(("PDMR3DeviceAttach: pszDevice=%p:{%s} iInstance=%d iLun=%d ppBase=%p\n", 4492 pszDevice, pszDevice, iInstance, iLun, ppBase)); 4493 4494 /* 4495 * Find the LUN in question. 4496 */ 4497 PPDMLUN pLun; 4498 int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun); 4499 if (VBOX_SUCCESS(rc)) 4500 { 4501 /* 4502 * Can we attach anything at runtime? 4503 */ 4504 PPDMDEVINS pDevIns = pLun->pDevIns; 4505 if (pDevIns->pDevReg->pfnAttach) 4506 { 4507 if (!pLun->pTop) 4508 { 4509 rc = pDevIns->pDevReg->pfnAttach(pDevIns, iLun); 4510 4511 } 4512 else 4513 rc = VERR_PDM_DRIVER_ALREADY_ATTACHED; 4514 } 4515 else 4516 rc = VERR_PDM_DEVICE_NO_RT_ATTACH; 4517 4518 if (ppBase) 4519 *ppBase = pLun->pTop ? &pLun->pTop->IBase : NULL; 4520 } 4521 else if (ppBase) 4522 *ppBase = NULL; 4523 4524 if (ppBase) 4525 LogFlow(("PDMR3DeviceAttach: returns %Vrc *ppBase=%p\n", rc, *ppBase)); 4526 else 4527 LogFlow(("PDMR3DeviceAttach: returns %Vrc\n", rc)); 4528 return rc; 4529 } 4530 4531 4532 /** 4533 * Detaches a driver chain from an existing device instance. 4534 * 4535 * This is used to change drivers and suchlike at runtime. 4536 * 4537 * @returns VBox status code. 4538 * @param pVM VM Handle. 4539 * @param pszDevice Device name. 4540 * @param iInstance Device instance. 4541 * @param iLun The Logical Unit to obtain the interface of. 4542 * @thread EMT 4543 */ 4544 PDMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun) 4545 { 4546 VM_ASSERT_EMT(pVM); 4547 LogFlow(("PDMR3DeviceDetach: pszDevice=%p:{%s} iInstance=%d iLun=%d\n", 4548 pszDevice, pszDevice, iInstance, iLun)); 4549 4550 /* 4551 * Find the LUN in question. 4552 */ 4553 PPDMLUN pLun; 4554 int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun); 4555 if (VBOX_SUCCESS(rc)) 4556 { 4557 /* 4558 * Can we detach anything at runtime? 4559 */ 4560 PPDMDEVINS pDevIns = pLun->pDevIns; 4561 if (pDevIns->pDevReg->pfnDetach) 4562 { 4563 if (pLun->pTop) 4564 rc = pdmR3DrvDetach(pLun->pTop); 4565 else 4566 rc = VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN; 4567 } 4568 else 4569 rc = VERR_PDM_DEVICE_NO_RT_DETACH; 4570 } 4571 4572 LogFlow(("PDMR3DeviceDetach: returns %Vrc\n", rc)); 4573 return rc; 4574 } 4575 428 * PCI Bus Device Helpers. 429 */ 430 const PDMPCIHLPR3 g_pdmR3DevPciHlp = 431 { 432 PDM_PCIHLPR3_VERSION, 433 pdmR3PciHlp_IsaSetIrq, 434 pdmR3PciHlp_IoApicSetIrq, 435 pdmR3PciHlp_IsMMIO2Base, 436 pdmR3PciHlp_GetRCHelpers, 437 pdmR3PciHlp_GetR0Helpers, 438 pdmR3PciHlp_Lock, 439 pdmR3PciHlp_Unlock, 440 PDM_PCIHLPR3_VERSION, /* the end */ 441 }; 442 443 /** @} */ 444 445 446 447 /* none yet */ 448 449 /** 450 * DMAC Device Helpers. 451 */ 452 const PDMDMACHLP g_pdmR3DevDmacHlp = 453 { 454 PDM_DMACHLP_VERSION 455 }; 456 457 458 459 460 /* none yet */ 461 462 /** 463 * RTC Device Helpers. 464 */ 465 const PDMRTCHLP g_pdmR3DevRtcHlp = 466 { 467 PDM_RTCHLP_VERSION 468 }; 469 470 -
trunk/src/VBox/VMM/PDMDevice.cpp
r12979 r12980 75 75 static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg); 76 76 static DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb); 77 static DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);78 79 /* VSlick regex:80 search : \om/\*\*.+?\*\/\nDECLCALLBACKMEMBER\(([^,]*), *pfn([^)]*)\)\(81 replace: \/\*\* @copydoc PDMDEVHLPR3::pfn\2 \*\/\nstatic DECLCALLBACK\(\1\) pdmR3DevHlp_\2\(82 */83 84 /** @name R3 DevHlp85 * @{86 */87 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc);88 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);89 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser, const char *pszOut, const char *pszIn, const char *pszOutStr, const char *pszInStr, const char *pszDesc);90 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts);91 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,92 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,93 const char *pszDesc);94 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,95 const char *pszWrite, const char *pszRead, const char *pszFill,96 const char *pszDesc);97 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,98 const char *pszWrite, const char *pszRead, const char *pszFill,99 const char *pszDesc);100 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);101 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);102 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,103 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,104 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);105 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);106 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc);107 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev);108 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback);109 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,110 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld);111 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);112 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);113 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);114 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);115 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc);116 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb);117 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb);118 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv);119 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);120 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);121 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);122 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);123 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);124 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);125 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args);126 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler);127 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc);128 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...);129 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args);130 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);131 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime);132 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,133 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);134 135 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns);136 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);137 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);138 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);139 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);140 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);141 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp);142 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue);143 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);144 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);145 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);146 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);147 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);148 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);149 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns);150 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);151 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable);152 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns);153 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns);154 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns);155 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns);156 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns);157 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);158 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);159 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);160 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);161 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);162 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);163 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns);164 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);165 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);166 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,167 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);168 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);169 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);170 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);171 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);172 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);173 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);174 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);175 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);176 177 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns);178 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);179 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);180 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);181 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);182 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);183 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);184 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);185 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);186 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);187 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);188 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC);189 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr);190 191 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns);192 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable);193 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns);194 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns);195 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns);196 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns);197 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns);198 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);199 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);200 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);201 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);202 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);203 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);204 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns);205 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);206 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);207 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,208 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);209 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);210 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);211 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);212 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);213 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);214 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);215 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);216 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys);217 /** @} */218 219 220 /** @name HC PIC Helpers221 * @{222 */223 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);224 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);225 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc);226 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns);227 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns);228 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns);229 /** @} */230 231 232 /** @name HC APIC Helpers233 * @{234 */235 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);236 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);237 static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);238 static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);239 static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns);240 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns);241 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);242 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);243 /** @} */244 245 246 /** @name HC I/O APIC Helpers247 * @{248 */249 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,250 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);251 static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);252 static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns);253 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);254 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);255 /** @} */256 257 258 /** @name HC PCI Bus Helpers259 * @{260 */261 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);262 static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);263 static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys);264 static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc);265 static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns);266 static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns);267 static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns);268 /** @} */269 270 /** @def PDMDEV_ASSERT_DEVINS271 * Asserts the validity of the device instance.272 */273 #ifdef VBOX_STRICT274 # define PDMDEV_ASSERT_DEVINS(pDevIns) \275 do { \276 AssertPtr(pDevIns); \277 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \278 Assert(pDevIns->pvInstanceDataR3 == (void *)&pDevIns->achInstanceData[0]); \279 } while (0)280 #else281 # define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)282 #endif283 77 284 78 static int pdmR3DevLoadModules(PVM pVM); … … 292 86 293 87 __END_DECLS 294 295 /*******************************************************************************296 * Global Variables *297 *******************************************************************************/298 /**299 * The device helper structure for trusted devices.300 */301 const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =302 {303 PDM_DEVHLP_VERSION,304 pdmR3DevHlp_IOPortRegister,305 pdmR3DevHlp_IOPortRegisterGC,306 pdmR3DevHlp_IOPortRegisterR0,307 pdmR3DevHlp_IOPortDeregister,308 pdmR3DevHlp_MMIORegister,309 pdmR3DevHlp_MMIORegisterGC,310 pdmR3DevHlp_MMIORegisterR0,311 pdmR3DevHlp_MMIODeregister,312 pdmR3DevHlp_ROMRegister,313 pdmR3DevHlp_SSMRegister,314 pdmR3DevHlp_TMTimerCreate,315 pdmR3DevHlp_TMTimerCreateExternal,316 pdmR3DevHlp_PCIRegister,317 pdmR3DevHlp_PCIIORegionRegister,318 pdmR3DevHlp_PCISetConfigCallbacks,319 pdmR3DevHlp_PCISetIrq,320 pdmR3DevHlp_PCISetIrqNoWait,321 pdmR3DevHlp_ISASetIrq,322 pdmR3DevHlp_ISASetIrqNoWait,323 pdmR3DevHlp_DriverAttach,324 pdmR3DevHlp_MMHeapAlloc,325 pdmR3DevHlp_MMHeapAllocZ,326 pdmR3DevHlp_MMHeapFree,327 pdmR3DevHlp_VMSetError,328 pdmR3DevHlp_VMSetErrorV,329 pdmR3DevHlp_VMSetRuntimeError,330 pdmR3DevHlp_VMSetRuntimeErrorV,331 pdmR3DevHlp_AssertEMT,332 pdmR3DevHlp_AssertOther,333 pdmR3DevHlp_DBGFStopV,334 pdmR3DevHlp_DBGFInfoRegister,335 pdmR3DevHlp_STAMRegister,336 pdmR3DevHlp_STAMRegisterF,337 pdmR3DevHlp_STAMRegisterV,338 pdmR3DevHlp_RTCRegister,339 pdmR3DevHlp_PDMQueueCreate,340 pdmR3DevHlp_CritSectInit,341 pdmR3DevHlp_UTCNow,342 pdmR3DevHlp_PDMThreadCreate,343 pdmR3DevHlp_PhysGCPtr2GCPhys,344 pdmR3DevHlp_VMState,345 0,346 0,347 0,348 0,349 0,350 0,351 0,352 pdmR3DevHlp_GetVM,353 pdmR3DevHlp_PCIBusRegister,354 pdmR3DevHlp_PICRegister,355 pdmR3DevHlp_APICRegister,356 pdmR3DevHlp_IOAPICRegister,357 pdmR3DevHlp_DMACRegister,358 pdmR3DevHlp_PhysRead,359 pdmR3DevHlp_PhysWrite,360 pdmR3DevHlp_PhysReadGCVirt,361 pdmR3DevHlp_PhysWriteGCVirt,362 pdmR3DevHlp_PhysReserve,363 pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt,364 pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr,365 pdmR3DevHlp_A20IsEnabled,366 pdmR3DevHlp_A20Set,367 pdmR3DevHlp_VMReset,368 pdmR3DevHlp_VMSuspend,369 pdmR3DevHlp_VMPowerOff,370 pdmR3DevHlp_LockVM,371 pdmR3DevHlp_UnlockVM,372 pdmR3DevHlp_AssertVMLock,373 pdmR3DevHlp_DMARegister,374 pdmR3DevHlp_DMAReadMemory,375 pdmR3DevHlp_DMAWriteMemory,376 pdmR3DevHlp_DMASetDREQ,377 pdmR3DevHlp_DMAGetChannelMode,378 pdmR3DevHlp_DMASchedule,379 pdmR3DevHlp_CMOSWrite,380 pdmR3DevHlp_CMOSRead,381 pdmR3DevHlp_GetCpuId,382 pdmR3DevHlp_ROMProtectShadow,383 pdmR3DevHlp_MMIO2Register,384 pdmR3DevHlp_MMIO2Deregister,385 pdmR3DevHlp_MMIO2Map,386 pdmR3DevHlp_MMIO2Unmap,387 pdmR3DevHlp_MMHyperMapMMIO2,388 pdmR3DevHlp_RegisterVMMDevHeap,389 pdmR3DevHlp_UnregisterVMMDevHeap,390 PDM_DEVHLP_VERSION /* the end */391 };392 393 394 /**395 * The device helper structure for non-trusted devices.396 */397 const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =398 {399 PDM_DEVHLP_VERSION,400 pdmR3DevHlp_IOPortRegister,401 pdmR3DevHlp_IOPortRegisterGC,402 pdmR3DevHlp_IOPortRegisterR0,403 pdmR3DevHlp_IOPortDeregister,404 pdmR3DevHlp_MMIORegister,405 pdmR3DevHlp_MMIORegisterGC,406 pdmR3DevHlp_MMIORegisterR0,407 pdmR3DevHlp_MMIODeregister,408 pdmR3DevHlp_ROMRegister,409 pdmR3DevHlp_SSMRegister,410 pdmR3DevHlp_TMTimerCreate,411 pdmR3DevHlp_TMTimerCreateExternal,412 pdmR3DevHlp_PCIRegister,413 pdmR3DevHlp_PCIIORegionRegister,414 pdmR3DevHlp_PCISetConfigCallbacks,415 pdmR3DevHlp_PCISetIrq,416 pdmR3DevHlp_PCISetIrqNoWait,417 pdmR3DevHlp_ISASetIrq,418 pdmR3DevHlp_ISASetIrqNoWait,419 pdmR3DevHlp_DriverAttach,420 pdmR3DevHlp_MMHeapAlloc,421 pdmR3DevHlp_MMHeapAllocZ,422 pdmR3DevHlp_MMHeapFree,423 pdmR3DevHlp_VMSetError,424 pdmR3DevHlp_VMSetErrorV,425 pdmR3DevHlp_VMSetRuntimeError,426 pdmR3DevHlp_VMSetRuntimeErrorV,427 pdmR3DevHlp_AssertEMT,428 pdmR3DevHlp_AssertOther,429 pdmR3DevHlp_DBGFStopV,430 pdmR3DevHlp_DBGFInfoRegister,431 pdmR3DevHlp_STAMRegister,432 pdmR3DevHlp_STAMRegisterF,433 pdmR3DevHlp_STAMRegisterV,434 pdmR3DevHlp_RTCRegister,435 pdmR3DevHlp_PDMQueueCreate,436 pdmR3DevHlp_CritSectInit,437 pdmR3DevHlp_UTCNow,438 pdmR3DevHlp_PDMThreadCreate,439 pdmR3DevHlp_PhysGCPtr2GCPhys,440 pdmR3DevHlp_VMState,441 0,442 0,443 0,444 0,445 0,446 0,447 0,448 pdmR3DevHlp_Untrusted_GetVM,449 pdmR3DevHlp_Untrusted_PCIBusRegister,450 pdmR3DevHlp_Untrusted_PICRegister,451 pdmR3DevHlp_Untrusted_APICRegister,452 pdmR3DevHlp_Untrusted_IOAPICRegister,453 pdmR3DevHlp_Untrusted_DMACRegister,454 pdmR3DevHlp_Untrusted_PhysRead,455 pdmR3DevHlp_Untrusted_PhysWrite,456 pdmR3DevHlp_Untrusted_PhysReadGCVirt,457 pdmR3DevHlp_Untrusted_PhysWriteGCVirt,458 pdmR3DevHlp_Untrusted_PhysReserve,459 pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt,460 pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr,461 pdmR3DevHlp_Untrusted_A20IsEnabled,462 pdmR3DevHlp_Untrusted_A20Set,463 pdmR3DevHlp_Untrusted_VMReset,464 pdmR3DevHlp_Untrusted_VMSuspend,465 pdmR3DevHlp_Untrusted_VMPowerOff,466 pdmR3DevHlp_Untrusted_LockVM,467 pdmR3DevHlp_Untrusted_UnlockVM,468 pdmR3DevHlp_Untrusted_AssertVMLock,469 pdmR3DevHlp_Untrusted_DMARegister,470 pdmR3DevHlp_Untrusted_DMAReadMemory,471 pdmR3DevHlp_Untrusted_DMAWriteMemory,472 pdmR3DevHlp_Untrusted_DMASetDREQ,473 pdmR3DevHlp_Untrusted_DMAGetChannelMode,474 pdmR3DevHlp_Untrusted_DMASchedule,475 pdmR3DevHlp_Untrusted_CMOSWrite,476 pdmR3DevHlp_Untrusted_CMOSRead,477 pdmR3DevHlp_Untrusted_GetCpuId,478 pdmR3DevHlp_Untrusted_ROMProtectShadow,479 pdmR3DevHlp_Untrusted_MMIO2Register,480 pdmR3DevHlp_Untrusted_MMIO2Deregister,481 pdmR3DevHlp_Untrusted_MMIO2Map,482 pdmR3DevHlp_Untrusted_MMIO2Unmap,483 pdmR3DevHlp_Untrusted_MMHyperMapMMIO2,484 pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,485 pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap,486 PDM_DEVHLP_VERSION /* the end */487 };488 489 490 /**491 * PIC Device Helpers.492 */493 const PDMPICHLPR3 g_pdmR3DevPicHlp =494 {495 PDM_PICHLPR3_VERSION,496 pdmR3PicHlp_SetInterruptFF,497 pdmR3PicHlp_ClearInterruptFF,498 pdmR3PicHlp_Lock,499 pdmR3PicHlp_Unlock,500 pdmR3PicHlp_GetRCHelpers,501 pdmR3PicHlp_GetR0Helpers,502 PDM_PICHLPR3_VERSION /* the end */503 };504 505 506 /**507 * APIC Device Helpers.508 */509 const PDMAPICHLPR3 g_pdmR3DevApicHlp =510 {511 PDM_APICHLPR3_VERSION,512 pdmR3ApicHlp_SetInterruptFF,513 pdmR3ApicHlp_ClearInterruptFF,514 pdmR3ApicHlp_ChangeFeature,515 pdmR3ApicHlp_Lock,516 pdmR3ApicHlp_Unlock,517 pdmR3ApicHlp_GetCpuId,518 pdmR3ApicHlp_GetRCHelpers,519 pdmR3ApicHlp_GetR0Helpers,520 PDM_APICHLPR3_VERSION /* the end */521 };522 523 524 /**525 * I/O APIC Device Helpers.526 */527 const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =528 {529 PDM_IOAPICHLPR3_VERSION,530 pdmR3IoApicHlp_ApicBusDeliver,531 pdmR3IoApicHlp_Lock,532 pdmR3IoApicHlp_Unlock,533 pdmR3IoApicHlp_GetRCHelpers,534 pdmR3IoApicHlp_GetR0Helpers,535 PDM_IOAPICHLPR3_VERSION /* the end */536 };537 538 539 /**540 * PCI Bus Device Helpers.541 */542 const PDMPCIHLPR3 g_pdmR3DevPciHlp =543 {544 PDM_PCIHLPR3_VERSION,545 pdmR3PciHlp_IsaSetIrq,546 pdmR3PciHlp_IoApicSetIrq,547 pdmR3PciHlp_IsMMIO2Base,548 pdmR3PciHlp_GetRCHelpers,549 pdmR3PciHlp_GetR0Helpers,550 pdmR3PciHlp_Lock,551 pdmR3PciHlp_Unlock,552 PDM_PCIHLPR3_VERSION, /* the end */553 };554 555 556 /**557 * DMAC Device Helpers.558 */559 const PDMDMACHLP g_pdmR3DevDmacHlp =560 {561 PDM_DMACHLP_VERSION562 };563 564 565 /**566 * RTC Device Helpers.567 */568 const PDMRTCHLP g_pdmR3DevRtcHlp =569 {570 PDM_RTCHLP_VERSION571 };572 88 573 89 … … 1215 731 1216 732 1217 1218 1219 1220 /*1221 *1222 *1223 *1224 *1225 * p d m R 3 D e v H l p1226 * p d m R 3 D e v H l p1227 * p d m R 3 D e v H l p1228 *1229 *1230 *1231 *1232 */1233 1234 1235 /**1236 * Queue consumer callback for internal component.1237 *1238 * @returns Success indicator.1239 * If false the item will not be removed and the flushing will stop.1240 * @param pVM The VM handle.1241 * @param pItem The item to consume. Upon return this item will be freed.1242 */1243 static DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)1244 {1245 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;1246 LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsHC));1247 switch (pTask->enmOp)1248 {1249 case PDMDEVHLPTASKOP_ISA_SET_IRQ:1250 PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);1251 break;1252 1253 case PDMDEVHLPTASKOP_PCI_SET_IRQ:1254 pdmR3DevHlp_PCISetIrq(pTask->pDevInsHC, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);1255 break;1256 1257 case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:1258 PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);1259 break;1260 1261 default:1262 AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));1263 break;1264 }1265 return true;1266 }1267 1268 1269 /** @copydoc PDMDEVHLPR3::pfnIOPortRegister */1270 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,1271 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)1272 {1273 PDMDEV_ASSERT_DEVINS(pDevIns);1274 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,1275 Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc));1276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1277 1278 int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);1279 1280 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1281 return rc;1282 }1283 1284 1285 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterGC */1286 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,1287 const char *pszOut, const char *pszIn,1288 const char *pszOutStr, const char *pszInStr, const char *pszDesc)1289 {1290 PDMDEV_ASSERT_DEVINS(pDevIns);1291 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1292 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,1293 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));1294 1295 /*1296 * Resolve the functions (one of the can be NULL).1297 */1298 int rc = VINF_SUCCESS;1299 if ( pDevIns->pDevReg->szRCMod[0]1300 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))1301 {1302 RTGCPTR32 GCPtrIn = 0;1303 if (pszIn)1304 {1305 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszIn, &GCPtrIn);1306 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szRCMod, pszIn));1307 }1308 RTGCPTR32 GCPtrOut = 0;1309 if (pszOut && VBOX_SUCCESS(rc))1310 {1311 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOut, &GCPtrOut);1312 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szRCMod, pszOut));1313 }1314 RTGCPTR32 GCPtrInStr = 0;1315 if (pszInStr && VBOX_SUCCESS(rc))1316 {1317 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszInStr, &GCPtrInStr);1318 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szRCMod, pszInStr));1319 }1320 RTGCPTR32 GCPtrOutStr = 0;1321 if (pszOutStr && VBOX_SUCCESS(rc))1322 {1323 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOutStr, &GCPtrOutStr);1324 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szRCMod, pszOutStr));1325 }1326 1327 if (VBOX_SUCCESS(rc))1328 rc = IOMR3IOPortRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc);1329 }1330 else1331 {1332 AssertMsgFailed(("No GC module for this driver!\n"));1333 rc = VERR_INVALID_PARAMETER;1334 }1335 1336 LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1337 return rc;1338 }1339 1340 1341 /** @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0 */1342 static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,1343 const char *pszOut, const char *pszIn,1344 const char *pszOutStr, const char *pszInStr, const char *pszDesc)1345 {1346 PDMDEV_ASSERT_DEVINS(pDevIns);1347 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1348 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,1349 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));1350 1351 /*1352 * Resolve the functions (one of the can be NULL).1353 */1354 int rc = VINF_SUCCESS;1355 if ( pDevIns->pDevReg->szR0Mod[0]1356 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))1357 {1358 R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0;1359 if (pszIn)1360 {1361 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn);1362 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn));1363 }1364 R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0;1365 if (pszOut && VBOX_SUCCESS(rc))1366 {1367 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut);1368 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut));1369 }1370 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0;1371 if (pszInStr && VBOX_SUCCESS(rc))1372 {1373 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr);1374 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr));1375 }1376 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0;1377 if (pszOutStr && VBOX_SUCCESS(rc))1378 {1379 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr);1380 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr));1381 }1382 1383 if (VBOX_SUCCESS(rc))1384 rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc);1385 }1386 else1387 {1388 AssertMsgFailed(("No R0 module for this driver!\n"));1389 rc = VERR_INVALID_PARAMETER;1390 }1391 1392 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1393 return rc;1394 }1395 1396 1397 /** @copydoc PDMDEVHLPR3::pfnIOPortDeregister */1398 static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts)1399 {1400 PDMDEV_ASSERT_DEVINS(pDevIns);1401 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1402 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,1403 Port, cPorts));1404 1405 int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts);1406 1407 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1408 return rc;1409 }1410 1411 1412 /** @copydoc PDMDEVHLPR3::pfnMMIORegister */1413 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,1414 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,1415 const char *pszDesc)1416 {1417 PDMDEV_ASSERT_DEVINS(pDevIns);1418 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1419 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n",1420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc));1421 1422 int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);1423 1424 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1425 return rc;1426 }1427 1428 1429 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterGC */1430 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,1431 const char *pszWrite, const char *pszRead, const char *pszFill,1432 const char *pszDesc)1433 {1434 PDMDEV_ASSERT_DEVINS(pDevIns);1435 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1436 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",1437 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));1438 1439 /*1440 * Resolve the functions.1441 * Not all function have to present, leave it to IOM to enforce this.1442 */1443 int rc = VINF_SUCCESS;1444 if ( pDevIns->pDevReg->szRCMod[0]1445 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))1446 {1447 RTGCPTR32 GCPtrWrite = 0;1448 if (pszWrite)1449 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszWrite, &GCPtrWrite);1450 RTGCPTR32 GCPtrRead = 0;1451 int rc2 = VINF_SUCCESS;1452 if (pszRead)1453 rc2 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszRead, &GCPtrRead);1454 RTGCPTR32 GCPtrFill = 0;1455 int rc3 = VINF_SUCCESS;1456 if (pszFill)1457 rc3 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszFill, &GCPtrFill);1458 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))1459 rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill);1460 else1461 {1462 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szRCMod, pszWrite));1463 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szRCMod, pszRead));1464 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szRCMod, pszFill));1465 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))1466 rc = rc2;1467 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))1468 rc = rc3;1469 }1470 }1471 else1472 {1473 AssertMsgFailed(("No GC module for this driver!\n"));1474 rc = VERR_INVALID_PARAMETER;1475 }1476 1477 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1478 return rc;1479 }1480 1481 /** @copydoc PDMDEVHLPR3::pfnMMIORegisterR0 */1482 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,1483 const char *pszWrite, const char *pszRead, const char *pszFill,1484 const char *pszDesc)1485 {1486 PDMDEV_ASSERT_DEVINS(pDevIns);1487 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1488 LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",1489 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));1490 1491 /*1492 * Resolve the functions.1493 * Not all function have to present, leave it to IOM to enforce this.1494 */1495 int rc = VINF_SUCCESS;1496 if ( pDevIns->pDevReg->szR0Mod[0]1497 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))1498 {1499 R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0;1500 if (pszWrite)1501 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite);1502 R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0;1503 int rc2 = VINF_SUCCESS;1504 if (pszRead)1505 rc2 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead);1506 R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0;1507 int rc3 = VINF_SUCCESS;1508 if (pszFill)1509 rc3 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill);1510 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))1511 rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);1512 else1513 {1514 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite));1515 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead));1516 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill));1517 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))1518 rc = rc2;1519 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))1520 rc = rc3;1521 }1522 }1523 else1524 {1525 AssertMsgFailed(("No R0 module for this driver!\n"));1526 rc = VERR_INVALID_PARAMETER;1527 }1528 1529 LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1530 return rc;1531 }1532 1533 1534 /** @copydoc PDMDEVHLPR3::pfnMMIODeregister */1535 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)1536 {1537 PDMDEV_ASSERT_DEVINS(pDevIns);1538 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1539 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",1540 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));1541 1542 int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange);1543 1544 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1545 return rc;1546 }1547 1548 1549 /** @copydoc PDMDEVHLPR3::pfnROMRegister */1550 static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)1551 {1552 PDMDEV_ASSERT_DEVINS(pDevIns);1553 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1554 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n",1555 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc));1556 1557 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc);1558 1559 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1560 return rc;1561 }1562 1563 1564 /** @copydoc PDMDEVHLPR3::pfnSSMRegister */1565 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,1566 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,1567 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)1568 {1569 PDMDEV_ASSERT_DEVINS(pDevIns);1570 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1571 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n",1572 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));1573 1574 int rc = SSMR3Register(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess,1575 pfnSavePrep, pfnSaveExec, pfnSaveDone,1576 pfnLoadPrep, pfnLoadExec, pfnLoadDone);1577 1578 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1579 return rc;1580 }1581 1582 1583 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */1584 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)1585 {1586 PDMDEV_ASSERT_DEVINS(pDevIns);1587 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1588 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n",1589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer));1590 1591 int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);1592 1593 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1594 return rc;1595 }1596 1597 1598 /** @copydoc PDMDEVHLPR3::pfnTMTimerCreateExternal */1599 static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc)1600 {1601 PDMDEV_ASSERT_DEVINS(pDevIns);1602 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);1603 1604 return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMR3, enmClock, pfnCallback, pvUser, pszDesc);1605 }1606 1607 /** @copydoc PDMDEVHLPR3::pfnPCIRegister */1608 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)1609 {1610 PDMDEV_ASSERT_DEVINS(pDevIns);1611 PVM pVM = pDevIns->Internal.s.pVMR3;1612 VM_ASSERT_EMT(pVM);1613 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n",1614 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config));1615 1616 /*1617 * Validate input.1618 */1619 if (!pPciDev)1620 {1621 Assert(pPciDev);1622 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));1623 return VERR_INVALID_PARAMETER;1624 }1625 if (!pPciDev->config[0] && !pPciDev->config[1])1626 {1627 Assert(pPciDev->config[0] || pPciDev->config[1]);1628 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));1629 return VERR_INVALID_PARAMETER;1630 }1631 if (pDevIns->Internal.s.pPciDeviceR3)1632 {1633 /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to1634 * support a PDM device with multiple PCI devices. This might become a problem1635 * when upgrading the chipset for instance...1636 */1637 AssertMsgFailed(("Only one PCI device per device is currently implemented!\n"));1638 return VERR_INTERNAL_ERROR;1639 }1640 1641 /*1642 * Choose the PCI bus for the device.1643 * This is simple. If the device was configured for a particular bus, it'll1644 * already have one. If not, we'll just take the first one.1645 */1646 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;1647 if (!pBus)1648 pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[0];1649 int rc;1650 if (pBus)1651 {1652 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)1653 pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3);1654 else1655 pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR;1656 1657 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)1658 pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3);1659 else1660 pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR;1661 1662 /*1663 * Check the configuration for PCI device and function assignment.1664 */1665 int iDev = -1;1666 uint8_t u8Device;1667 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device);1668 if (VBOX_SUCCESS(rc))1669 {1670 if (u8Device > 31)1671 {1672 AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n",1673 u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1674 return VERR_INTERNAL_ERROR;1675 }1676 1677 uint8_t u8Function;1678 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function);1679 if (VBOX_FAILURE(rc))1680 {1681 AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n",1682 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1683 return rc;1684 }1685 if (u8Function > 7)1686 {1687 AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n",1688 u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1689 return VERR_INTERNAL_ERROR;1690 }1691 iDev = (u8Device << 3) | u8Function;1692 }1693 else if (rc != VERR_CFGM_VALUE_NOT_FOUND)1694 {1695 AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n",1696 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1697 return rc;1698 }1699 1700 /*1701 * Call the pci bus device to do the actual registration.1702 */1703 pdmLock(pVM);1704 rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev);1705 pdmUnlock(pVM);1706 if (VBOX_SUCCESS(rc))1707 {1708 pPciDev->pDevIns = pDevIns;1709 1710 pDevIns->Internal.s.pPciDeviceR3 = pPciDev;1711 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)1712 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev);1713 else1714 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR;1715 1716 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)1717 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev);1718 else1719 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR;1720 1721 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",1722 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus));1723 }1724 }1725 else1726 {1727 AssertMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n"));1728 rc = VERR_PDM_NO_PCI_BUS;1729 }1730 1731 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1732 return rc;1733 }1734 1735 1736 /** @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister */1737 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)1738 {1739 PDMDEV_ASSERT_DEVINS(pDevIns);1740 PVM pVM = pDevIns->Internal.s.pVMR3;1741 VM_ASSERT_EMT(pVM);1742 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n",1743 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback));1744 1745 /*1746 * Validate input.1747 */1748 if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS)1749 {1750 Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS);1751 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));1752 return VERR_INVALID_PARAMETER;1753 }1754 switch (enmType)1755 {1756 case PCI_ADDRESS_SPACE_MEM:1757 case PCI_ADDRESS_SPACE_IO:1758 case PCI_ADDRESS_SPACE_MEM_PREFETCH:1759 break;1760 default:1761 AssertMsgFailed(("enmType=%#x is unknown\n", enmType));1762 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));1763 return VERR_INVALID_PARAMETER;1764 }1765 if (!pfnCallback)1766 {1767 Assert(pfnCallback);1768 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));1769 return VERR_INVALID_PARAMETER;1770 }1771 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);1772 1773 /*1774 * Must have a PCI device registered!1775 */1776 int rc;1777 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;1778 if (pPciDev)1779 {1780 /*1781 * We're currently restricted to page aligned MMIO regions.1782 */1783 if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH)1784 && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE))1785 {1786 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n",1787 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE)));1788 cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE);1789 }1790 1791 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;1792 Assert(pBus);1793 pdmLock(pVM);1794 rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);1795 pdmUnlock(pVM);1796 }1797 else1798 {1799 AssertMsgFailed(("No PCI device registered!\n"));1800 rc = VERR_PDM_NOT_PCI_DEVICE;1801 }1802 1803 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));1804 return rc;1805 }1806 1807 1808 /** @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks */1809 static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,1810 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)1811 {1812 PDMDEV_ASSERT_DEVINS(pDevIns);1813 PVM pVM = pDevIns->Internal.s.pVMR3;1814 VM_ASSERT_EMT(pVM);1815 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n",1816 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld));1817 1818 /*1819 * Validate input and resolve defaults.1820 */1821 AssertPtr(pfnRead);1822 AssertPtr(pfnWrite);1823 AssertPtrNull(ppfnReadOld);1824 AssertPtrNull(ppfnWriteOld);1825 AssertPtrNull(pPciDev);1826 1827 if (!pPciDev)1828 pPciDev = pDevIns->Internal.s.pPciDeviceR3;1829 AssertReleaseMsg(pPciDev, ("You must register your device first!\n"));1830 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;1831 AssertRelease(pBus);1832 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);1833 1834 /*1835 * Do the job.1836 */1837 pdmLock(pVM);1838 pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);1839 pdmUnlock(pVM);1840 1841 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1842 }1843 1844 1845 /** @copydoc PDMDEVHLPR3::pfnPCISetIrq */1846 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)1847 {1848 PDMDEV_ASSERT_DEVINS(pDevIns);1849 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));1850 1851 /*1852 * Validate input.1853 */1854 /** @todo iIrq and iLevel checks. */1855 1856 /*1857 * Must have a PCI device registered!1858 */1859 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;1860 if (pPciDev)1861 {1862 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */1863 Assert(pBus);1864 PVM pVM = pDevIns->Internal.s.pVMR3;1865 pdmLock(pVM);1866 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel);1867 pdmUnlock(pVM);1868 }1869 else1870 AssertReleaseMsgFailed(("No PCI device registered!\n"));1871 1872 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1873 }1874 1875 1876 /** @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait */1877 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)1878 {1879 pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel);1880 }1881 1882 1883 /** @copydoc PDMDEVHLPR3::pfnISASetIrq */1884 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)1885 {1886 PDMDEV_ASSERT_DEVINS(pDevIns);1887 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));1888 1889 /*1890 * Validate input.1891 */1892 /** @todo iIrq and iLevel checks. */1893 1894 PVM pVM = pDevIns->Internal.s.pVMR3;1895 PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */1896 1897 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1898 }1899 1900 1901 /** @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait */1902 static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)1903 {1904 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);1905 }1906 1907 1908 /** @copydoc PDMDEVHLPR3::pfnDriverAttach */1909 static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)1910 {1911 PDMDEV_ASSERT_DEVINS(pDevIns);1912 PVM pVM = pDevIns->Internal.s.pVMR3;1913 VM_ASSERT_EMT(pVM);1914 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",1915 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));1916 1917 /*1918 * Lookup the LUN, it might already be registered.1919 */1920 PPDMLUN pLunPrev = NULL;1921 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3;1922 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)1923 if (pLun->iLun == iLun)1924 break;1925 1926 /*1927 * Create the LUN if if wasn't found, else check if driver is already attached to it.1928 */1929 if (!pLun)1930 {1931 if ( !pBaseInterface1932 || !pszDesc1933 || !*pszDesc)1934 {1935 Assert(pBaseInterface);1936 Assert(pszDesc || *pszDesc);1937 return VERR_INVALID_PARAMETER;1938 }1939 1940 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));1941 if (!pLun)1942 return VERR_NO_MEMORY;1943 1944 pLun->iLun = iLun;1945 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;1946 pLun->pTop = NULL;1947 pLun->pBottom = NULL;1948 pLun->pDevIns = pDevIns;1949 pLun->pszDesc = pszDesc;1950 pLun->pBase = pBaseInterface;1951 if (!pLunPrev)1952 pDevIns->Internal.s.pLunsR3 = pLun;1953 else1954 pLunPrev->pNext = pLun;1955 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",1956 iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1957 }1958 else if (pLun->pTop)1959 {1960 AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));1961 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));1962 return VERR_PDM_DRIVER_ALREADY_ATTACHED;1963 }1964 Assert(pLun->pBase == pBaseInterface);1965 1966 1967 /*1968 * Get the attached driver configuration.1969 */1970 int rc;1971 char szNode[48];1972 RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun);1973 PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode);1974 if (pNode)1975 {1976 char *pszName;1977 rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);1978 if (VBOX_SUCCESS(rc))1979 {1980 /*1981 * Find the driver.1982 */1983 PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName);1984 if (pDrv)1985 {1986 /* config node */1987 PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config");1988 if (!pConfigNode)1989 rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode);1990 if (VBOX_SUCCESS(rc))1991 {1992 CFGMR3SetRestrictedRoot(pConfigNode);1993 1994 /*1995 * Allocate the driver instance.1996 */1997 size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]);1998 cb = RT_ALIGN_Z(cb, 16);1999 PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb);2000 if (pNew)2001 {2002 /*2003 * Initialize the instance structure (declaration order).2004 */2005 pNew->u32Version = PDM_DRVINS_VERSION;2006 //pNew->Internal.s.pUp = NULL;2007 //pNew->Internal.s.pDown = NULL;2008 pNew->Internal.s.pLun = pLun;2009 pNew->Internal.s.pDrv = pDrv;2010 pNew->Internal.s.pVM = pVM;2011 //pNew->Internal.s.fDetaching = false;2012 pNew->Internal.s.pCfgHandle = pNode;2013 pNew->pDrvHlp = &g_pdmR3DrvHlp;2014 pNew->pDrvReg = pDrv->pDrvReg;2015 pNew->pCfgHandle = pConfigNode;2016 pNew->iInstance = pDrv->cInstances++;2017 pNew->pUpBase = pBaseInterface;2018 //pNew->pDownBase = NULL;2019 //pNew->IBase.pfnQueryInterface = NULL;2020 pNew->pvInstanceData = &pNew->achInstanceData[0];2021 2022 /*2023 * Link with LUN and call the constructor.2024 */2025 pLun->pTop = pLun->pBottom = pNew;2026 rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle);2027 if (VBOX_SUCCESS(rc))2028 {2029 MMR3HeapFree(pszName);2030 *ppBaseInterface = &pNew->IBase;2031 Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n",2032 pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));2033 LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));2034 /*2035 * Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS) */2036 return rc;2037 }2038 2039 /*2040 * Free the driver.2041 */2042 pLun->pTop = pLun->pBottom = NULL;2043 ASMMemFill32(pNew, cb, 0xdeadd0d0);2044 MMR3HeapFree(pNew);2045 pDrv->cInstances--;2046 }2047 else2048 {2049 AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName));2050 rc = VERR_NO_MEMORY;2051 }2052 }2053 else2054 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc));2055 }2056 else2057 {2058 AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName));2059 rc = VERR_PDM_DRIVER_NOT_FOUND;2060 }2061 MMR3HeapFree(pszName);2062 }2063 else2064 {2065 AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc));2066 if (rc == VERR_CFGM_VALUE_NOT_FOUND)2067 rc = VERR_PDM_CFG_MISSING_DRIVER_NAME;2068 }2069 }2070 else2071 rc = VERR_PDM_NO_ATTACHED_DRIVER;2072 2073 2074 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2075 return rc;2076 }2077 2078 2079 /** @copydoc PDMDEVHLPR3::pfnMMHeapAlloc */2080 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)2081 {2082 PDMDEV_ASSERT_DEVINS(pDevIns);2083 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));2084 2085 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);2086 2087 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));2088 return pv;2089 }2090 2091 2092 /** @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ */2093 static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)2094 {2095 PDMDEV_ASSERT_DEVINS(pDevIns);2096 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));2097 2098 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);2099 2100 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));2101 return pv;2102 }2103 2104 2105 /** @copydoc PDMDEVHLPR3::pfnMMHeapFree */2106 static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv)2107 {2108 PDMDEV_ASSERT_DEVINS(pDevIns);2109 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));2110 2111 MMR3HeapFree(pv);2112 2113 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));2114 }2115 2116 2117 /** @copydoc PDMDEVHLPR3::pfnVMSetError */2118 static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)2119 {2120 PDMDEV_ASSERT_DEVINS(pDevIns);2121 va_list args;2122 va_start(args, pszFormat);2123 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);2124 va_end(args);2125 return rc;2126 }2127 2128 2129 /** @copydoc PDMDEVHLPR3::pfnVMSetErrorV */2130 static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)2131 {2132 PDMDEV_ASSERT_DEVINS(pDevIns);2133 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);2134 return rc;2135 }2136 2137 2138 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError */2139 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)2140 {2141 PDMDEV_ASSERT_DEVINS(pDevIns);2142 va_list args;2143 va_start(args, pszFormat);2144 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, args);2145 va_end(args);2146 return rc;2147 }2148 2149 2150 /** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeErrorV */2151 static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va)2152 {2153 PDMDEV_ASSERT_DEVINS(pDevIns);2154 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, va);2155 return rc;2156 }2157 2158 2159 /** @copydoc PDMDEVHLPR3::pfnAssertEMT */2160 static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)2161 {2162 PDMDEV_ASSERT_DEVINS(pDevIns);2163 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3))2164 return true;2165 2166 char szMsg[100];2167 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);2168 AssertMsg1(szMsg, iLine, pszFile, pszFunction);2169 AssertBreakpoint();2170 return false;2171 }2172 2173 2174 /** @copydoc PDMDEVHLPR3::pfnAssertOther */2175 static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)2176 {2177 PDMDEV_ASSERT_DEVINS(pDevIns);2178 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3))2179 return true;2180 2181 char szMsg[100];2182 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);2183 AssertMsg1(szMsg, iLine, pszFile, pszFunction);2184 AssertBreakpoint();2185 return false;2186 }2187 2188 2189 /** @copydoc PDMDEVHLPR3::pfnDBGFStopV */2190 static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args)2191 {2192 PDMDEV_ASSERT_DEVINS(pDevIns);2193 #ifdef LOG_ENABLED2194 va_list va2;2195 va_copy(va2, args);2196 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n",2197 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2));2198 va_end(va2);2199 #endif2200 2201 PVM pVM = pDevIns->Internal.s.pVMR3;2202 VM_ASSERT_EMT(pVM);2203 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args);2204 2205 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2206 return rc;2207 }2208 2209 2210 /** @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister */2211 static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)2212 {2213 PDMDEV_ASSERT_DEVINS(pDevIns);2214 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",2215 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));2216 2217 PVM pVM = pDevIns->Internal.s.pVMR3;2218 VM_ASSERT_EMT(pVM);2219 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns);2220 2221 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2222 return rc;2223 }2224 2225 2226 /** @copydoc PDMDEVHLPR3::pfnSTAMRegister */2227 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)2228 {2229 PDMDEV_ASSERT_DEVINS(pDevIns);2230 PVM pVM = pDevIns->Internal.s.pVMR3;2231 VM_ASSERT_EMT(pVM);2232 2233 STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);2234 NOREF(pVM);2235 }2236 2237 2238 2239 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterF */2240 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,2241 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...)2242 {2243 PDMDEV_ASSERT_DEVINS(pDevIns);2244 PVM pVM = pDevIns->Internal.s.pVMR3;2245 VM_ASSERT_EMT(pVM);2246 2247 va_list args;2248 va_start(args, pszName);2249 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);2250 va_end(args);2251 AssertRC(rc);2252 2253 NOREF(pVM);2254 }2255 2256 2257 /** @copydoc PDMDEVHLPR3::pfnSTAMRegisterV */2258 static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,2259 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)2260 {2261 PDMDEV_ASSERT_DEVINS(pDevIns);2262 PVM pVM = pDevIns->Internal.s.pVMR3;2263 VM_ASSERT_EMT(pVM);2264 2265 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);2266 AssertRC(rc);2267 2268 NOREF(pVM);2269 }2270 2271 2272 /** @copydoc PDMDEVHLPR3::pfnRTCRegister */2273 static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)2274 {2275 PDMDEV_ASSERT_DEVINS(pDevIns);2276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);2277 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",2278 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,2279 pRtcReg->pfnWrite, ppRtcHlp));2280 2281 /*2282 * Validate input.2283 */2284 if (pRtcReg->u32Version != PDM_RTCREG_VERSION)2285 {2286 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,2287 PDM_RTCREG_VERSION));2288 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n",2289 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2290 return VERR_INVALID_PARAMETER;2291 }2292 if ( !pRtcReg->pfnWrite2293 || !pRtcReg->pfnRead)2294 {2295 Assert(pRtcReg->pfnWrite);2296 Assert(pRtcReg->pfnRead);2297 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",2298 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2299 return VERR_INVALID_PARAMETER;2300 }2301 2302 if (!ppRtcHlp)2303 {2304 Assert(ppRtcHlp);2305 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n",2306 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2307 return VERR_INVALID_PARAMETER;2308 }2309 2310 /*2311 * Only one DMA device.2312 */2313 PVM pVM = pDevIns->Internal.s.pVMR3;2314 if (pVM->pdm.s.pRtc)2315 {2316 AssertMsgFailed(("Only one RTC device is supported!\n"));2317 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",2318 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2319 return VERR_INVALID_PARAMETER;2320 }2321 2322 /*2323 * Allocate and initialize pci bus structure.2324 */2325 int rc = VINF_SUCCESS;2326 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc));2327 if (pRtc)2328 {2329 pRtc->pDevIns = pDevIns;2330 pRtc->Reg = *pRtcReg;2331 pVM->pdm.s.pRtc = pRtc;2332 2333 /* set the helper pointer. */2334 *ppRtcHlp = &g_pdmR3DevRtcHlp;2335 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",2336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));2337 }2338 else2339 rc = VERR_NO_MEMORY;2340 2341 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",2342 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2343 return rc;2344 }2345 2346 2347 /** @copydoc PDMDEVHLPR3::pfnPDMQueueCreate */2348 static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,2349 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue)2350 {2351 PDMDEV_ASSERT_DEVINS(pDevIns);2352 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n",2353 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue));2354 2355 PVM pVM = pDevIns->Internal.s.pVMR3;2356 VM_ASSERT_EMT(pVM);2357 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue);2358 2359 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue));2360 return rc;2361 }2362 2363 2364 /** @copydoc PDMDEVHLPR3::pfnCritSectInit */2365 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName)2366 {2367 PDMDEV_ASSERT_DEVINS(pDevIns);2368 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n",2369 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName));2370 2371 PVM pVM = pDevIns->Internal.s.pVMR3;2372 VM_ASSERT_EMT(pVM);2373 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName);2374 2375 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2376 return rc;2377 }2378 2379 2380 /** @copydoc PDMDEVHLPR3::pfnUTCNow */2381 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)2382 {2383 PDMDEV_ASSERT_DEVINS(pDevIns);2384 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n",2385 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime));2386 2387 pTime = TMR3UTCNow(pDevIns->Internal.s.pVMR3, pTime);2388 2389 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime)));2390 return pTime;2391 }2392 2393 2394 /** @copydoc PDMDEVHLPR3::pfnPDMThreadCreate */2395 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,2396 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)2397 {2398 PDMDEV_ASSERT_DEVINS(pDevIns);2399 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);2400 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",2401 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));2402 2403 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);2404 2405 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,2406 rc, *ppThread));2407 return rc;2408 }2409 2410 2411 /** @copydoc PDMDEVHLPR3::pfnGetVM */2412 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)2413 {2414 PDMDEV_ASSERT_DEVINS(pDevIns);2415 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));2416 return pDevIns->Internal.s.pVMR3;2417 }2418 2419 2420 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */2421 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)2422 {2423 PDMDEV_ASSERT_DEVINS(pDevIns);2424 PVM pVM = pDevIns->Internal.s.pVMR3;2425 VM_ASSERT_EMT(pVM);2426 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, "2427 ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n",2428 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,2429 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3,2430 pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3));2431 2432 /*2433 * Validate the structure.2434 */2435 if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION)2436 {2437 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION));2438 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2439 return VERR_INVALID_PARAMETER;2440 }2441 if ( !pPciBusReg->pfnRegisterR32442 || !pPciBusReg->pfnIORegionRegisterR32443 || !pPciBusReg->pfnSetIrqR32444 || !pPciBusReg->pfnSaveExecR32445 || !pPciBusReg->pfnLoadExecR32446 || !pPciBusReg->pfnFakePCIBIOSR3)2447 {2448 Assert(pPciBusReg->pfnRegisterR3);2449 Assert(pPciBusReg->pfnIORegionRegisterR3);2450 Assert(pPciBusReg->pfnSetIrqR3);2451 Assert(pPciBusReg->pfnSaveExecR3);2452 Assert(pPciBusReg->pfnLoadExecR3);2453 Assert(pPciBusReg->pfnFakePCIBIOSR3);2454 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2455 return VERR_INVALID_PARAMETER;2456 }2457 if ( pPciBusReg->pszSetIrqRC2458 && !VALID_PTR(pPciBusReg->pszSetIrqRC))2459 {2460 Assert(VALID_PTR(pPciBusReg->pszSetIrqRC));2461 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2462 return VERR_INVALID_PARAMETER;2463 }2464 if ( pPciBusReg->pszSetIrqR02465 && !VALID_PTR(pPciBusReg->pszSetIrqR0))2466 {2467 Assert(VALID_PTR(pPciBusReg->pszSetIrqR0));2468 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2469 return VERR_INVALID_PARAMETER;2470 }2471 if (!ppPciHlpR3)2472 {2473 Assert(ppPciHlpR3);2474 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2475 return VERR_INVALID_PARAMETER;2476 }2477 2478 /*2479 * Find free PCI bus entry.2480 */2481 unsigned iBus = 0;2482 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)2483 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)2484 break;2485 if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses))2486 {2487 AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)));2488 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2489 return VERR_INVALID_PARAMETER;2490 }2491 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];2492 2493 /*2494 * Resolve and init the RC bits.2495 */2496 if (pPciBusReg->pszSetIrqRC)2497 {2498 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC);2499 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, rc));2500 if (VBOX_FAILURE(rc))2501 {2502 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2503 return rc;2504 }2505 pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);2506 }2507 else2508 {2509 pPciBus->pfnSetIrqRC = 0;2510 pPciBus->pDevInsRC = 0;2511 }2512 2513 /*2514 * Resolve and init the R0 bits.2515 */2516 if (pPciBusReg->pszSetIrqR0)2517 {2518 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0);2519 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc));2520 if (VBOX_FAILURE(rc))2521 {2522 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2523 return rc;2524 }2525 pPciBus->pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);2526 }2527 else2528 {2529 pPciBus->pfnSetIrqR0 = 0;2530 pPciBus->pDevInsR0 = 0;2531 }2532 2533 /*2534 * Init the R3 bits.2535 */2536 pPciBus->iBus = iBus;2537 pPciBus->pDevInsR3 = pDevIns;2538 pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3;2539 pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3;2540 pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3;2541 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;2542 pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3;2543 pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3;2544 pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3;2545 2546 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));2547 2548 /* set the helper pointer and return. */2549 *ppPciHlpR3 = &g_pdmR3DevPciHlp;2550 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));2551 return VINF_SUCCESS;2552 }2553 2554 2555 /** @copydoc PDMDEVHLPR3::pfnPICRegister */2556 static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)2557 {2558 PDMDEV_ASSERT_DEVINS(pDevIns);2559 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);2560 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n",2561 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3,2562 pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC,2563 pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0,2564 ppPicHlpR3));2565 2566 /*2567 * Validate input.2568 */2569 if (pPicReg->u32Version != PDM_PICREG_VERSION)2570 {2571 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION));2572 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2573 return VERR_INVALID_PARAMETER;2574 }2575 if ( !pPicReg->pfnSetIrqR32576 || !pPicReg->pfnGetInterruptR3)2577 {2578 Assert(pPicReg->pfnSetIrqR3);2579 Assert(pPicReg->pfnGetInterruptR3);2580 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2581 return VERR_INVALID_PARAMETER;2582 }2583 if ( ( pPicReg->pszSetIrqRC2584 || pPicReg->pszGetInterruptRC)2585 && ( !VALID_PTR(pPicReg->pszSetIrqRC)2586 || !VALID_PTR(pPicReg->pszGetInterruptRC))2587 )2588 {2589 Assert(VALID_PTR(pPicReg->pszSetIrqRC));2590 Assert(VALID_PTR(pPicReg->pszGetInterruptRC));2591 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2592 return VERR_INVALID_PARAMETER;2593 }2594 if ( pPicReg->pszSetIrqRC2595 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))2596 {2597 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC);2598 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2599 return VERR_INVALID_PARAMETER;2600 }2601 if ( pPicReg->pszSetIrqR02602 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))2603 {2604 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0);2605 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2606 return VERR_INVALID_PARAMETER;2607 }2608 if (!ppPicHlpR3)2609 {2610 Assert(ppPicHlpR3);2611 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2612 return VERR_INVALID_PARAMETER;2613 }2614 2615 /*2616 * Only one PIC device.2617 */2618 PVM pVM = pDevIns->Internal.s.pVMR3;2619 if (pVM->pdm.s.Pic.pDevInsR3)2620 {2621 AssertMsgFailed(("Only one pic device is supported!\n"));2622 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2623 return VERR_INVALID_PARAMETER;2624 }2625 2626 /*2627 * RC stuff.2628 */2629 if (pPicReg->pszSetIrqRC)2630 {2631 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);2632 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, rc));2633 if (VBOX_SUCCESS(rc))2634 {2635 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC);2636 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, rc));2637 }2638 if (VBOX_FAILURE(rc))2639 {2640 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2641 return rc;2642 }2643 pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);2644 }2645 else2646 {2647 pVM->pdm.s.Pic.pDevInsRC = 0;2648 pVM->pdm.s.Pic.pfnSetIrqRC = 0;2649 pVM->pdm.s.Pic.pfnGetInterruptRC = 0;2650 }2651 2652 /*2653 * R0 stuff.2654 */2655 if (pPicReg->pszSetIrqR0)2656 {2657 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);2658 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc));2659 if (VBOX_SUCCESS(rc))2660 {2661 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0);2662 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc));2663 }2664 if (VBOX_FAILURE(rc))2665 {2666 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2667 return rc;2668 }2669 pVM->pdm.s.Pic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);2670 Assert(pVM->pdm.s.Pic.pDevInsR0);2671 }2672 else2673 {2674 pVM->pdm.s.Pic.pfnSetIrqR0 = 0;2675 pVM->pdm.s.Pic.pfnGetInterruptR0 = 0;2676 pVM->pdm.s.Pic.pDevInsR0 = 0;2677 }2678 2679 /*2680 * R3 stuff.2681 */2682 pVM->pdm.s.Pic.pDevInsR3 = pDevIns;2683 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3;2684 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3;2685 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));2686 2687 /* set the helper pointer and return. */2688 *ppPicHlpR3 = &g_pdmR3DevPicHlp;2689 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));2690 return VINF_SUCCESS;2691 }2692 2693 2694 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */2695 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)2696 {2697 PDMDEV_ASSERT_DEVINS(pDevIns);2698 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);2699 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "2700 ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "2701 ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",2702 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,2703 pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,2704 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,2705 pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC,2706 pApicReg->pszBusDeliverRC, ppApicHlpR3));2707 2708 /*2709 * Validate input.2710 */2711 if (pApicReg->u32Version != PDM_APICREG_VERSION)2712 {2713 AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION));2714 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2715 return VERR_INVALID_PARAMETER;2716 }2717 if ( !pApicReg->pfnGetInterruptR32718 || !pApicReg->pfnHasPendingIrqR32719 || !pApicReg->pfnSetBaseR32720 || !pApicReg->pfnGetBaseR32721 || !pApicReg->pfnSetTPRR32722 || !pApicReg->pfnGetTPRR32723 || !pApicReg->pfnBusDeliverR3)2724 {2725 Assert(pApicReg->pfnGetInterruptR3);2726 Assert(pApicReg->pfnHasPendingIrqR3);2727 Assert(pApicReg->pfnSetBaseR3);2728 Assert(pApicReg->pfnGetBaseR3);2729 Assert(pApicReg->pfnSetTPRR3);2730 Assert(pApicReg->pfnGetTPRR3);2731 Assert(pApicReg->pfnBusDeliverR3);2732 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2733 return VERR_INVALID_PARAMETER;2734 }2735 if ( ( pApicReg->pszGetInterruptRC2736 || pApicReg->pszHasPendingIrqRC2737 || pApicReg->pszSetBaseRC2738 || pApicReg->pszGetBaseRC2739 || pApicReg->pszSetTPRRC2740 || pApicReg->pszGetTPRRC2741 || pApicReg->pszBusDeliverRC)2742 && ( !VALID_PTR(pApicReg->pszGetInterruptRC)2743 || !VALID_PTR(pApicReg->pszHasPendingIrqRC)2744 || !VALID_PTR(pApicReg->pszSetBaseRC)2745 || !VALID_PTR(pApicReg->pszGetBaseRC)2746 || !VALID_PTR(pApicReg->pszSetTPRRC)2747 || !VALID_PTR(pApicReg->pszGetTPRRC)2748 || !VALID_PTR(pApicReg->pszBusDeliverRC))2749 )2750 {2751 Assert(VALID_PTR(pApicReg->pszGetInterruptRC));2752 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC));2753 Assert(VALID_PTR(pApicReg->pszSetBaseRC));2754 Assert(VALID_PTR(pApicReg->pszGetBaseRC));2755 Assert(VALID_PTR(pApicReg->pszSetTPRRC));2756 Assert(VALID_PTR(pApicReg->pszGetTPRRC));2757 Assert(VALID_PTR(pApicReg->pszBusDeliverRC));2758 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2759 return VERR_INVALID_PARAMETER;2760 }2761 if ( ( pApicReg->pszGetInterruptR02762 || pApicReg->pszHasPendingIrqR02763 || pApicReg->pszSetBaseR02764 || pApicReg->pszGetBaseR02765 || pApicReg->pszSetTPRR02766 || pApicReg->pszGetTPRR02767 || pApicReg->pszBusDeliverR0)2768 && ( !VALID_PTR(pApicReg->pszGetInterruptR0)2769 || !VALID_PTR(pApicReg->pszHasPendingIrqR0)2770 || !VALID_PTR(pApicReg->pszSetBaseR0)2771 || !VALID_PTR(pApicReg->pszGetBaseR0)2772 || !VALID_PTR(pApicReg->pszSetTPRR0)2773 || !VALID_PTR(pApicReg->pszGetTPRR0)2774 || !VALID_PTR(pApicReg->pszBusDeliverR0))2775 )2776 {2777 Assert(VALID_PTR(pApicReg->pszGetInterruptR0));2778 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0));2779 Assert(VALID_PTR(pApicReg->pszSetBaseR0));2780 Assert(VALID_PTR(pApicReg->pszGetBaseR0));2781 Assert(VALID_PTR(pApicReg->pszSetTPRR0));2782 Assert(VALID_PTR(pApicReg->pszGetTPRR0));2783 Assert(VALID_PTR(pApicReg->pszBusDeliverR0));2784 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2785 return VERR_INVALID_PARAMETER;2786 }2787 if (!ppApicHlpR3)2788 {2789 Assert(ppApicHlpR3);2790 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2791 return VERR_INVALID_PARAMETER;2792 }2793 2794 /*2795 * Only one APIC device. (malc: only in UP case actually)2796 */2797 PVM pVM = pDevIns->Internal.s.pVMR3;2798 if (pVM->pdm.s.Apic.pDevInsR3)2799 {2800 AssertMsgFailed(("Only one apic device is supported!\n"));2801 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2802 return VERR_INVALID_PARAMETER;2803 }2804 2805 /*2806 * Resolve & initialize the RC bits.2807 */2808 if (pApicReg->pszGetInterruptRC)2809 {2810 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC);2811 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, rc));2812 if (RT_SUCCESS(rc))2813 {2814 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC);2815 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc));2816 }2817 if (RT_SUCCESS(rc))2818 {2819 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC);2820 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, rc));2821 }2822 if (RT_SUCCESS(rc))2823 {2824 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC);2825 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, rc));2826 }2827 if (RT_SUCCESS(rc))2828 {2829 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC);2830 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, rc));2831 }2832 if (RT_SUCCESS(rc))2833 {2834 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC);2835 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc));2836 }2837 if (RT_SUCCESS(rc))2838 {2839 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);2840 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc));2841 }2842 if (VBOX_FAILURE(rc))2843 {2844 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2845 return rc;2846 }2847 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);2848 }2849 else2850 {2851 pVM->pdm.s.Apic.pDevInsRC = 0;2852 pVM->pdm.s.Apic.pfnGetInterruptRC = 0;2853 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0;2854 pVM->pdm.s.Apic.pfnSetBaseRC = 0;2855 pVM->pdm.s.Apic.pfnGetBaseRC = 0;2856 pVM->pdm.s.Apic.pfnSetTPRRC = 0;2857 pVM->pdm.s.Apic.pfnGetTPRRC = 0;2858 pVM->pdm.s.Apic.pfnBusDeliverRC = 0;2859 }2860 2861 /*2862 * Resolve & initialize the R0 bits.2863 */2864 if (pApicReg->pszGetInterruptR0)2865 {2866 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0);2867 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc));2868 if (RT_SUCCESS(rc))2869 {2870 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0);2871 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc));2872 }2873 if (RT_SUCCESS(rc))2874 {2875 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0);2876 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc));2877 }2878 if (RT_SUCCESS(rc))2879 {2880 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0);2881 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc));2882 }2883 if (RT_SUCCESS(rc))2884 {2885 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0);2886 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc));2887 }2888 if (RT_SUCCESS(rc))2889 {2890 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0);2891 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc));2892 }2893 if (RT_SUCCESS(rc))2894 {2895 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);2896 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));2897 }2898 if (VBOX_FAILURE(rc))2899 {2900 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));2901 return rc;2902 }2903 pVM->pdm.s.Apic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);2904 Assert(pVM->pdm.s.Apic.pDevInsR0);2905 }2906 else2907 {2908 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0;2909 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0;2910 pVM->pdm.s.Apic.pfnSetBaseR0 = 0;2911 pVM->pdm.s.Apic.pfnGetBaseR0 = 0;2912 pVM->pdm.s.Apic.pfnSetTPRR0 = 0;2913 pVM->pdm.s.Apic.pfnGetTPRR0 = 0;2914 pVM->pdm.s.Apic.pfnBusDeliverR0 = 0;2915 pVM->pdm.s.Apic.pDevInsR0 = 0;2916 }2917 2918 /*2919 * Initialize the HC bits.2920 */2921 pVM->pdm.s.Apic.pDevInsR3 = pDevIns;2922 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3;2923 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3;2924 pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3;2925 pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3;2926 pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3;2927 pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3;2928 pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3;2929 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));2930 2931 /* set the helper pointer and return. */2932 *ppApicHlpR3 = &g_pdmR3DevApicHlp;2933 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));2934 return VINF_SUCCESS;2935 }2936 2937 2938 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */2939 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)2940 {2941 PDMDEV_ASSERT_DEVINS(pDevIns);2942 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);2943 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n",2944 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3,2945 pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3));2946 2947 /*2948 * Validate input.2949 */2950 if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION)2951 {2952 AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION));2953 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2954 return VERR_INVALID_PARAMETER;2955 }2956 if (!pIoApicReg->pfnSetIrqR3)2957 {2958 Assert(pIoApicReg->pfnSetIrqR3);2959 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2960 return VERR_INVALID_PARAMETER;2961 }2962 if ( pIoApicReg->pszSetIrqRC2963 && !VALID_PTR(pIoApicReg->pszSetIrqRC))2964 {2965 Assert(VALID_PTR(pIoApicReg->pszSetIrqRC));2966 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2967 return VERR_INVALID_PARAMETER;2968 }2969 if ( pIoApicReg->pszSetIrqR02970 && !VALID_PTR(pIoApicReg->pszSetIrqR0))2971 {2972 Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));2973 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2974 return VERR_INVALID_PARAMETER;2975 }2976 if (!ppIoApicHlpR3)2977 {2978 Assert(ppIoApicHlpR3);2979 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2980 return VERR_INVALID_PARAMETER;2981 }2982 2983 /*2984 * The I/O APIC requires the APIC to be present (hacks++).2985 * If the I/O APIC does GC stuff so must the APIC.2986 */2987 PVM pVM = pDevIns->Internal.s.pVMR3;2988 if (!pVM->pdm.s.Apic.pDevInsR3)2989 {2990 AssertMsgFailed(("Configuration error / Init order error! No APIC!\n"));2991 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2992 return VERR_INVALID_PARAMETER;2993 }2994 if ( pIoApicReg->pszSetIrqRC2995 && !pVM->pdm.s.Apic.pDevInsRC)2996 {2997 AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n"));2998 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));2999 return VERR_INVALID_PARAMETER;3000 }3001 3002 /*3003 * Only one I/O APIC device.3004 */3005 if (pVM->pdm.s.IoApic.pDevInsR3)3006 {3007 AssertMsgFailed(("Only one ioapic device is supported!\n"));3008 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));3009 return VERR_INVALID_PARAMETER;3010 }3011 3012 /*3013 * Resolve & initialize the GC bits.3014 */3015 if (pIoApicReg->pszSetIrqRC)3016 {3017 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);3018 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, rc));3019 if (VBOX_FAILURE(rc))3020 {3021 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3022 return rc;3023 }3024 pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);3025 }3026 else3027 {3028 pVM->pdm.s.IoApic.pDevInsRC = 0;3029 pVM->pdm.s.IoApic.pfnSetIrqRC = 0;3030 }3031 3032 /*3033 * Resolve & initialize the R0 bits.3034 */3035 if (pIoApicReg->pszSetIrqR0)3036 {3037 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);3038 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc));3039 if (VBOX_FAILURE(rc))3040 {3041 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3042 return rc;3043 }3044 pVM->pdm.s.IoApic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);3045 Assert(pVM->pdm.s.IoApic.pDevInsR0);3046 }3047 else3048 {3049 pVM->pdm.s.IoApic.pfnSetIrqR0 = 0;3050 pVM->pdm.s.IoApic.pDevInsR0 = 0;3051 }3052 3053 /*3054 * Initialize the R3 bits.3055 */3056 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;3057 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3;3058 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));3059 3060 /* set the helper pointer and return. */3061 *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp;3062 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));3063 return VINF_SUCCESS;3064 }3065 3066 3067 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */3068 static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)3069 {3070 PDMDEV_ASSERT_DEVINS(pDevIns);3071 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3072 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n",3073 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,3074 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));3075 3076 /*3077 * Validate input.3078 */3079 if (pDmacReg->u32Version != PDM_DMACREG_VERSION)3080 {3081 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,3082 PDM_DMACREG_VERSION));3083 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n",3084 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));3085 return VERR_INVALID_PARAMETER;3086 }3087 if ( !pDmacReg->pfnRun3088 || !pDmacReg->pfnRegister3089 || !pDmacReg->pfnReadMemory3090 || !pDmacReg->pfnWriteMemory3091 || !pDmacReg->pfnSetDREQ3092 || !pDmacReg->pfnGetChannelMode)3093 {3094 Assert(pDmacReg->pfnRun);3095 Assert(pDmacReg->pfnRegister);3096 Assert(pDmacReg->pfnReadMemory);3097 Assert(pDmacReg->pfnWriteMemory);3098 Assert(pDmacReg->pfnSetDREQ);3099 Assert(pDmacReg->pfnGetChannelMode);3100 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",3101 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));3102 return VERR_INVALID_PARAMETER;3103 }3104 3105 if (!ppDmacHlp)3106 {3107 Assert(ppDmacHlp);3108 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n",3109 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));3110 return VERR_INVALID_PARAMETER;3111 }3112 3113 /*3114 * Only one DMA device.3115 */3116 PVM pVM = pDevIns->Internal.s.pVMR3;3117 if (pVM->pdm.s.pDmac)3118 {3119 AssertMsgFailed(("Only one DMA device is supported!\n"));3120 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",3121 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));3122 return VERR_INVALID_PARAMETER;3123 }3124 3125 /*3126 * Allocate and initialize pci bus structure.3127 */3128 int rc = VINF_SUCCESS;3129 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac));3130 if (pDmac)3131 {3132 pDmac->pDevIns = pDevIns;3133 pDmac->Reg = *pDmacReg;3134 pVM->pdm.s.pDmac = pDmac;3135 3136 /* set the helper pointer. */3137 *ppDmacHlp = &g_pdmR3DevDmacHlp;3138 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",3139 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));3140 }3141 else3142 rc = VERR_NO_MEMORY;3143 3144 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",3145 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3146 return rc;3147 }3148 3149 3150 /** @copydoc PDMDEVHLPR3::pfnPhysRead */3151 static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)3152 {3153 PDMDEV_ASSERT_DEVINS(pDevIns);3154 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",3155 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));3156 3157 /*3158 * For the convenience of the device we put no thread restriction on this interface.3159 * That means we'll have to check which thread we're in and choose our path.3160 */3161 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD3162 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);3163 #else3164 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3))3165 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);3166 else3167 {3168 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3169 PVMREQ pReq;3170 AssertCompileSize(RTGCPHYS, 4);3171 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,3172 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);3173 while (rc == VERR_TIMEOUT)3174 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);3175 AssertReleaseRC(rc);3176 VMR3ReqFree(pReq);3177 }3178 #endif3179 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3180 }3181 3182 3183 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */3184 static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)3185 {3186 PDMDEV_ASSERT_DEVINS(pDevIns);3187 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",3188 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));3189 3190 /*3191 * For the convenience of the device we put no thread restriction on this interface.3192 * That means we'll have to check which thread we're in and choose our path.3193 */3194 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD3195 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);3196 #else3197 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3))3198 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);3199 else3200 {3201 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3202 PVMREQ pReq;3203 AssertCompileSize(RTGCPHYS, 4);3204 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,3205 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);3206 while (rc == VERR_TIMEOUT)3207 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);3208 AssertReleaseRC(rc);3209 VMR3ReqFree(pReq);3210 }3211 #endif3212 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3213 }3214 3215 3216 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */3217 static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)3218 {3219 PDMDEV_ASSERT_DEVINS(pDevIns);3220 PVM pVM = pDevIns->Internal.s.pVMR3;3221 VM_ASSERT_EMT(pVM);3222 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n",3223 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb));3224 3225 if (!VM_IS_EMT(pVM))3226 return VERR_ACCESS_DENIED;3227 3228 int rc = PGMPhysReadGCPtr(pVM, pvDst, GCVirtSrc, cb);3229 3230 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3231 3232 return rc;3233 }3234 3235 3236 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */3237 static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)3238 {3239 PDMDEV_ASSERT_DEVINS(pDevIns);3240 PVM pVM = pDevIns->Internal.s.pVMR3;3241 VM_ASSERT_EMT(pVM);3242 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n",3243 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb));3244 3245 if (!VM_IS_EMT(pVM))3246 return VERR_ACCESS_DENIED;3247 3248 int rc = PGMPhysWriteGCPtr(pVM, GCVirtDst, pvSrc, cb);3249 3250 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3251 3252 return rc;3253 }3254 3255 3256 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */3257 static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)3258 {3259 PDMDEV_ASSERT_DEVINS(pDevIns);3260 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3261 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n",3262 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc));3263 3264 int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMR3, GCPhys, cbRange, pszDesc);3265 3266 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3267 3268 return rc;3269 }3270 3271 3272 /** @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys */3273 static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)3274 {3275 PDMDEV_ASSERT_DEVINS(pDevIns);3276 PVM pVM = pDevIns->Internal.s.pVMR3;3277 VM_ASSERT_EMT(pVM);3278 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n",3279 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys));3280 3281 if (!VM_IS_EMT(pVM))3282 return VERR_ACCESS_DENIED;3283 3284 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys);3285 3286 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys));3287 3288 return rc;3289 }3290 3291 3292 /** @copydoc PDMDEVHLPR3::pfnVMState */3293 static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns)3294 {3295 PDMDEV_ASSERT_DEVINS(pDevIns);3296 3297 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);3298 3299 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,3300 enmVMState, VMR3GetStateName(enmVMState)));3301 return enmVMState;3302 }3303 3304 3305 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */3306 static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)3307 {3308 PDMDEV_ASSERT_DEVINS(pDevIns);3309 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3310 3311 bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMR3);3312 3313 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc));3314 return fRc;3315 }3316 3317 3318 /** @copydoc PDMDEVHLPR3::pfnA20Set */3319 static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)3320 {3321 PDMDEV_ASSERT_DEVINS(pDevIns);3322 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3323 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable));3324 //Assert(*(unsigned *)&fEnable <= 1);3325 PGMR3PhysSetA20(pDevIns->Internal.s.pVMR3, fEnable);3326 }3327 3328 3329 /** @copydoc PDMDEVHLPR3::pfnVMReset */3330 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns)3331 {3332 PDMDEV_ASSERT_DEVINS(pDevIns);3333 PVM pVM = pDevIns->Internal.s.pVMR3;3334 VM_ASSERT_EMT(pVM);3335 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n",3336 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET)));3337 3338 /*3339 * We postpone this operation because we're likely to be inside a I/O instruction3340 * and the EIP will be updated when we return.3341 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.3342 */3343 bool fHaltOnReset;3344 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);3345 if (VBOX_SUCCESS(rc) && fHaltOnReset)3346 {3347 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));3348 rc = VINF_EM_HALT;3349 }3350 else3351 {3352 VM_FF_SET(pVM, VM_FF_RESET);3353 rc = VINF_EM_RESET;3354 }3355 3356 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3357 return rc;3358 }3359 3360 3361 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */3362 static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)3363 {3364 PDMDEV_ASSERT_DEVINS(pDevIns);3365 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3366 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",3367 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3368 3369 int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3);3370 3371 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3372 return rc;3373 }3374 3375 3376 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */3377 static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)3378 {3379 PDMDEV_ASSERT_DEVINS(pDevIns);3380 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3381 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",3382 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3383 3384 int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3);3385 3386 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3387 return rc;3388 }3389 3390 3391 /** @copydoc PDMDEVHLPR3::pfnLockVM */3392 static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns)3393 {3394 return VMMR3Lock(pDevIns->Internal.s.pVMR3);3395 }3396 3397 3398 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */3399 static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns)3400 {3401 return VMMR3Unlock(pDevIns->Internal.s.pVMR3);3402 }3403 3404 3405 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */3406 static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)3407 {3408 PVM pVM = pDevIns->Internal.s.pVMR3;3409 if (VMMR3LockIsOwner(pVM))3410 return true;3411 3412 RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM);3413 RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner);3414 char szMsg[100];3415 RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n",3416 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,3417 NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName());3418 AssertMsg1(szMsg, iLine, pszFile, pszFunction);3419 AssertBreakpoint();3420 return false;3421 }3422 3423 /** @copydoc PDMDEVHLPR3::pfnDMARegister */3424 static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)3425 {3426 PDMDEV_ASSERT_DEVINS(pDevIns);3427 PVM pVM = pDevIns->Internal.s.pVMR3;3428 VM_ASSERT_EMT(pVM);3429 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",3430 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));3431 int rc = VINF_SUCCESS;3432 if (pVM->pdm.s.pDmac)3433 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser);3434 else3435 {3436 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3437 rc = VERR_PDM_NO_DMAC_INSTANCE;3438 }3439 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n",3440 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3441 return rc;3442 }3443 3444 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */3445 static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)3446 {3447 PDMDEV_ASSERT_DEVINS(pDevIns);3448 PVM pVM = pDevIns->Internal.s.pVMR3;3449 VM_ASSERT_EMT(pVM);3450 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",3451 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));3452 int rc = VINF_SUCCESS;3453 if (pVM->pdm.s.pDmac)3454 {3455 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);3456 if (pcbRead)3457 *pcbRead = cb;3458 }3459 else3460 {3461 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3462 rc = VERR_PDM_NO_DMAC_INSTANCE;3463 }3464 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n",3465 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3466 return rc;3467 }3468 3469 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */3470 static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)3471 {3472 PDMDEV_ASSERT_DEVINS(pDevIns);3473 PVM pVM = pDevIns->Internal.s.pVMR3;3474 VM_ASSERT_EMT(pVM);3475 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",3476 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));3477 int rc = VINF_SUCCESS;3478 if (pVM->pdm.s.pDmac)3479 {3480 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);3481 if (pcbWritten)3482 *pcbWritten = cb;3483 }3484 else3485 {3486 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3487 rc = VERR_PDM_NO_DMAC_INSTANCE;3488 }3489 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n",3490 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3491 return rc;3492 }3493 3494 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */3495 static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)3496 {3497 PDMDEV_ASSERT_DEVINS(pDevIns);3498 PVM pVM = pDevIns->Internal.s.pVMR3;3499 VM_ASSERT_EMT(pVM);3500 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",3501 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel));3502 int rc = VINF_SUCCESS;3503 if (pVM->pdm.s.pDmac)3504 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);3505 else3506 {3507 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3508 rc = VERR_PDM_NO_DMAC_INSTANCE;3509 }3510 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n",3511 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3512 return rc;3513 }3514 3515 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */3516 static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)3517 {3518 PDMDEV_ASSERT_DEVINS(pDevIns);3519 PVM pVM = pDevIns->Internal.s.pVMR3;3520 VM_ASSERT_EMT(pVM);3521 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",3522 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel));3523 uint8_t u8Mode;3524 if (pVM->pdm.s.pDmac)3525 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);3526 else3527 {3528 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3529 u8Mode = 3 << 2 /* illegal mode type */;3530 }3531 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",3532 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode));3533 return u8Mode;3534 }3535 3536 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */3537 static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)3538 {3539 PDMDEV_ASSERT_DEVINS(pDevIns);3540 PVM pVM = pDevIns->Internal.s.pVMR3;3541 VM_ASSERT_EMT(pVM);3542 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",3543 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA)));3544 3545 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));3546 VM_FF_SET(pVM, VM_FF_PDM_DMA);3547 REMR3NotifyDmaPending(pVM);3548 VMR3NotifyFF(pVM, true);3549 }3550 3551 3552 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */3553 static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)3554 {3555 PDMDEV_ASSERT_DEVINS(pDevIns);3556 PVM pVM = pDevIns->Internal.s.pVMR3;3557 VM_ASSERT_EMT(pVM);3558 3559 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",3560 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value));3561 int rc;3562 if (pVM->pdm.s.pRtc)3563 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value);3564 else3565 rc = VERR_PDM_NO_RTC_INSTANCE;3566 3567 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",3568 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3569 return rc;3570 }3571 3572 3573 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */3574 static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)3575 {3576 PDMDEV_ASSERT_DEVINS(pDevIns);3577 PVM pVM = pDevIns->Internal.s.pVMR3;3578 VM_ASSERT_EMT(pVM);3579 3580 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",3581 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value));3582 int rc;3583 if (pVM->pdm.s.pRtc)3584 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value);3585 else3586 rc = VERR_PDM_NO_RTC_INSTANCE;3587 3588 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",3589 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3590 return rc;3591 }3592 3593 3594 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */3595 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,3596 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)3597 {3598 PDMDEV_ASSERT_DEVINS(pDevIns);3599 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",3600 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));3601 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);3602 3603 CPUMGetGuestCpuId(pDevIns->Internal.s.pVMR3, iLeaf, pEax, pEbx, pEcx, pEdx);3604 3605 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",3606 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));3607 }3608 3609 3610 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */3611 static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)3612 {3613 PDMDEV_ASSERT_DEVINS(pDevIns);3614 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",3615 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));3616 3617 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange);3618 3619 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3620 return rc;3621 }3622 3623 3624 /**3625 * @copydoc PDMDEVHLPR3::pfnMMIO2Register3626 */3627 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)3628 {3629 PDMDEV_ASSERT_DEVINS(pDevIns);3630 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3631 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",3632 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc));3633 3634 int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc);3635 3636 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3637 return rc;3638 }3639 3640 3641 /**3642 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister3643 */3644 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)3645 {3646 PDMDEV_ASSERT_DEVINS(pDevIns);3647 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3648 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n",3649 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion));3650 3651 AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);3652 3653 int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion);3654 3655 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3656 return rc;3657 }3658 3659 3660 /**3661 * @copydoc PDMDEVHLPR3::pfnMMIO2Map3662 */3663 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)3664 {3665 PDMDEV_ASSERT_DEVINS(pDevIns);3666 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3667 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",3668 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));3669 3670 int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);3671 3672 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3673 return rc;3674 }3675 3676 3677 /**3678 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap3679 */3680 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)3681 {3682 PDMDEV_ASSERT_DEVINS(pDevIns);3683 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3684 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",3685 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));3686 3687 int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);3688 3689 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));3690 return rc;3691 }3692 3693 3694 /**3695 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO23696 */3697 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,3698 const char *pszDesc, PRTRCPTR pRCPtr)3699 {3700 PDMDEV_ASSERT_DEVINS(pDevIns);3701 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3702 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",3703 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));3704 3705 int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, off, cb, pszDesc, pRCPtr);3706 3707 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr));3708 return rc;3709 }3710 3711 3712 /**3713 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap3714 */3715 static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)3716 {3717 PDMDEV_ASSERT_DEVINS(pDevIns);3718 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3719 3720 int rc = PDMR3RegisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys, pvHeap, cbSize);3721 return rc;3722 }3723 3724 3725 /**3726 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap3727 */3728 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)3729 {3730 PDMDEV_ASSERT_DEVINS(pDevIns);3731 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);3732 3733 int rc = PDMR3UnregisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys);3734 return rc;3735 }3736 3737 3738 3739 3740 3741 /** @copydoc PDMDEVHLPR3::pfnGetVM */3742 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)3743 {3744 PDMDEV_ASSERT_DEVINS(pDevIns);3745 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3746 return NULL;3747 }3748 3749 3750 /** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */3751 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)3752 {3753 PDMDEV_ASSERT_DEVINS(pDevIns);3754 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3755 NOREF(pPciBusReg);3756 NOREF(ppPciHlpR3);3757 return VERR_ACCESS_DENIED;3758 }3759 3760 3761 /** @copydoc PDMDEVHLPR3::pfnPICRegister */3762 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)3763 {3764 PDMDEV_ASSERT_DEVINS(pDevIns);3765 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3766 NOREF(pPicReg);3767 NOREF(ppPicHlpR3);3768 return VERR_ACCESS_DENIED;3769 }3770 3771 3772 /** @copydoc PDMDEVHLPR3::pfnAPICRegister */3773 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)3774 {3775 PDMDEV_ASSERT_DEVINS(pDevIns);3776 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3777 NOREF(pApicReg);3778 NOREF(ppApicHlpR3);3779 return VERR_ACCESS_DENIED;3780 }3781 3782 3783 /** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */3784 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)3785 {3786 PDMDEV_ASSERT_DEVINS(pDevIns);3787 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3788 NOREF(pIoApicReg);3789 NOREF(ppIoApicHlpR3);3790 return VERR_ACCESS_DENIED;3791 }3792 3793 3794 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */3795 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)3796 {3797 PDMDEV_ASSERT_DEVINS(pDevIns);3798 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3799 NOREF(pDmacReg);3800 NOREF(ppDmacHlp);3801 return VERR_ACCESS_DENIED;3802 }3803 3804 3805 /** @copydoc PDMDEVHLPR3::pfnPhysRead */3806 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)3807 {3808 PDMDEV_ASSERT_DEVINS(pDevIns);3809 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3810 NOREF(GCPhys);3811 NOREF(pvBuf);3812 NOREF(cbRead);3813 }3814 3815 3816 /** @copydoc PDMDEVHLPR3::pfnPhysWrite */3817 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)3818 {3819 PDMDEV_ASSERT_DEVINS(pDevIns);3820 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3821 NOREF(GCPhys);3822 NOREF(pvBuf);3823 NOREF(cbWrite);3824 }3825 3826 3827 /** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */3828 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)3829 {3830 PDMDEV_ASSERT_DEVINS(pDevIns);3831 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3832 NOREF(pvDst);3833 NOREF(GCVirtSrc);3834 NOREF(cb);3835 return VERR_ACCESS_DENIED;3836 }3837 3838 3839 /** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */3840 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)3841 {3842 PDMDEV_ASSERT_DEVINS(pDevIns);3843 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3844 NOREF(GCVirtDst);3845 NOREF(pvSrc);3846 NOREF(cb);3847 return VERR_ACCESS_DENIED;3848 }3849 3850 3851 /** @copydoc PDMDEVHLPR3::pfnPhysReserve */3852 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)3853 {3854 PDMDEV_ASSERT_DEVINS(pDevIns);3855 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3856 NOREF(GCPhys);3857 NOREF(cbRange);3858 return VERR_ACCESS_DENIED;3859 }3860 3861 3862 /** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */3863 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC)3864 {3865 PDMDEV_ASSERT_DEVINS(pDevIns);3866 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3867 NOREF(GCPhys);3868 NOREF(cbRange);3869 NOREF(ppvHC);3870 return VERR_ACCESS_DENIED;3871 }3872 3873 3874 /** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */3875 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr)3876 {3877 PDMDEV_ASSERT_DEVINS(pDevIns);3878 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3879 NOREF(GCPtr);3880 NOREF(pHCPtr);3881 return VERR_ACCESS_DENIED;3882 }3883 3884 3885 /** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */3886 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)3887 {3888 PDMDEV_ASSERT_DEVINS(pDevIns);3889 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3890 return false;3891 }3892 3893 3894 /** @copydoc PDMDEVHLPR3::pfnA20Set */3895 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)3896 {3897 PDMDEV_ASSERT_DEVINS(pDevIns);3898 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3899 NOREF(fEnable);3900 }3901 3902 3903 /** @copydoc PDMDEVHLPR3::pfnVMReset */3904 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns)3905 {3906 PDMDEV_ASSERT_DEVINS(pDevIns);3907 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3908 return VERR_ACCESS_DENIED;3909 }3910 3911 3912 /** @copydoc PDMDEVHLPR3::pfnVMSuspend */3913 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)3914 {3915 PDMDEV_ASSERT_DEVINS(pDevIns);3916 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3917 return VERR_ACCESS_DENIED;3918 }3919 3920 3921 /** @copydoc PDMDEVHLPR3::pfnVMPowerOff */3922 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)3923 {3924 PDMDEV_ASSERT_DEVINS(pDevIns);3925 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3926 return VERR_ACCESS_DENIED;3927 }3928 3929 3930 /** @copydoc PDMDEVHLPR3::pfnLockVM */3931 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns)3932 {3933 PDMDEV_ASSERT_DEVINS(pDevIns);3934 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3935 return VERR_ACCESS_DENIED;3936 }3937 3938 3939 /** @copydoc PDMDEVHLPR3::pfnUnlockVM */3940 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns)3941 {3942 PDMDEV_ASSERT_DEVINS(pDevIns);3943 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3944 return VERR_ACCESS_DENIED;3945 }3946 3947 3948 /** @copydoc PDMDEVHLPR3::pfnAssertVMLock */3949 static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)3950 {3951 PDMDEV_ASSERT_DEVINS(pDevIns);3952 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3953 return false;3954 }3955 3956 3957 /** @copydoc PDMDEVHLPR3::pfnDMARegister */3958 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)3959 {3960 PDMDEV_ASSERT_DEVINS(pDevIns);3961 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3962 return VERR_ACCESS_DENIED;3963 }3964 3965 3966 /** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */3967 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)3968 {3969 PDMDEV_ASSERT_DEVINS(pDevIns);3970 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3971 if (pcbRead)3972 *pcbRead = 0;3973 return VERR_ACCESS_DENIED;3974 }3975 3976 3977 /** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */3978 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)3979 {3980 PDMDEV_ASSERT_DEVINS(pDevIns);3981 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3982 if (pcbWritten)3983 *pcbWritten = 0;3984 return VERR_ACCESS_DENIED;3985 }3986 3987 3988 /** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */3989 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)3990 {3991 PDMDEV_ASSERT_DEVINS(pDevIns);3992 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));3993 return VERR_ACCESS_DENIED;3994 }3995 3996 3997 /** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */3998 static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)3999 {4000 PDMDEV_ASSERT_DEVINS(pDevIns);4001 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4002 return 3 << 2 /* illegal mode type */;4003 }4004 4005 4006 /** @copydoc PDMDEVHLPR3::pfnDMASchedule */4007 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns)4008 {4009 PDMDEV_ASSERT_DEVINS(pDevIns);4010 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4011 }4012 4013 4014 /** @copydoc PDMDEVHLPR3::pfnCMOSWrite */4015 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)4016 {4017 PDMDEV_ASSERT_DEVINS(pDevIns);4018 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4019 return VERR_ACCESS_DENIED;4020 }4021 4022 4023 /** @copydoc PDMDEVHLPR3::pfnCMOSRead */4024 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)4025 {4026 PDMDEV_ASSERT_DEVINS(pDevIns);4027 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4028 return VERR_ACCESS_DENIED;4029 }4030 4031 4032 /** @copydoc PDMDEVHLPR3::pfnGetCpuId */4033 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,4034 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)4035 {4036 PDMDEV_ASSERT_DEVINS(pDevIns);4037 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4038 }4039 4040 4041 /** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */4042 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)4043 {4044 PDMDEV_ASSERT_DEVINS(pDevIns);4045 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4046 return VERR_ACCESS_DENIED;4047 }4048 4049 4050 /** @copydoc PDMDEVHLPR3::pfnMMIO2Register */4051 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)4052 {4053 PDMDEV_ASSERT_DEVINS(pDevIns);4054 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4055 return VERR_ACCESS_DENIED;4056 }4057 4058 4059 /** @copydoc PDMDEVHLPR3::pfnMMIO2Deregister */4060 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)4061 {4062 PDMDEV_ASSERT_DEVINS(pDevIns);4063 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4064 return VERR_ACCESS_DENIED;4065 }4066 4067 4068 /** @copydoc PDMDEVHLPR3::pfnMMIO2Map */4069 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)4070 {4071 PDMDEV_ASSERT_DEVINS(pDevIns);4072 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4073 return VERR_ACCESS_DENIED;4074 }4075 4076 4077 /** @copydoc PDMDEVHLPR3::pfnMMIO2Unmap */4078 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)4079 {4080 PDMDEV_ASSERT_DEVINS(pDevIns);4081 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4082 return VERR_ACCESS_DENIED;4083 }4084 4085 4086 /** @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 */4087 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr)4088 {4089 PDMDEV_ASSERT_DEVINS(pDevIns);4090 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4091 return VERR_ACCESS_DENIED;4092 }4093 4094 4095 /** @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap */4096 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)4097 {4098 PDMDEV_ASSERT_DEVINS(pDevIns);4099 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4100 return VERR_ACCESS_DENIED;4101 }4102 4103 4104 /** @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap */4105 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)4106 {4107 PDMDEV_ASSERT_DEVINS(pDevIns);4108 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));4109 return VERR_ACCESS_DENIED;4110 }4111 4112 4113 4114 4115 4116 /** @copydoc PDMPICHLPR3::pfnSetInterruptFF */4117 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)4118 {4119 PDMDEV_ASSERT_DEVINS(pDevIns);4120 PVM pVM = pDevIns->Internal.s.pVMR3;4121 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",4122 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, 0, VM_FF_INTERRUPT_PIC)));4123 /* for PIC we always deliver to CPU 0, MP use APIC */4124 VMCPU_FF_SET(pVM, 0, VM_FF_INTERRUPT_PIC);4125 REMR3NotifyInterruptSet(pVM);4126 VMR3NotifyFF(pVM, true);4127 }4128 4129 4130 /** @copydoc PDMPICHLPR3::pfnClearInterruptFF */4131 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)4132 {4133 PDMDEV_ASSERT_DEVINS(pDevIns);4134 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",4135 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC)));4136 /* for PIC we always deliver to CPU 0, MP use APIC */4137 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, 0, VM_FF_INTERRUPT_PIC);4138 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3);4139 }4140 4141 4142 /** @copydoc PDMPICHLPR3::pfnLock */4143 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)4144 {4145 PDMDEV_ASSERT_DEVINS(pDevIns);4146 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);4147 }4148 4149 4150 /** @copydoc PDMPICHLPR3::pfnUnlock */4151 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)4152 {4153 PDMDEV_ASSERT_DEVINS(pDevIns);4154 pdmUnlock(pDevIns->Internal.s.pVMR3);4155 }4156 4157 4158 /** @copydoc PDMPICHLPR3::pfnGetRCHelpers */4159 static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)4160 {4161 PDMDEV_ASSERT_DEVINS(pDevIns);4162 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4163 RTRCPTR pRCHelpers = 0;4164 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers);4165 AssertReleaseRC(rc);4166 AssertRelease(pRCHelpers);4167 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",4168 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));4169 return pRCHelpers;4170 }4171 4172 4173 /** @copydoc PDMPICHLPR3::pfnGetR0Helpers */4174 static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)4175 {4176 PDMDEV_ASSERT_DEVINS(pDevIns);4177 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4178 PCPDMPICHLPR0 pR0Helpers = 0;4179 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers);4180 AssertReleaseRC(rc);4181 AssertRelease(pR0Helpers);4182 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",4183 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));4184 return pR0Helpers;4185 }4186 4187 4188 /** @copydoc PDMAPICHLPR3::pfnSetInterruptFF */4189 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)4190 {4191 PDMDEV_ASSERT_DEVINS(pDevIns);4192 PVM pVM = pDevIns->Internal.s.pVMR3;4193 LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 1\n",4194 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVM, idCpu, VM_FF_INTERRUPT_APIC)));4195 VMCPU_FF_SET(pVM, idCpu, VM_FF_INTERRUPT_APIC);4196 REMR3NotifyInterruptSet(pVM);4197 VMR3NotifyFF(pVM, true);4198 }4199 4200 4201 /** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */4202 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)4203 {4204 PDMDEV_ASSERT_DEVINS(pDevIns);4205 LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 0\n",4206 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC)));4207 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMR3, idCpu, VM_FF_INTERRUPT_APIC);4208 REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMR3);4209 }4210 4211 4212 /** @copydoc PDMAPICHLPR3::pfnChangeFeature */4213 static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)4214 {4215 PDMDEV_ASSERT_DEVINS(pDevIns);4216 LogFlow(("pdmR3ApicHlp_ChangeFeature: caller='%s'/%d: version=%d\n",4217 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, (int)enmVersion));4218 switch (enmVersion)4219 {4220 case PDMAPICVERSION_NONE:4221 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);4222 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);4223 break;4224 case PDMAPICVERSION_APIC:4225 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);4226 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);4227 break;4228 case PDMAPICVERSION_X2APIC:4229 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);4230 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);4231 break;4232 default:4233 AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));4234 }4235 }4236 4237 /** @copydoc PDMAPICHLPR3::pfnLock */4238 static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)4239 {4240 PDMDEV_ASSERT_DEVINS(pDevIns);4241 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);4242 }4243 4244 4245 /** @copydoc PDMAPICHLPR3::pfnUnlock */4246 static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns)4247 {4248 PDMDEV_ASSERT_DEVINS(pDevIns);4249 pdmUnlock(pDevIns->Internal.s.pVMR3);4250 }4251 4252 4253 /** @copydoc PDMAPICHLPR3::pfnGetCpuId */4254 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)4255 {4256 PDMDEV_ASSERT_DEVINS(pDevIns);4257 return VMMGetCpuId(pDevIns->Internal.s.pVMR3);4258 }4259 4260 4261 /** @copydoc PDMAPICHLPR3::pfnGetRCHelpers */4262 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)4263 {4264 PDMDEV_ASSERT_DEVINS(pDevIns);4265 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4266 RTRCPTR pRCHelpers = 0;4267 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCApicHlp", &pRCHelpers);4268 AssertReleaseRC(rc);4269 AssertRelease(pRCHelpers);4270 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",4271 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));4272 return pRCHelpers;4273 }4274 4275 4276 /** @copydoc PDMAPICHLPR3::pfnGetR0Helpers */4277 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)4278 {4279 PDMDEV_ASSERT_DEVINS(pDevIns);4280 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4281 PCPDMAPICHLPR0 pR0Helpers = 0;4282 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0ApicHlp", &pR0Helpers);4283 AssertReleaseRC(rc);4284 AssertRelease(pR0Helpers);4285 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",4286 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));4287 return pR0Helpers;4288 }4289 4290 4291 /** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */4292 static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,4293 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)4294 {4295 PDMDEV_ASSERT_DEVINS(pDevIns);4296 PVM pVM = pDevIns->Internal.s.pVMR3;4297 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",4298 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));4299 if (pVM->pdm.s.Apic.pfnBusDeliverR3)4300 pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);4301 }4302 4303 4304 /** @copydoc PDMIOAPICHLPR3::pfnLock */4305 static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)4306 {4307 PDMDEV_ASSERT_DEVINS(pDevIns);4308 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);4309 }4310 4311 4312 /** @copydoc PDMIOAPICHLPR3::pfnUnlock */4313 static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)4314 {4315 PDMDEV_ASSERT_DEVINS(pDevIns);4316 pdmUnlock(pDevIns->Internal.s.pVMR3);4317 }4318 4319 4320 /** @copydoc PDMIOAPICHLPR3::pfnGetRCHelpers */4321 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)4322 {4323 PDMDEV_ASSERT_DEVINS(pDevIns);4324 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4325 RTRCPTR pRCHelpers = 0;4326 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);4327 AssertReleaseRC(rc);4328 AssertRelease(pRCHelpers);4329 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",4330 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));4331 return pRCHelpers;4332 }4333 4334 4335 /** @copydoc PDMIOAPICHLPR3::pfnGetR0Helpers */4336 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)4337 {4338 PDMDEV_ASSERT_DEVINS(pDevIns);4339 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4340 PCPDMIOAPICHLPR0 pR0Helpers = 0;4341 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);4342 AssertReleaseRC(rc);4343 AssertRelease(pR0Helpers);4344 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",4345 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));4346 return pR0Helpers;4347 }4348 4349 4350 /** @copydoc PDMPCIHLPR3::pfnIsaSetIrq */4351 static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)4352 {4353 PDMDEV_ASSERT_DEVINS(pDevIns);4354 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));4355 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);4356 }4357 4358 4359 /** @copydoc PDMPCIHLPR3::pfnIoApicSetIrq */4360 static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)4361 {4362 PDMDEV_ASSERT_DEVINS(pDevIns);4363 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));4364 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);4365 }4366 4367 4368 /** @copydoc PDMPCIHLPR3::pfnIsMMIO2Base */4369 static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)4370 {4371 PDMDEV_ASSERT_DEVINS(pDevIns);4372 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4373 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);4374 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));4375 return fRc;4376 }4377 4378 4379 /** @copydoc PDMPCIHLPR3::pfnLock */4380 static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)4381 {4382 PDMDEV_ASSERT_DEVINS(pDevIns);4383 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);4384 }4385 4386 4387 /** @copydoc PDMPCIHLPR3::pfnUnlock */4388 static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)4389 {4390 PDMDEV_ASSERT_DEVINS(pDevIns);4391 pdmUnlock(pDevIns->Internal.s.pVMR3);4392 }4393 4394 4395 /** @copydoc PDMPCIHLPR3::pfnGetRCHelpers */4396 static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)4397 {4398 PDMDEV_ASSERT_DEVINS(pDevIns);4399 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4400 RTRCPTR pRCHelpers = 0;4401 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciHlp", &pRCHelpers);4402 AssertReleaseRC(rc);4403 AssertRelease(pRCHelpers);4404 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",4405 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));4406 return pRCHelpers;4407 }4408 4409 4410 /** @copydoc PDMPCIHLPR3::pfnGetR0Helpers */4411 static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)4412 {4413 PDMDEV_ASSERT_DEVINS(pDevIns);4414 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);4415 PCPDMPCIHLPR0 pR0Helpers = 0;4416 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciHlp", &pR0Helpers);4417 AssertReleaseRC(rc);4418 AssertRelease(pR0Helpers);4419 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",4420 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));4421 return pR0Helpers;4422 }4423 4424 4425 733 /** 4426 734 * Locates a LUN. -
trunk/src/VBox/VMM/PDMInternal.h
r12975 r12980 906 906 *******************************************************************************/ 907 907 #ifdef IN_RING3 908 extern const PDMDRVHLP g_pdmR3DrvHlp; 908 extern const PDMDRVHLP g_pdmR3DrvHlp; 909 extern const PDMDEVHLPR3 g_pdmR3DevHlpTrusted; 910 extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted; 911 extern const PDMPICHLPR3 g_pdmR3DevPicHlp; 912 extern const PDMAPICHLPR3 g_pdmR3DevApicHlp; 913 extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp; 914 extern const PDMPCIHLPR3 g_pdmR3DevPciHlp; 915 extern const PDMDMACHLP g_pdmR3DevDmacHlp; 916 extern const PDMRTCHLP g_pdmR3DevRtcHlp; 917 #endif 918 919 920 /******************************************************************************* 921 * Defined Constants And Macros * 922 *******************************************************************************/ 923 /** @def PDMDEV_ASSERT_DEVINS 924 * Asserts the validity of the device instance. 925 */ 926 #ifdef VBOX_STRICT 927 # define PDMDEV_ASSERT_DEVINS(pDevIns) \ 928 do { \ 929 AssertPtr(pDevIns); \ 930 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \ 931 Assert(pDevIns->CTX_SUFF(pvInstanceData) == (void *)&pDevIns->achInstanceData[0]); \ 932 } while (0) 933 #else 934 # define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0) 909 935 #endif 910 936 … … 923 949 PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName); 924 950 int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun); 951 DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem); 925 952 926 953 int pdmR3UsbLoadModules(PVM pVM);
Note:
See TracChangeset
for help on using the changeset viewer.