PDMDevice.cpp revision 6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/* $Id$ */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @file
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * PDM - Pluggable Device and Driver Manager, Device parts.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * available from http://www.virtualbox.org. This file is free software;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * General Public License (GPL) as published by the Free Software
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * additional information or have any questions.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*******************************************************************************
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync* Header Files *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync*******************************************************************************/
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#define LOG_GROUP LOG_GROUP_PDM_DEVICE
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include "PDMInternal.h"
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/pdm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/mm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/pgm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/iom.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/cfgm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/rem.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/dbgf.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/vm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/vmm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/version.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/log.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <VBox/err.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/alloc.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/alloca.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/asm.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/assert.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/path.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/semaphore.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/string.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#include <iprt/thread.h>
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*******************************************************************************
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync* Structures and Typedefs *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync*******************************************************************************/
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Internal callback structure pointer.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * The main purpose is to define the extra data we associate
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * with PDMDEVREGCB so we can find the VM instance and so on.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsynctypedef struct PDMDEVREGCBINT
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** The callback structure. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEVREGCB Core;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** A bit of padding. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t u32[4];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** VM Handle. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync} PDMDEVREGCBINT, *PPDMDEVREGCBINT;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsynctypedef const PDMDEVREGCBINT *PCPDMDEVREGCBINT;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*******************************************************************************
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync* Internal Functions *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync*******************************************************************************/
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync__BEGIN_DECLS
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/* VSlick regex:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncsearch : \om/\*\*.+?\*\/\nDECLCALLBACKMEMBER\(([^,]*), *pfn([^)]*)\)\(
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncreplace: \/\*\* @copydoc PDMDEVHLP::pfn\2 \*\/\nstatic DECLCALLBACK\(\1\) pdmR3DevHlp_\2\(
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @name R3 DevHlp
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic 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);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic 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);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszWrite, const char *pszRead, const char *pszFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszWrite, const char *pszRead, const char *pszFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_Untrusted_QueryCPUId(PPDMDEVINS pDevIns, uint32_t iLeaf,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @} */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @name HC PIC Helpers
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @} */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @name HC APIC Helpers
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(uint32_t) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @} */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @name HC I/O APIC Helpers
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @} */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @name HC PCI Bus Helpers
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @} */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @def PDMDEV_ASSERT_DEVINS
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Asserts the validity of the device instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#ifdef VBOX_STRICT
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync# define PDMDEV_ASSERT_DEVINS(pDevIns) \
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync do { \
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtr(pDevIns); \
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pDevIns->pvInstanceDataR3 == (void *)&pDevIns->achInstanceData[0]); \
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync } while (0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#endif
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allow physical read and writes from any thread
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#define PDM_PHYS_READWRITE_FROM_ANY_THREAD
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync__END_DECLS
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/*******************************************************************************
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync* Global Variables *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync*******************************************************************************/
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * The device helper structure for trusted devices.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMDEVHLP g_pdmR3DevHlpTrusted =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_DEVHLP_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegisterGC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegisterR0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortDeregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegisterGC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegisterR0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIODeregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ROMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_SSMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_TMTimerCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_TMTimerCreateExternal,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCIRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCIIORegionRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetConfigCallbacks,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrqNoWait,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ISASetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ISASetIrqNoWait,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DriverAttach,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapAlloc,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapAllocZ,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapFree,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetError,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetErrorV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetRuntimeError,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetRuntimeErrorV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_AssertEMT,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_AssertOther,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DBGFStopV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DBGFInfoRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegisterF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegisterV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_RTCRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PDMQueueCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_CritSectInit,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_UTCNow,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PDMThreadCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysGCPtr2GCPhys,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMState,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_GetVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCIBusRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_APICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOAPICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMACRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysRead,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysWrite,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysReadGCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysWriteGCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysReserve,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_A20IsEnabled,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_A20Set,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMReset,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSuspend,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMPowerOff,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_LockVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_UnlockVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_AssertVMLock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMARegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMAReadMemory,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMAWriteMemory,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMASetDREQ,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMAGetChannelMode,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DMASchedule,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_CMOSWrite,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_CMOSRead,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_GetCpuId,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ROMProtectShadow,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIO2Register,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIO2Deregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIO2Map,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIO2Unmap,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHyperMapMMIO2,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_DEVHLP_VERSION /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * The device helper structure for non-trusted devices.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMDEVHLP g_pdmR3DevHlpUnTrusted =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_DEVHLP_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegisterGC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortRegisterR0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_IOPortDeregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegisterGC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIORegisterR0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMIODeregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ROMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_SSMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_TMTimerCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_TMTimerCreateExternal,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCIRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCIIORegionRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetConfigCallbacks,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrqNoWait,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ISASetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ISASetIrqNoWait,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DriverAttach,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapAlloc,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapAllocZ,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_MMHeapFree,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetError,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetErrorV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetRuntimeError,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMSetRuntimeErrorV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_AssertEMT,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_AssertOther,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DBGFStopV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_DBGFInfoRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegisterF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_STAMRegisterV,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_RTCRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PDMQueueCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_CritSectInit,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_UTCNow,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PDMThreadCreate,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PhysGCPtr2GCPhys,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_VMState,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_GetVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PCIBusRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_APICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_IOAPICRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMACRegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PhysRead,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PhysWrite,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PhysReadGCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PhysWriteGCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_PhysReserve,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_A20IsEnabled,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_A20Set,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_VMReset,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_VMSuspend,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_VMPowerOff,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_LockVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_UnlockVM,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_AssertVMLock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMARegister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMAReadMemory,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMAWriteMemory,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMASetDREQ,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMAGetChannelMode,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_DMASchedule,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_CMOSWrite,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_CMOSRead,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_QueryCPUId,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_ROMProtectShadow,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_MMIO2Register,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_MMIO2Deregister,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_MMIO2Map,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_MMIO2Unmap,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_Untrusted_MMHyperMapMMIO2,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_DEVHLP_VERSION /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * PIC Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMPICHLPR3 g_pdmR3DevPicHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_PICHLPR3_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_SetInterruptFF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_ClearInterruptFF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_Lock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_Unlock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_GetRCHelpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PicHlp_GetR0Helpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_PICHLPR3_VERSION /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * APIC Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMAPICHLPR3 g_pdmR3DevApicHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_APICHLPR3_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_SetInterruptFF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_ClearInterruptFF,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_ChangeFeature,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_Lock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_Unlock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_GetCpuId,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_GetRCHelpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3ApicHlp_GetR0Helpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_APICHLPR3_VERSION /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * I/O APIC Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_IOAPICHLPR3_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3IoApicHlp_ApicBusDeliver,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3IoApicHlp_Lock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3IoApicHlp_Unlock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3IoApicHlp_GetRCHelpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3IoApicHlp_GetR0Helpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_IOAPICHLPR3_VERSION /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * PCI Bus Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMPCIHLPR3 g_pdmR3DevPciHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_PCIHLPR3_VERSION,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_IsaSetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_IoApicSetIrq,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_IsMMIO2Base,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_GetRCHelpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_GetR0Helpers,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_Lock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3PciHlp_Unlock,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_PCIHLPR3_VERSION, /* the end */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * DMAC Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMDMACHLP g_pdmR3DevDmacHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_DMACHLP_VERSION
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * RTC Device Helpers.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncconst PDMRTCHLP g_pdmR3DevRtcHlp =
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_RTCHLP_VERSION
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync};
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * This function will initialize the devices for this VM instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * First of all this mean loading the builtin device and letting them
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * register themselves. Beyond that any additional device modules are
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * loaded and called for registration.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Then the device configuration is enumerated, the instantiation order
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * is determined, and finally they are instantiated.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * After all device have been successfully instantiated the the primary
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * PCI Bus device is called to emulate the PCI BIOS, i.e. making the
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * resource assignments. If there is no PCI device, this step is of course
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * skipped.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Finally the init completion routines of the instantiated devices
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * are called.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @returns VBox status code.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pVM VM Handle.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncint pdmR3DevInit(PVM pVM)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevInit:\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRelease(!(RT_OFFSETOF(PDMDEVINS, achInstanceData) & 15));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRelease(sizeof(pVM->pdm.s.pDevInstances->Internal.s) <= sizeof(pVM->pdm.s.pDevInstances->Internal.padding));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Get the GC & R0 devhlps and create the devhlp R3 task queue.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RCPTRTYPE(PCPDMDEVHLPGC) pDevHlpGC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3GetSymbolGC(pVM, NULL, "g_pdmGCDevHlp", &pDevHlpGC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertReleaseRCReturn(rc, rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PCPDMDEVHLPR0) pDevHlpR0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0(pVM, NULL, "g_pdmR0DevHlp", &pDevHlpR0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertReleaseRCReturn(rc, rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3QueueCreateInternal(pVM, sizeof(PDMDEVHLPTASK), 8, 0, pdmR3DevHlpQueueConsumer, true, &pVM->pdm.s.pDevHlpQueueHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRCReturn(rc, rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.pDevHlpQueueGC = PDMQueueGCPtr(pVM->pdm.s.pDevHlpQueueHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Initialize the callback structure.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEVREGCBINT RegCB;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RegCB.Core.u32Version = PDM_DEVREG_CB_VERSION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RegCB.Core.pfnRegister = pdmR3DevReg_Register;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RegCB.Core.pfnMMHeapAlloc = pdmR3DevReg_MMHeapAlloc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RegCB.pVM = pVM;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Load the builtin module
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/Devices");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync bool fLoadBuiltin;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryBool(pDevicesNode, "LoadBuiltin", &fLoadBuiltin);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync fLoadBuiltin = true;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: Querying boolean \"LoadBuiltin\" failed with %Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (fLoadBuiltin)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* make filename */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char *pszFilename = pdmR3FileR3("VBoxDD", /* fShared = */ true);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pszFilename)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_NO_TMP_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTMemTmpFree(pszFilename);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* make filename */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pszFilename = pdmR3FileR3("VBoxDD2", /* fShared = */ true);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pszFilename)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_NO_TMP_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3DevLoad(pVM, &RegCB, pszFilename, "VBoxDD2");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTMemTmpFree(pszFilename);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Load additional device modules.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pCur;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Get the name and path.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szName[PDMMOD_NAME_LEN];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3GetName(pCur, &szName[0], sizeof(szName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("configuration error: The module name is too long, cchName=%d.\n", CFGMR3GetNameLen(pCur)));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_MODULE_NAME_TOO_LONG;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("CFGMR3GetName -> %Vrc.\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* the path is optional, if no path the module name + path is used. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szFilename[RTPATH_MAX];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryString(pCur, "Path", &szFilename[0], sizeof(szFilename));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync strcpy(szFilename, szName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("configuration error: Failure to query the module path, rc=%Vrc.\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* prepend path? */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!RTPathHavePath(szFilename))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char *psz = pdmR3FileR3(szFilename);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!psz)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_NO_TMP_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync size_t cch = strlen(psz) + 1;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (cch > sizeof(szFilename))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTMemTmpFree(psz);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Filename too long! cch=%d '%s'\n", cch, psz));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_FILENAME_TOO_LONG;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync memcpy(szFilename, psz, cch);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTMemTmpFree(psz);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Load the module and register it's devices.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3DevLoad(pVM, &RegCB, szFilename, szName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#ifdef VBOX_WITH_USB
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* ditto for USB Devices. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3UsbLoadModules(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (RT_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#endif
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Enumerate the device instance configurations
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * and come up with a instantiation order.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Switch to /Devices, which contains the device instantiations. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevicesNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Count the device instances.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pInstanceNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync unsigned cDevs = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync cDevs++;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!cDevs)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: No devices were configured!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log2(("PDM: cDevs=%d!\n", cDevs));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Collect info on each device instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync struct DEVORDER
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** Configuration node. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** Pointer to device. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEV pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** Init order. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t u32Order;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** VBox instance number. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t iInstance;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync } *paDevs = (struct DEVORDER *)alloca(sizeof(paDevs[0]) * (cDevs + 1)); /* (One extra for swapping) */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(paDevs);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync unsigned i = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (pCur = CFGMR3GetFirstChild(pDevicesNode); pCur; pCur = CFGMR3GetNextChild(pCur))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Get the device name. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szName[sizeof(paDevs[0].pDev->pDevReg->szDeviceName)];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3GetName(pCur, szName, sizeof(szName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRCReturn(rc, ("Configuration error: device name is too long (or something)! rc=%Vrc\n", rc), rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Find the device. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEV pDev = pdmR3DevLookup(pVM, szName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgReturn(pDev, ("Configuration error: device '%s' not found!\n", szName), VERR_PDM_DEVICE_NOT_FOUND);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Configured priority or use default based on device class? */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t u32Order;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryU32(pCur, "Priority", &u32Order);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint32_t u32 = pDev->pDevReg->fClass;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (u32Order = 1; !(u32 & u32Order); u32Order <<= 1)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* nop */;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRCReturn(rc, ("Configuration error: reading \"Priority\" for the '%s' device failed rc=%Vrc!\n", szName, rc), rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Enumerate the device instances. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (pInstanceNode = CFGMR3GetFirstChild(pCur); pInstanceNode; pInstanceNode = CFGMR3GetNextChild(pInstanceNode))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i].pNode = pInstanceNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i].pDev = pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i].u32Order = u32Order;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Get the instance number. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szInstance[32];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3GetName(pInstanceNode, szInstance, sizeof(szInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRCReturn(rc, ("Configuration error: instance name is too long (or something)! rc=%Vrc\n", rc), rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char *pszNext = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = RTStrToUInt32Ex(szInstance, &pszNext, 0, &paDevs[i].iInstance);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRCReturn(rc, ("Configuration error: RTStrToInt32Ex failed on the instance name '%s'! rc=%Vrc\n", szInstance, rc), rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgReturn(!*pszNext, ("Configuration error: the instance name '%s' isn't all digits. (%s)\n", szInstance, pszNext), VERR_INVALID_PARAMETER);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* next instance */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync i++;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync } /* devices */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(i == cDevs);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Sort the device array ascending on u32Order. (bubble)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync unsigned c = cDevs - 1;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync while (c)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync unsigned j = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (i = 0; i < c; i++)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (paDevs[i].u32Order > paDevs[i + 1].u32Order)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[cDevs] = paDevs[i + 1];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i + 1] = paDevs[i];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i] = paDevs[cDevs];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync j = i;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync c = j;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Instantiate the devices.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (i = 0; i < cDevs; i++)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Gather a bit of config.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* trusted */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync bool fTrusted;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryBool(paDevs[i].pNode, "Trusted", &fTrusted);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync fTrusted = false;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("configuration error: failed to query boolean \"Trusted\", rc=%Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* config node */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pConfigNode = CFGMR3GetChild(paDevs[i].pNode, "Config");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pConfigNode)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3InsertNode(paDevs[i].pNode, "Config", &pConfigNode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync CFGMR3SetRestrictedRoot(pConfigNode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allocate the device instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync size_t cb = RT_OFFSETOF(PDMDEVINS, achInstanceData[paDevs[i].pDev->pDevReg->cbInstance]);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync cb = RT_ALIGN_Z(cb, 16);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEVINS pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (paDevs[i].pDev->pDevReg->fFlags & (PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = MMR3HyperAllocOnceNoRel(pVM, cb, 0, MM_TAG_PDM_DEVICE, (void **)&pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to allocate %d bytes of instance data for device '%s'. rc=%Vrc\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync cb, paDevs[i].pDev->pDevReg->szDeviceName, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Initialize it.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->u32Version = PDM_DEVINS_VERSION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pDevIns->Internal.s.pNextHC = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pDevIns->Internal.s.pPerDeviceNextHC = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pDevHC = paDevs[i].pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pVMHC = pVM;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pVMGC = pVM->pVMGC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pDevIns->Internal.s.pLunsHC = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pCfgHandle = paDevs[i].pNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pDevIns->Internal.s.pPciDevice = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pDevIns->Internal.s.pPciBus = NULL; /** @todo pci bus selection. (in 2008 perhaps) */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevHlp = fTrusted ? &g_pdmR3DevHlpTrusted : &g_pdmR3DevHlpUnTrusted;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevHlpGC = pDevHlpGC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevHlpR0 = pDevHlpR0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg = paDevs[i].pDev->pDevReg;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pCfgHandle = pConfigNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->iInstance = paDevs[i].iInstance;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pvInstanceDataR3 = &pDevIns->achInstanceData[0];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pvInstanceDataGC = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ? MMHyperHC2GC(pVM, pDevIns->pvInstanceDataR3) : 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pvInstanceDataR0 = pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Link it into all the lists.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* The global instance FIFO. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEVINS pPrev1 = pVM->pdm.s.pDevInstances;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pPrev1)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.pDevInstances = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync while (pPrev1->Internal.s.pNextHC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPrev1 = pPrev1->Internal.s.pNextHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPrev1->Internal.s.pNextHC = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* The per device instance FIFO. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEVINS pPrev2 = paDevs[i].pDev->pInstances;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pPrev2)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync paDevs[i].pDev->pInstances = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync while (pPrev2->Internal.s.pPerDeviceNextHC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPrev2 = pPrev2->Internal.s.pPerDeviceNextHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPrev2->Internal.s.pPerDeviceNextHC = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Call the constructor.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Constructing device '%s' instance %d...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pDevIns->pDevReg->pfnConstruct(pDevIns, pDevIns->iInstance, pDevIns->pCfgHandle);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogRel(("PDM: Failed to construct '%s'/%d! %Vra\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* because we're damn lazy right now, we'll say that the destructor will be called even if the constructor fails. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync } /* for device instances */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#ifdef VBOX_WITH_USB
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* ditto for USB Devices. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3UsbInstantiateDevices(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (RT_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#endif
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * PCI BIOS Fake and Init Complete.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pVM->pdm.s.aPciBuses[0].pDevInsR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmLock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pVM->pdm.s.aPciBuses[0].pfnFakePCIBIOSR3(pVM->pdm.s.aPciBuses[0].pDevInsR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmUnlock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("PCI BIOS fake failed rc=%Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextHC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevIns->pDevReg->pfnInitComplete)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pDevIns->pDevReg->pfnInitComplete(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("InitComplete on device '%s'/%d failed with rc=%Vrc\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#ifdef VBOX_WITH_USB
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* ditto for USB Devices. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pdmR3UsbVMInitComplete(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (RT_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#endif
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevInit: returns %Vrc\n", VINF_SUCCESS));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Lookups a device structure by name.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @internal
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncPPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTUINT cchName = strlen(pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pDev->cchName == cchName
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && !strcmp(pDev->pDevReg->szDeviceName, pszName))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Loads one device module and call the registration entry point.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @returns VBox status code.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pVM VM handle.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pRegCB The registration callback stuff.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pszFilename Module filename.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pszName Module name.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic int pdmR3DevLoad(PVM pVM, PPDMDEVREGCBINT pRegCB, const char *pszFilename, const char *pszName)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Load it.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = pdmR3LoadR3U(pVM->pUVM, pszFilename, pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Get the registration export and call it.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync FNPDMVBOXDEVICESREGISTER *pfnVBoxDevicesRegister;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR3(pVM, pszName, "VBoxDevicesRegister", (void **)&pfnVBoxDevicesRegister);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Calling VBoxDevicesRegister (%p) of %s (%s)\n", pfnVBoxDevicesRegister, pszName, pszFilename));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pfnVBoxDevicesRegister(&pRegCB->Core, VBOX_VERSION);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Successfully loaded device module %s (%s).\n", pszName, pszFilename));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("VBoxDevicesRegister failed with rc=%Vrc for module %s (%s)\n", rc, pszName, pszFilename));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to locate 'VBoxDevicesRegister' in %s (%s) rc=%Vrc\n", pszName, pszFilename, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_SYMBOL_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_NO_REGISTRATION_EXPORT;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to load %s %s!\n", pszFilename, pszName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Registers a device with the current VM instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @returns VBox status code.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pCallbacks Pointer to the callback table.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pDevReg Pointer to the device registration record.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * This data must be permanent and readonly.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate the registration structure.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pDevReg);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevReg->u32Version != PDM_DEVREG_VERSION)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Unknown struct version %#x!\n", pDevReg->u32Version));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_UNKNOWN_DEVREG_VERSION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pDevReg->szDeviceName[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || strlen(pDevReg->szDeviceName) >= sizeof(pDevReg->szDeviceName))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Invalid name '%s'\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_GC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && ( !pDevReg->szGCMod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || strlen(pDevReg->szGCMod) >= sizeof(pDevReg->szGCMod)))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Invalid GC module name '%s' - (Device %s)\n", pDevReg->szGCMod, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( (pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && ( !pDevReg->szR0Mod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || strlen(pDevReg->szR0Mod) >= sizeof(pDevReg->szR0Mod)))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Invalid R0 module name '%s' - (Device %s)\n", pDevReg->szR0Mod, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ((pDevReg->fFlags & PDM_DEVREG_FLAGS_HOST_BITS_MASK) != PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Invalid host bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_HOST_BITS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_MASK))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Invalid guest bits flags! fFlags=%#x (Device %s)\n", pDevReg->fFlags, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pDevReg->fClass)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No class! (Device %s)\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevReg->cMaxInstances <= 0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Max instances %u! (Device %s)\n", pDevReg->cMaxInstances, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevReg->cbInstance > (RTUINT)(pDevReg->fFlags & (PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0) ? 96 * _1K : _1M))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Instance size %d bytes! (Device %s)\n", pDevReg->cbInstance, pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pDevReg->pfnConstruct)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No constructore! (Device %s)\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_REGISTRATION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* Check matching guest bits last without any asserting. Enables trial and error registration. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!(pDevReg->fFlags & PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Rejected device '%s' because it didn't match the guest bits.\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_INVALID_DEVICE_GUEST_BITS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Check for duplicate and find FIFO entry at the same time.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCPDMDEVREGCBINT pRegCB = (PCPDMDEVREGCBINT)pCallbacks;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEV pDevPrev = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEV pDev = pRegCB->pVM->pdm.s.pDevs;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (; pDev; pDevPrev = pDev, pDev = pDev->pNext)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!strcmp(pDev->pDevReg->szDeviceName, pDevReg->szDeviceName))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Device '%s' already exists\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_DEVICE_NAME_CLASH;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allocate new device structure and insert it into the list.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev = (PPDMDEV)MMR3HeapAlloc(pRegCB->pVM, MM_TAG_PDM_DEVICE, sizeof(*pDev));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev->pNext = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev->cInstances = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev->pInstances = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev->pDevReg = pDevReg;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDev->cchName = strlen(pDevReg->szDeviceName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevPrev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevPrev->pNext = pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pRegCB->pVM->pdm.s.pDevs = pDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Registered device '%s'\n", pDevReg->szDeviceName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_NO_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allocate memory which is associated with current VM instance
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * and automatically freed on it's destruction.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pCallbacks Pointer to the callback table.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param cb Number of bytes to allocate.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevReg_MMHeapAlloc(PPDMDEVREGCB pCallbacks, size_t cb)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pCallbacks);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pCallbacks->u32Version == PDM_DEVREG_CB_VERSION);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevReg_MMHeapAlloc: cb=%#x\n", cb));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync void *pv = MMR3HeapAlloc(((PPDMDEVREGCBINT)pCallbacks)->pVM, MM_TAG_PDM_DEVICE_USER, cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevReg_MMHeapAlloc: returns %p\n", pv));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pv;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/**
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Queue consumer callback for internal component.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @returns Success indicator.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * If false the item will not be removed and the flushing will stop.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pVM The VM handle.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * @param pItem The item to consume. Upon return this item will be freed.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsHC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync switch (pTask->enmOp)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PDMDEVHLPTASKOP_ISA_SET_IRQ:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PDMDEVHLPTASKOP_PCI_SET_IRQ:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrq(pTask->pDevInsHC, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync default:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return true;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnIOPortRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 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,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMHC, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnIOPortRegisterGC */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszOut, const char *pszIn,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszOutStr, const char *pszInStr, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 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,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve the functions (one of the can be NULL).
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pDevIns->pDevReg->szGCMod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrIn = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszIn)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszIn, &GCPtrIn);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szGCMod, pszIn));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrOut = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszOut && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszOut, &GCPtrOut);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szGCMod, pszOut));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrInStr = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszInStr && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszInStr, &GCPtrInStr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szGCMod, pszInStr));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrOutStr = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszOutStr && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszOutStr, &GCPtrOutStr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szGCMod, pszOutStr));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = IOMR3IOPortRegisterGC(pDevIns->Internal.s.pVMHC, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No GC module for this driver!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnIOPortRegisterR0 */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszOut, const char *pszIn,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszOutStr, const char *pszInStr, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 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,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve the functions (one of the can be NULL).
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pDevIns->pDevReg->szR0Mod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszIn)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszOut && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszInStr && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszOutStr && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMHC, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No R0 module for this driver!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnIOPortDeregister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Port, cPorts));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMHC, pDevIns, Port, cPorts);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMIORegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMIORegisterGC */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszWrite, const char *pszRead, const char *pszFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve the functions.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Not all function have to present, leave it to IOM to enforce this.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pDevIns->pDevReg->szGCMod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrWrite = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszWrite)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszWrite, &GCPtrWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrRead = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc2 = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszRead)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc2 = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszRead, &GCPtrRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTGCPTR32 GCPtrFill = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc3 = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszFill)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc3 = PDMR3GetSymbolGCLazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szGCMod, pszFill, &GCPtrFill);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = IOMR3MMIORegisterGC(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szGCMod, pszWrite));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szGCMod, pszRead));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szGCMod, pszFill));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = rc2;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = rc3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No GC module for this driver!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMIORegisterR0 */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszWrite, const char *pszRead, const char *pszFill,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve the functions.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Not all function have to present, leave it to IOM to enforce this.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pDevIns->pDevReg->szR0Mod[0]
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszWrite)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc2 = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszRead)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc2 = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc3 = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pszFill)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc3 = PDMR3GetSymbolR0Lazy(pDevIns->Internal.s.pVMHC, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = rc2;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = rc3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No R0 module for this driver!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMIODeregister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnROMRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnSSMRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 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",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = SSMR3Register(pDevIns->Internal.s.pVMHC, pDevIns, pszName, u32Instance, u32Version, cbGuess,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pfnSavePrep, pfnSaveExec, pfnSaveDone,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pfnLoadPrep, pfnLoadExec, pfnLoadDone);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnTMTimerCreate */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMHC, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnTMTimerCreateExternal */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMHC, enmClock, pfnCallback, pvUser, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCIRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pPciDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciDev);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pPciDev->config[0] && !pPciDev->config[1])
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciDev->config[0] || pPciDev->config[1]);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevIns->Internal.s.pPciDeviceHC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * support a PDM device with multiple PCI devices. This might become a problem
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * when upgrading the chipset for instance...
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Only one PCI device per device is currently implemented!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INTERNAL_ERROR;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Choose the PCI bus for the device.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * This is simple. If the device was configured for a particular bus, it'll
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * already have one. If not, we'll just take the first one.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pBus)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pBus = pDevIns->Internal.s.pPciBusHC = &pVM->pdm.s.aPciBuses[0];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pBus)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pPciBusGC = MMHyperHC2GC(pVM, pDevIns->Internal.s.pPciBusHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Check the configuration for PCI device and function assignment.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int iDev = -1;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint8_t u8Device;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (u8Device > 31)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INTERNAL_ERROR;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync uint8_t u8Function;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (u8Function > 7)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INTERNAL_ERROR;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync iDev = (u8Device << 3) | u8Function;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Call the pci bus device to do the actual registration.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmLock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmUnlock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pPciDeviceHC = pPciDev;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pPciDeviceGC = MMHyperHC2GC(pVM, pPciDev);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pPciDeviceGC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciDev->pDevIns = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusHC->iBus));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_NO_PCI_BUS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCIIORegionRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync switch (enmType)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PCI_ADDRESS_SPACE_MEM:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PCI_ADDRESS_SPACE_IO:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync case PCI_ADDRESS_SPACE_MEM_PREFETCH:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync default:
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("enmType=%#x is unknown\n", enmType));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pfnCallback)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pfnCallback);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Must have a PCI device registered!
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPciDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * We're currently restricted to page aligned MMIO regions.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE)));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pBus);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmLock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmUnlock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("No PCI device registered!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_NOT_PCI_DEVICE;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCISetConfigCallbacks */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input and resolve defaults.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtr(pfnRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtr(pfnWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtrNull(ppfnReadOld);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtrNull(ppfnWriteOld);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertPtrNull(pPciDev);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pPciDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciDev = pDevIns->Internal.s.pPciDeviceHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertReleaseMsg(pPciDev, ("You must register your device first!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRelease(pBus);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Do the job.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmLock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmUnlock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCISetIrq */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** @todo iIrq and iLevel checks. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Must have a PCI device registered!
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPciDev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusHC; /** @todo the bus should be associated with the PCI device not the PDM device. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pBus);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmLock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmUnlock(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertReleaseMsgFailed(("No PCI device registered!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCISetIrqNoWait */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnISASetIrq */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /** @todo iIrq and iLevel checks. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnISASetIrqNoWait */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnDriverAttach */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Lookup the LUN, it might already be registered.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMLUN pLunPrev = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMLUN pLun = pDevIns->Internal.s.pLunsHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pLun->iLun == iLun)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Create the LUN if if wasn't found, else check if driver is already attached to it.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pLun)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pBaseInterface
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pszDesc
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !*pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pBaseInterface);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pszDesc || *pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pLun)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_NO_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->iLun = iLun;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pTop = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pBottom = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pDevIns = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pszDesc = pszDesc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pBase = pBaseInterface;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pLunPrev)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->Internal.s.pLunsHC = pLun;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLunPrev->pNext = pLun;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else if (pLun->pTop)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_PDM_DRIVER_ALREADY_ATTACHED;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pLun->pBase == pBaseInterface);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Get the attached driver configuration.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szNode[48];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pNode)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char *pszName;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Find the driver.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pDrv)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* config node */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config");
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pConfigNode)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync CFGMR3SetRestrictedRoot(pConfigNode);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allocate the driver instance.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync cb = RT_ALIGN_Z(cb, 16);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pNew)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Initialize the instance structure (declaration order).
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->u32Version = PDM_DRVINS_VERSION;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pNew->Internal.s.pUp = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pNew->Internal.s.pDown = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->Internal.s.pLun = pLun;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->Internal.s.pDrv = pDrv;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->Internal.s.pVM = pVM;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pNew->Internal.s.fDetaching = false;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->Internal.s.pCfgHandle = pNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->pDrvHlp = &g_pdmR3DrvHlp;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->pDrvReg = pDrv->pDrvReg;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->pCfgHandle = pConfigNode;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->iInstance = pDrv->cInstances++;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->pUpBase = pBaseInterface;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pNew->pDownBase = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync //pNew->IBase.pfnQueryInterface = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pNew->pvInstanceData = &pNew->achInstanceData[0];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Link with LUN and call the constructor.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pTop = pLun->pBottom = pNew;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync MMR3HeapFree(pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *ppBaseInterface = &pNew->IBase;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS) */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Free the driver.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pLun->pTop = pLun->pBottom = NULL;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ASMMemFill32(pNew, cb, 0xdeadd0d0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync MMR3HeapFree(pNew);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDrv->cInstances--;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_NO_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_DRIVER_NOT_FOUND;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync MMR3HeapFree(pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_CFG_MISSING_DRIVER_NAME;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_PDM_NO_ATTACHED_DRIVER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMHeapAlloc */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMHC, MM_TAG_PDM_DEVICE_USER, cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pv;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMHeapAllocZ */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMHC, MM_TAG_PDM_DEVICE_USER, cb);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pv;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnMMHeapFree */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync MMR3HeapFree(pv);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnVMSetError */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_list args;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_start(args, pszFormat);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMHC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_end(args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnVMSetErrorV */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMHC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnVMSetRuntimeError */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_list args;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_start(args, pszFormat);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMHC, fFatal, pszErrorID, pszFormat, args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_end(args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnVMSetRuntimeErrorV */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMHC, fFatal, pszErrorID, pszFormat, va);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnAssertEMT */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VM_IS_EMT(pDevIns->Internal.s.pVMHC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return true;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szMsg[100];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsg1(szMsg, iLine, pszFile, pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertBreakpoint();
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return false;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnAssertOther */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!VM_IS_EMT(pDevIns->Internal.s.pVMHC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return true;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync char szMsg[100];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsg1(szMsg, iLine, pszFile, pszFunction);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertBreakpoint();
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return false;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnDBGFStopV */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#ifdef LOG_ENABLED
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_list va2;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_copy(va2, args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_end(va2);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync#endif
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnDBGFInfoRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnSTAMRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync NOREF(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnSTAMRegisterF */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_list args;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_start(args, pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync va_end(args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRC(rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync NOREF(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnSTAMRegisterV */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertRC(rc);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync NOREF(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnRTCRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pRtcReg->pfnWrite, ppRtcHlp));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pRtcReg->u32Version != PDM_RTCREG_VERSION)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDM_RTCREG_VERSION));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pRtcReg->pfnWrite
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pRtcReg->pfnRead)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pRtcReg->pfnWrite);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pRtcReg->pfnRead);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!ppRtcHlp)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(ppRtcHlp);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Only one DMA device.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pVM->pdm.s.pRtc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Only one RTC device is supported!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Allocate and initialize pci bus structure.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMHC, MM_TAG_PDM_DEVICE, sizeof(*pRtc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pRtc)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pRtc->pDevIns = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pRtc->Reg = *pRtcReg;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.pRtc = pRtc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* set the helper pointer. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *ppRtcHlp = &g_pdmR3DevRtcHlp;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = VERR_NO_MEMORY;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPDMQueueCreate */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnCritSectInit */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnUTCNow */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pTime = TMR3UTCNow(pDevIns->Internal.s.pVMHC, pTime);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime)));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pTime;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPDMThreadCreate */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMHC, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc, *ppThread));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnGetVM */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMHC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPCIBusRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pVM);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, "
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate the structure.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pPciBusReg->pfnRegisterR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPciBusReg->pfnIORegionRegisterR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPciBusReg->pfnSetIrqR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPciBusReg->pfnSaveExecR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPciBusReg->pfnLoadExecR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPciBusReg->pfnFakePCIBIOSR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnRegisterR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnIORegionRegisterR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnSetIrqR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnSaveExecR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnLoadExecR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPciBusReg->pfnFakePCIBIOSR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pPciBusReg->pszSetIrqRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && !VALID_PTR(pPciBusReg->pszSetIrqRC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pPciBusReg->pszSetIrqRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pPciBusReg->pszSetIrqR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && !VALID_PTR(pPciBusReg->pszSetIrqR0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pPciBusReg->pszSetIrqR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!ppPciHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(ppPciHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Find free PCI bus entry.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync unsigned iBus = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync break;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve and init the RC bits.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPciBusReg->pszSetIrqRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pPciBusReg->pszSetIrqRC, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnSetIrqRC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pDevInsRC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Resolve and init the R0 bits.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPciBusReg->pszSetIrqR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnSetIrqR0 = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pDevInsR0 = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Init the R3 bits.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->iBus = iBus;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pDevInsR3 = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* set the helper pointer and return. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *ppPciHlpR3 = &g_pdmR3DevPciHlp;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnPICRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync 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",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ppPicHlpR3));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPicReg->u32Version != PDM_PICREG_VERSION)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pPicReg->pfnSetIrqR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pPicReg->pfnGetInterruptR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPicReg->pfnSetIrqR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pPicReg->pfnGetInterruptR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( ( pPicReg->pszSetIrqRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pPicReg->pszGetInterruptRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && ( !VALID_PTR(pPicReg->pszSetIrqRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pPicReg->pszGetInterruptRC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync )
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pPicReg->pszSetIrqRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pPicReg->pszGetInterruptRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pPicReg->pszSetIrqRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_GC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( pPicReg->pszSetIrqR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!ppPicHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(ppPicHlpR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Only one PIC device.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PVM pVM = pDevIns->Internal.s.pVMHC;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pVM->pdm.s.Pic.pDevInsR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("Only one pic device is supported!\n"));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * RC stuff.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPicReg->pszSetIrqRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pPicReg->pszSetIrqRC, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pPicReg->pszGetInterruptRC, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pDevInsRC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnSetIrqRC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnGetInterruptRC = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * R0 stuff.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pPicReg->pszSetIrqR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync int rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_SUCCESS(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (VBOX_FAILURE(rc))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return rc;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pVM->pdm.s.Pic.pDevInsR0);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync else
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnSetIrqR0 = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnGetInterruptR0 = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pDevInsR0 = 0;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * R3 stuff.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /* set the helper pointer and return. */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync *ppPicHlpR3 = &g_pdmR3DevPicHlp;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VINF_SUCCESS;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync}
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync/** @copydoc PDMDEVHLP::pfnAPICRegister */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsyncstatic DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync{
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync PDMDEV_ASSERT_DEVINS(pDevIns);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC,
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync pApicReg->pszBusDeliverRC, ppApicHlpR3));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync /*
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync * Validate input.
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync */
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (pApicReg->u32Version != PDM_APICREG_VERSION)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( !pApicReg->pfnGetInterruptR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnHasPendingIrqR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnSetBaseR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnGetBaseR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnSetTPRR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnGetTPRR3
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !pApicReg->pfnBusDeliverR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnGetInterruptR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnHasPendingIrqR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnSetBaseR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnGetBaseR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnSetTPRR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnGetTPRR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(pApicReg->pfnBusDeliverR3);
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( ( pApicReg->pszGetInterruptRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszHasPendingIrqRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszSetBaseRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszGetBaseRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszSetTPRRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszGetTPRRC
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszBusDeliverRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && ( !VALID_PTR(pApicReg->pszGetInterruptRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszHasPendingIrqRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszSetBaseRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszGetBaseRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszSetTPRRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszGetTPRRC)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszBusDeliverRC))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync )
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetInterruptRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszSetBaseRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetBaseRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszSetTPRRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetTPRRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if ( ( pApicReg->pszGetInterruptR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszHasPendingIrqR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszSetBaseR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszGetBaseR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszSetTPRR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszGetTPRR0
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || pApicReg->pszBusDeliverR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync && ( !VALID_PTR(pApicReg->pszGetInterruptR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszHasPendingIrqR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszSetBaseR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszGetBaseR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszSetTPRR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszGetTPRR0)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync || !VALID_PTR(pApicReg->pszBusDeliverR0))
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync )
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetInterruptR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszSetBaseR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetBaseR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszSetTPRR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszGetTPRR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync return VERR_INVALID_PARAMETER;
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync }
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync if (!ppApicHlpR3)
7b57f6ec6175ce1ee53e1ea49c24ff06f3723379vboxsync {
Assert(ppApicHlpR3);
LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Only one APIC device. (malc: only in UP case actually)
*/
PVM pVM = pDevIns->Internal.s.pVMHC;
if (pVM->pdm.s.Apic.pDevInsR3)
{
AssertMsgFailed(("Only one apic device is supported!\n"));
LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Resolve & initialize the RC bits.
*/
if (pApicReg->pszGetInterruptRC)
{
int rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszGetInterruptRC, rc));
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszHasPendingIrqRC, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszSetBaseRC, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszGetBaseRC, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszSetTPRRC, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszGetTPRRC, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pApicReg->pszBusDeliverRC, rc));
}
if (VBOX_FAILURE(rc))
{
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
}
else
{
pVM->pdm.s.Apic.pDevInsRC = 0;
pVM->pdm.s.Apic.pfnGetInterruptRC = 0;
pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0;
pVM->pdm.s.Apic.pfnSetBaseRC = 0;
pVM->pdm.s.Apic.pfnGetBaseRC = 0;
pVM->pdm.s.Apic.pfnSetTPRRC = 0;
pVM->pdm.s.Apic.pfnGetTPRRC = 0;
pVM->pdm.s.Apic.pfnBusDeliverRC = 0;
}
/*
* Resolve & initialize the R0 bits.
*/
if (pApicReg->pszGetInterruptR0)
{
int rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc));
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc));
}
if (RT_SUCCESS(rc))
{
rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));
}
if (VBOX_FAILURE(rc))
{
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
pVM->pdm.s.Apic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
Assert(pVM->pdm.s.Apic.pDevInsR0);
}
else
{
pVM->pdm.s.Apic.pfnGetInterruptR0 = 0;
pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0;
pVM->pdm.s.Apic.pfnSetBaseR0 = 0;
pVM->pdm.s.Apic.pfnGetBaseR0 = 0;
pVM->pdm.s.Apic.pfnSetTPRR0 = 0;
pVM->pdm.s.Apic.pfnGetTPRR0 = 0;
pVM->pdm.s.Apic.pfnBusDeliverR0 = 0;
pVM->pdm.s.Apic.pDevInsR0 = 0;
}
/*
* Initialize the HC bits.
*/
pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3;
pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3;
pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3;
pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3;
pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3;
pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3;
pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3;
Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
/* set the helper pointer and return. */
*ppApicHlpR3 = &g_pdmR3DevApicHlp;
LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
return VINF_SUCCESS;
}
/** @copydoc PDMDEVHLP::pfnIOAPICRegister */
static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3,
pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3));
/*
* Validate input.
*/
if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION)
{
AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if (!pIoApicReg->pfnSetIrqR3)
{
Assert(pIoApicReg->pfnSetIrqR3);
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if ( pIoApicReg->pszSetIrqRC
&& !VALID_PTR(pIoApicReg->pszSetIrqRC))
{
Assert(VALID_PTR(pIoApicReg->pszSetIrqRC));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if ( pIoApicReg->pszSetIrqR0
&& !VALID_PTR(pIoApicReg->pszSetIrqR0))
{
Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if (!ppIoApicHlpR3)
{
Assert(ppIoApicHlpR3);
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* The I/O APIC requires the APIC to be present (hacks++).
* If the I/O APIC does GC stuff so must the APIC.
*/
PVM pVM = pDevIns->Internal.s.pVMHC;
if (!pVM->pdm.s.Apic.pDevInsR3)
{
AssertMsgFailed(("Configuration error / Init order error! No APIC!\n"));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if ( pIoApicReg->pszSetIrqRC
&& !pVM->pdm.s.Apic.pDevInsRC)
{
AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n"));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Only one I/O APIC device.
*/
if (pVM->pdm.s.IoApic.pDevInsR3)
{
AssertMsgFailed(("Only one ioapic device is supported!\n"));
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Resolve & initialize the GC bits.
*/
if (pIoApicReg->pszSetIrqRC)
{
int rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szGCMod, pIoApicReg->pszSetIrqRC, rc));
if (VBOX_FAILURE(rc))
{
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
}
else
{
pVM->pdm.s.IoApic.pDevInsRC = 0;
pVM->pdm.s.IoApic.pfnSetIrqRC = 0;
}
/*
* Resolve & initialize the R0 bits.
*/
if (pIoApicReg->pszSetIrqR0)
{
int rc = PDMR3GetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);
AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc));
if (VBOX_FAILURE(rc))
{
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
pVM->pdm.s.IoApic.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
Assert(pVM->pdm.s.IoApic.pDevInsR0);
}
else
{
pVM->pdm.s.IoApic.pfnSetIrqR0 = 0;
pVM->pdm.s.IoApic.pDevInsR0 = 0;
}
/*
* Initialize the R3 bits.
*/
pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;
pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3;
Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
/* set the helper pointer and return. */
*ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp;
LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
return VINF_SUCCESS;
}
/** @copydoc PDMDEVHLP::pfnDMACRegister */
static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
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",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,
pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));
/*
* Validate input.
*/
if (pDmacReg->u32Version != PDM_DMACREG_VERSION)
{
AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,
PDM_DMACREG_VERSION));
LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if ( !pDmacReg->pfnRun
|| !pDmacReg->pfnRegister
|| !pDmacReg->pfnReadMemory
|| !pDmacReg->pfnWriteMemory
|| !pDmacReg->pfnSetDREQ
|| !pDmacReg->pfnGetChannelMode)
{
Assert(pDmacReg->pfnRun);
Assert(pDmacReg->pfnRegister);
Assert(pDmacReg->pfnReadMemory);
Assert(pDmacReg->pfnWriteMemory);
Assert(pDmacReg->pfnSetDREQ);
Assert(pDmacReg->pfnGetChannelMode);
LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
if (!ppDmacHlp)
{
Assert(ppDmacHlp);
LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Only one DMA device.
*/
PVM pVM = pDevIns->Internal.s.pVMHC;
if (pVM->pdm.s.pDmac)
{
AssertMsgFailed(("Only one DMA device is supported!\n"));
LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
return VERR_INVALID_PARAMETER;
}
/*
* Allocate and initialize pci bus structure.
*/
int rc = VINF_SUCCESS;
PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMHC, MM_TAG_PDM_DEVICE, sizeof(*pDmac));
if (pDmac)
{
pDmac->pDevIns = pDevIns;
pDmac->Reg = *pDmacReg;
pVM->pdm.s.pDmac = pDmac;
/* set the helper pointer. */
*ppDmacHlp = &g_pdmR3DevDmacHlp;
Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
}
else
rc = VERR_NO_MEMORY;
LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnPhysRead */
static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
/*
* For the convenience of the device we put no thread restriction on this interface.
* That means we'll have to check which thread we're in and choose our path.
*/
#ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD
PGMPhysRead(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbRead);
#else
if (VM_IS_EMT(pDevIns->Internal.s.pVMHC) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMHC))
PGMPhysRead(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbRead);
else
{
Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
PVMREQ pReq;
AssertCompileSize(RTGCPHYS, 4);
int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMHC, &pReq, RT_INDEFINITE_WAIT,
(PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbRead);
while (rc == VERR_TIMEOUT)
rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
AssertReleaseRC(rc);
VMR3ReqFree(pReq);
}
#endif
Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
}
/** @copydoc PDMDEVHLP::pfnPhysWrite */
static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
/*
* For the convenience of the device we put no thread restriction on this interface.
* That means we'll have to check which thread we're in and choose our path.
*/
#ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD
PGMPhysWrite(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbWrite);
#else
if (VM_IS_EMT(pDevIns->Internal.s.pVMHC) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMHC))
PGMPhysWrite(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbWrite);
else
{
Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
PVMREQ pReq;
AssertCompileSize(RTGCPHYS, 4);
int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMHC, &pReq, RT_INDEFINITE_WAIT,
(PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbWrite);
while (rc == VERR_TIMEOUT)
rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
AssertReleaseRC(rc);
VMR3ReqFree(pReq);
}
#endif
Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
}
/** @copydoc PDMDEVHLP::pfnPhysReadGCVirt */
static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb));
if (!VM_IS_EMT(pVM))
return VERR_ACCESS_DENIED;
int rc = PGMPhysReadGCPtr(pVM, pvDst, GCVirtSrc, cb);
LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnPhysWriteGCVirt */
static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb));
if (!VM_IS_EMT(pVM))
return VERR_ACCESS_DENIED;
int rc = PGMPhysWriteGCPtr(pVM, GCVirtDst, pvSrc, cb);
LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnPhysReserve */
static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc));
int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMHC, GCPhys, cbRange, pszDesc);
LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnPhysGCPtr2GCPhys */
static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys));
if (!VM_IS_EMT(pVM))
return VERR_ACCESS_DENIED;
int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys);
LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys));
return rc;
}
/** @copydoc PDMDEVHLP::pfnVMState */
static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
enmVMState, VMR3GetStateName(enmVMState)));
return enmVMState;
}
/** @copydoc PDMDEVHLP::pfnA20IsEnabled */
static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc));
return fRc;
}
/** @copydoc PDMDEVHLP::pfnA20Set */
static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable));
//Assert(*(unsigned *)&fEnable <= 1);
PGMR3PhysSetA20(pDevIns->Internal.s.pVMHC, fEnable);
}
/** @copydoc PDMDEVHLP::pfnVMReset */
static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET)));
/*
* We postpone this operation because we're likely to be inside a I/O instruction
* and the EIP will be updated when we return.
* We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.
*/
bool fHaltOnReset;
int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);
if (VBOX_SUCCESS(rc) && fHaltOnReset)
{
Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));
rc = VINF_EM_HALT;
}
else
{
VM_FF_SET(pVM, VM_FF_RESET);
rc = VINF_EM_RESET;
}
LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnVMSuspend */
static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
int rc = VMR3Suspend(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnVMPowerOff */
static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
int rc = VMR3PowerOff(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnLockVM */
static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns)
{
return VMMR3Lock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMDEVHLP::pfnUnlockVM */
static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns)
{
return VMMR3Unlock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMDEVHLP::pfnAssertVMLock */
static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
{
PVM pVM = pDevIns->Internal.s.pVMHC;
if (VMMR3LockIsOwner(pVM))
return true;
RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM);
RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner);
char szMsg[100];
RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName());
AssertMsg1(szMsg, iLine, pszFile, pszFunction);
AssertBreakpoint();
return false;
}
/** @copydoc PDMDEVHLP::pfnDMARegister */
static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));
int rc = VINF_SUCCESS;
if (pVM->pdm.s.pDmac)
pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser);
else
{
AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
rc = VERR_PDM_NO_DMAC_INSTANCE;
}
LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnDMAReadMemory */
static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));
int rc = VINF_SUCCESS;
if (pVM->pdm.s.pDmac)
{
uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
if (pcbRead)
*pcbRead = cb;
}
else
{
AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
rc = VERR_PDM_NO_DMAC_INSTANCE;
}
LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnDMAWriteMemory */
static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));
int rc = VINF_SUCCESS;
if (pVM->pdm.s.pDmac)
{
uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
if (pcbWritten)
*pcbWritten = cb;
}
else
{
AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
rc = VERR_PDM_NO_DMAC_INSTANCE;
}
LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnDMASetDREQ */
static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel));
int rc = VINF_SUCCESS;
if (pVM->pdm.s.pDmac)
pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);
else
{
AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
rc = VERR_PDM_NO_DMAC_INSTANCE;
}
LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnDMAGetChannelMode */
static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel));
uint8_t u8Mode;
if (pVM->pdm.s.pDmac)
u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);
else
{
AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
u8Mode = 3 << 2 /* illegal mode type */;
}
LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode));
return u8Mode;
}
/** @copydoc PDMDEVHLP::pfnDMASchedule */
static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA)));
AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
VM_FF_SET(pVM, VM_FF_PDM_DMA);
REMR3NotifyDmaPending(pVM);
VMR3NotifyFF(pVM, true);
}
/** @copydoc PDMDEVHLP::pfnCMOSWrite */
static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value));
int rc;
if (pVM->pdm.s.pRtc)
rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value);
else
rc = VERR_PDM_NO_RTC_INSTANCE;
LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnCMOSRead */
static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
VM_ASSERT_EMT(pVM);
LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value));
int rc;
if (pVM->pdm.s.pRtc)
rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value);
else
rc = VERR_PDM_NO_RTC_INSTANCE;
LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/** @copydoc PDMDEVHLP::pfnGetCpuId */
static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));
AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
CPUMGetGuestCpuId(pDevIns->Internal.s.pVMHC, iLeaf, pEax, pEbx, pEcx, pEdx);
LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));
}
/** @copydoc PDMDEVHLP::pfnROMProtectShadow */
static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));
int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMHC, GCPhysStart, cbRange);
LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/**
* @copydoc PDMDEVHLP::pfnMMIO2Register
*/
static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc));
int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMHC, pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/**
* @copydoc PDMDEVHLP::pfnMMIO2Deregister
*/
static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion));
AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);
int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMHC, pDevIns, iRegion);
LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/**
* @copydoc PDMDEVHLP::pfnMMIO2Map
*/
static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));
int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMHC, pDevIns, iRegion, GCPhys);
LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/**
* @copydoc PDMDEVHLP::pfnMMIO2Unmap
*/
static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));
int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMHC, pDevIns, iRegion, GCPhys);
LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
return rc;
}
/**
* @copydoc PDMDEVHLP::pfnMMHyperMapMMIO2
*/
static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
const char *pszDesc, PRTRCPTR pRCPtr)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMHC, pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr));
return rc;
}
/** @copydoc PDMDEVHLP::pfnGetVM */
static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return NULL;
}
/** @copydoc PDMDEVHLP::pfnPCIBusRegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pPciBusReg);
NOREF(ppPciHlpR3);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPICRegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pPicReg);
NOREF(ppPicHlpR3);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnAPICRegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pApicReg);
NOREF(ppApicHlpR3);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnIOAPICRegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pIoApicReg);
NOREF(ppIoApicHlpR3);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnDMACRegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pDmacReg);
NOREF(ppDmacHlp);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPhysRead */
static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCPhys);
NOREF(pvBuf);
NOREF(cbRead);
}
/** @copydoc PDMDEVHLP::pfnPhysWrite */
static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCPhys);
NOREF(pvBuf);
NOREF(cbWrite);
}
/** @copydoc PDMDEVHLP::pfnPhysReadGCVirt */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(pvDst);
NOREF(GCVirtSrc);
NOREF(cb);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPhysWriteGCVirt */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCVirtDst);
NOREF(pvSrc);
NOREF(cb);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPhysReserve */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCPhys);
NOREF(cbRange);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPhys2HCVirt */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCPhys);
NOREF(cbRange);
NOREF(ppvHC);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnPhysGCPtr2HCPtr */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(GCPtr);
NOREF(pHCPtr);
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnA20IsEnabled */
static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return false;
}
/** @copydoc PDMDEVHLP::pfnA20Set */
static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
NOREF(fEnable);
}
/** @copydoc PDMDEVHLP::pfnVMReset */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnVMSuspend */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnVMPowerOff */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnLockVM */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnUnlockVM */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnAssertVMLock */
static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return false;
}
/** @copydoc PDMDEVHLP::pfnDMARegister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnDMAReadMemory */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
if (pcbRead)
*pcbRead = 0;
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnDMAWriteMemory */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
if (pcbWritten)
*pcbWritten = 0;
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnDMASetDREQ */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnDMAGetChannelMode */
static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return 3 << 2 /* illegal mode type */;
}
/** @copydoc PDMDEVHLP::pfnDMASchedule */
static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
}
/** @copydoc PDMDEVHLP::pfnCMOSWrite */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnCMOSRead */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnQueryCPUId */
static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_QueryCPUId(PPDMDEVINS pDevIns, uint32_t iLeaf,
uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
}
/** @copydoc PDMDEVHLP::pfnROMProtectShadow */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnMMIO2Register */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnMMIO2Deregister */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnMMIO2Map */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnMMIO2Unmap */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMDEVHLP::pfnMMHyperMapMMIO2 */
static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return VERR_ACCESS_DENIED;
}
/** @copydoc PDMPICHLPR3::pfnSetInterruptFF */
static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_INTERRUPT_PIC)));
VM_FF_SET(pVM, VM_FF_INTERRUPT_PIC);
REMR3NotifyInterruptSet(pVM);
VMR3NotifyFF(pVM, true);
}
/** @copydoc PDMPICHLPR3::pfnClearInterruptFF */
static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC)));
VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC);
REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMPICHLPR3::pfnLock */
static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
}
/** @copydoc PDMPICHLPR3::pfnUnlock */
static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
pdmUnlock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMPICHLPR3::pfnGetRCHelpers */
static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
RTRCPTR pRCHelpers = 0;
int rc = PDMR3GetSymbolGC(pDevIns->Internal.s.pVMHC, NULL, "g_pdmRCPicHlp", &pRCHelpers);
AssertReleaseRC(rc);
AssertRelease(pRCHelpers);
LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
return pRCHelpers;
}
/** @copydoc PDMPICHLPR3::pfnGetR0Helpers */
static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
PCPDMPICHLPR0 pR0Helpers = 0;
int rc = PDMR3GetSymbolR0(pDevIns->Internal.s.pVMHC, NULL, "g_pdmR0PicHlp", &pR0Helpers);
AssertReleaseRC(rc);
AssertRelease(pR0Helpers);
LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
return pR0Helpers;
}
/** @copydoc PDMAPICHLPR3::pfnSetInterruptFF */
static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 1\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_INTERRUPT_APIC)));
VM_FF_SET(pVM, VM_FF_INTERRUPT_APIC);
REMR3NotifyInterruptSet(pVM);
VMR3NotifyFF(pVM, true);
}
/** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */
static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT %d -> 0\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC)));
VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC);
REMR3NotifyInterruptClear(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMAPICHLPR3::pfnChangeFeature */
static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: fEnabled=%RTbool\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnabled));
if (fEnabled)
CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
else
CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
}
/** @copydoc PDMAPICHLPR3::pfnLock */
static DECLCALLBACK(int) pdmR3ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
}
/** @copydoc PDMAPICHLPR3::pfnUnlock */
static DECLCALLBACK(void) pdmR3ApicHlp_Unlock(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
pdmUnlock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMAPICHLPR3::pfnGetCpuId */
static DECLCALLBACK(uint32_t) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
return VMMGetCpuId(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMAPICHLPR3::pfnGetRCHelpers */
static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
RTRCPTR pRCHelpers = 0;
int rc = PDMR3GetSymbolGC(pDevIns->Internal.s.pVMHC, NULL, "g_pdmRCApicHlp", &pRCHelpers);
AssertReleaseRC(rc);
AssertRelease(pRCHelpers);
LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
return pRCHelpers;
}
/** @copydoc PDMAPICHLPR3::pfnGetR0Helpers */
static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
PCPDMAPICHLPR0 pR0Helpers = 0;
int rc = PDMR3GetSymbolR0(pDevIns->Internal.s.pVMHC, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
AssertReleaseRC(rc);
AssertRelease(pR0Helpers);
LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
return pR0Helpers;
}
/** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */
static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
PVM pVM = pDevIns->Internal.s.pVMHC;
LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
if (pVM->pdm.s.Apic.pfnBusDeliverR3)
pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
}
/** @copydoc PDMIOAPICHLPR3::pfnLock */
static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
}
/** @copydoc PDMIOAPICHLPR3::pfnUnlock */
static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
pdmUnlock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMIOAPICHLPR3::pfnGetRCHelpers */
static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
RTRCPTR pRCHelpers = 0;
int rc = PDMR3GetSymbolGC(pDevIns->Internal.s.pVMHC, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
AssertReleaseRC(rc);
AssertRelease(pRCHelpers);
LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %VGv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
return pRCHelpers;
}
/** @copydoc PDMIOAPICHLPR3::pfnGetR0Helpers */
static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
PCPDMIOAPICHLPR0 pR0Helpers = 0;
int rc = PDMR3GetSymbolR0(pDevIns->Internal.s.pVMHC, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
AssertReleaseRC(rc);
AssertRelease(pR0Helpers);
LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
return pR0Helpers;
}
/** @copydoc PDMPCIHLPR3::pfnIsaSetIrq */
static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
PDMIsaSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
}
/** @copydoc PDMPCIHLPR3::pfnIoApicSetIrq */
static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
PDMIoApicSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
}
/** @copydoc PDMPCIHLPR3::pfnIsMMIO2Base */
static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMHC, pOwner, GCPhys);
Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
return fRc;
}
/** @copydoc PDMPCIHLPR3::pfnLock */
static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
}
/** @copydoc PDMPCIHLPR3::pfnUnlock */
static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
pdmUnlock(pDevIns->Internal.s.pVMHC);
}
/** @copydoc PDMPCIHLPR3::pfnGetRCHelpers */
static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
RTRCPTR pRCHelpers = 0;
int rc = PDMR3GetSymbolGC(pDevIns->Internal.s.pVMHC, NULL, "g_pdmRCPciHlp", &pRCHelpers);
AssertReleaseRC(rc);
AssertRelease(pRCHelpers);
LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
return pRCHelpers;
}
/** @copydoc PDMPCIHLPR3::pfnGetR0Helpers */
static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
{
PDMDEV_ASSERT_DEVINS(pDevIns);
VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
PCPDMPCIHLPR0 pR0Helpers = 0;
int rc = PDMR3GetSymbolR0(pDevIns->Internal.s.pVMHC, NULL, "g_pdmR0PciHlp", &pR0Helpers);
AssertReleaseRC(rc);
AssertRelease(pR0Helpers);
LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %VHv\n",
pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
return pR0Helpers;
}
/**
* Locates a LUN.
*
* @returns VBox status code.
* @param pVM VM Handle.
* @param pszDevice Device name.
* @param iInstance Device instance.
* @param iLun The Logical Unit to obtain the interface of.
* @param ppLun Where to store the pointer to the LUN if found.
* @thread Try only do this in EMT...
*/
int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun)
{
/*
* Iterate registered devices looking for the device.
*/
RTUINT cchDevice = strlen(pszDevice);
for (PPDMDEV pDev = pVM->pdm.s.pDevs; pDev; pDev = pDev->pNext)
{
if ( pDev->cchName == cchDevice
&& !memcmp(pDev->pDevReg->szDeviceName, pszDevice, cchDevice))
{
/*
* Iterate device instances.
*/
for (PPDMDEVINS pDevIns = pDev->pInstances; pDevIns; pDevIns = pDevIns->Internal.s.pPerDeviceNextHC)
{
if (pDevIns->iInstance == iInstance)
{
/*
* Iterate luns.
*/
for (PPDMLUN pLun = pDevIns->Internal.s.pLunsHC; pLun; pLun = pLun->pNext)
{
if (pLun->iLun == iLun)
{
*ppLun = pLun;
return VINF_SUCCESS;
}
}
return VERR_PDM_LUN_NOT_FOUND;
}
}
return VERR_PDM_DEVICE_INSTANCE_NOT_FOUND;
}
}
return VERR_PDM_DEVICE_NOT_FOUND;
}
/**
* Attaches a preconfigured driver to an existing device instance.
*
* This is used to change drivers and suchlike at runtime.
*
* @returns VBox status code.
* @param pVM VM Handle.
* @param pszDevice Device name.
* @param iInstance Device instance.
* @param iLun The Logical Unit to obtain the interface of.
* @param ppBase Where to store the base interface pointer. Optional.
* @thread EMT
*/
PDMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
{
VM_ASSERT_EMT(pVM);
LogFlow(("PDMR3DeviceAttach: pszDevice=%p:{%s} iInstance=%d iLun=%d ppBase=%p\n",
pszDevice, pszDevice, iInstance, iLun, ppBase));
/*
* Find the LUN in question.
*/
PPDMLUN pLun;
int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun);
if (VBOX_SUCCESS(rc))
{
/*
* Can we attach anything at runtime?
*/
PPDMDEVINS pDevIns = pLun->pDevIns;
if (pDevIns->pDevReg->pfnAttach)
{
if (!pLun->pTop)
{
rc = pDevIns->pDevReg->pfnAttach(pDevIns, iLun);
}
else
rc = VERR_PDM_DRIVER_ALREADY_ATTACHED;
}
else
rc = VERR_PDM_DEVICE_NO_RT_ATTACH;
if (ppBase)
*ppBase = pLun->pTop ? &pLun->pTop->IBase : NULL;
}
else if (ppBase)
*ppBase = NULL;
if (ppBase)
LogFlow(("PDMR3DeviceAttach: returns %Vrc *ppBase=%p\n", rc, *ppBase));
else
LogFlow(("PDMR3DeviceAttach: returns %Vrc\n", rc));
return rc;
}
/**
* Detaches a driver chain from an existing device instance.
*
* This is used to change drivers and suchlike at runtime.
*
* @returns VBox status code.
* @param pVM VM Handle.
* @param pszDevice Device name.
* @param iInstance Device instance.
* @param iLun The Logical Unit to obtain the interface of.
* @thread EMT
*/
PDMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun)
{
VM_ASSERT_EMT(pVM);
LogFlow(("PDMR3DeviceDetach: pszDevice=%p:{%s} iInstance=%d iLun=%d\n",
pszDevice, pszDevice, iInstance, iLun));
/*
* Find the LUN in question.
*/
PPDMLUN pLun;
int rc = pdmR3DevFindLun(pVM, pszDevice, iInstance, iLun, &pLun);
if (VBOX_SUCCESS(rc))
{
/*
* Can we detach anything at runtime?
*/
PPDMDEVINS pDevIns = pLun->pDevIns;
if (pDevIns->pDevReg->pfnDetach)
{
if (pLun->pTop)
rc = pdmR3DrvDetach(pLun->pTop);
else
rc = VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN;
}
else
rc = VERR_PDM_DEVICE_NO_RT_DETACH;
}
LogFlow(("PDMR3DeviceDetach: returns %Vrc\n", rc));
return rc;
}