Changeset 12980 in vbox for trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
- Timestamp:
- Oct 4, 2008 9:20:46 PM (16 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.