Logo Search packages:      
Sourcecode: virtualbox-ose version File versions

PDMInternal.h

Go to the documentation of this file.
/* $Id: PDMInternal.h 4071 2007-08-07 17:07:59Z vboxsync $ */
/** @file
 * PDM - Internal header file.
 */

/*
 * Copyright (C) 2006-2007 innotek GmbH
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation,
 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
 * distribution. VirtualBox OSE is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#ifndef ___PDMInternal_h
#define ___PDMInternal_h

#include <VBox/cdefs.h>
#include <VBox/types.h>
#include <VBox/param.h>
#include <VBox/cfgm.h>
#include <VBox/stam.h>
#include <iprt/critsect.h>
#ifdef IN_RING3
# include <iprt/thread.h>
#endif

__BEGIN_DECLS


/** @defgroup grp_pdm_int       Internal
 * @ingroup grp_pdm
 * @internal
 * @{
 */

/*******************************************************************************
*   Structures and Typedefs                                                    *
*******************************************************************************/

/** Pointer to a PDM Device. */
00045 typedef struct PDMDEV *PPDMDEV;
/** Pointer to a pointer to a PDM Device. */
00047 typedef PPDMDEV *PPPDMDEV;

/** Pointer to a PDM USB Device. */
00050 typedef struct PDMUSB *PPDMUSB;
/** Pointer to a pointer to a PDM USB Device. */
00052 typedef PPDMUSB *PPPDMUSB;

/** Pointer to a PDM Driver. */
00055 typedef struct PDMDRV *PPDMDRV;
/** Pointer to a pointer to a PDM Driver. */
00057 typedef PPDMDRV *PPPDMDRV;

/** Pointer to a PDM Logical Unit. */
00060 typedef struct PDMLUN *PPDMLUN;
/** Pointer to a pointer to a PDM Logical Unit. */
00062 typedef PPDMLUN *PPPDMLUN;

/** Pointer to a PDM PCI Bus instance. */
00065 typedef struct PDMPCIBUS *PPDMPCIBUS;
/** Pointer to a DMAC instance. */
00067 typedef struct PDMDMAC *PPDMDMAC;
/** Pointer to a RTC instance. */
00069 typedef struct PDMRTC *PPDMRTC;

/** Pointer to an USB HUB registration record. */
00072 typedef struct PDMUSBHUB *PPDMUSBHUB;

/**
 * Private device instance data.
 */
00077 typedef struct PDMDEVINSINT
{
    /** Pointer to the next instance (HC Ptr).
     * (Head is pointed to by PDM::pDevInstances.) */
    HCPTRTYPE(PPDMDEVINS)           pNextHC;
    /** Pointer to the next per device instance (HC Ptr).
     * (Head is pointed to by PDMDEV::pInstances.) */
    HCPTRTYPE(PPDMDEVINS)           pPerDeviceNextHC;

    /** Pointer to device structure - HC Ptr. */
    HCPTRTYPE(PPDMDEV)              pDevHC;

    /** Pointer to the VM this instance was created for - HC Ptr. */
    HCPTRTYPE(PVM)                  pVMHC;
    /** Pointer to the list of logical units associated with the device. (FIFO) */
    HCPTRTYPE(PPDMLUN)              pLunsHC;
    /** Configuration handle to the instance node. */
    HCPTRTYPE(PCFGMNODE)            pCfgHandle;
    /** HC pointer to associated PCI device structure. */
    HCPTRTYPE(struct PCIDevice *)   pPciDeviceHC;
    /** HC pointer to associated PCI bus structure. */
    HCPTRTYPE(PPDMPCIBUS)           pPciBusHC;

    /** GC pointer to associated PCI device structure. */
    GCPTRTYPE(struct PCIDevice *)   pPciDeviceGC;
    /** Pointer to the VM this instance was created for - GC Ptr. */
    GCPTRTYPE(PVM)                  pVMGC;
    /** GC pointer to associated PCI bus structure. */
    GCPTRTYPE(PPDMPCIBUS)           pPciBusGC;
#if GC_ARCH_BITS == 32
    uint32_t                        Alignment0;
#endif
} PDMDEVINSINT;


/**
 * Private USB device instance data.
 */
00115 typedef struct PDMUSBINSINT
{
    /** Pointer to the next instance.
     * (Head is pointed to by PDM::pUsbInstances.) */
    R3PTRTYPE(PPDMUSBINS)           pNext;
    /** Pointer to the next per USB device instance.
     * (Head is pointed to by PDMUSB::pInstances.) */
    R3PTRTYPE(PPDMUSBINS)           pPerDeviceNext;

    /** Pointer to device structure. */
    R3PTRTYPE(PPDMUSB)              pUsb;

    /** Pointer to the VM this instance was created for. */
00128     PVMR3                           pVM;
    /** Pointer to the list of logical units associated with the device. (FIFO) */
    R3PTRTYPE(PPDMLUN)              pLuns;
    /** The per instance device configuration. */
    R3PTRTYPE(PCFGMNODE)            pCfg;
    /** The global device configuration. */
    R3PTRTYPE(PCFGMNODE)            pCfgGlobal;

    /** Pointer to the USB hub this device is connected to. */
    R3PTRTYPE(PPDMUSBHUB)           pHub;
    /** The port number that we're connected to. */
00139     uint32_t                        iPort;
#if HC_ARCH_BITS == 64
    uint32_t                        Alignment0;
#endif
} PDMUSBINSINT;


/**
 * Private driver instance data.
 */
00149 typedef struct PDMDRVINSINT
{
    /** Pointer to the driver instance above.
     * This is NULL for the topmost drive. */
00153     PPDMDRVINS          pUp;
    /** Pointer to the driver instance below.
     * This is NULL for the bottommost driver. */
00156     PPDMDRVINS          pDown;
    /** Pointer to the logical unit this driver chained on. */
00158     PPDMLUN             pLun;
    /** Pointer to driver structure from which this was instantiated. */
00160     PPDMDRV             pDrv;
    /** Pointer to the VM this instance was created for. */
00162     PVM                 pVM;
    /** Flag indicating that the driver is being detached and destroyed.
     * (Helps detect potential recursive detaching.) */
00165     bool                fDetaching;
    /** Configuration handle to the instance node. */
00167     PCFGMNODE           pCfgHandle;

} PDMDRVINSINT;


/**
 * Private critical section data.
 */
00175 typedef struct PDMCRITSECTINT
{
    /** The critical section core which is shared with IPRT. */
00178     RTCRITSECT          Core;
    /** Pointer to the next critical section.
     * This chain is used for relocating pVMGC and device cleanup. */
    R3PTRTYPE(struct PDMCRITSECTINT *) pNext;
    /** Owner identifier.
     * This is pDevIns if the owner is a device. Similarily for a driver or service.
     * PDMR3CritSectInit() sets this to point to the critsect itself. */
00185     RTR3PTR             pvKey;
    /** Pointer to the VM - R3Ptr. */
    R3PTRTYPE(PVM)      pVMR3;
    /** Pointer to the VM - R0Ptr. */
    R0PTRTYPE(PVM)      pVMR0;
    /** Pointer to the VM - GCPtr. */
    GCPTRTYPE(PVM)      pVMGC;
#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32
    uint32_t            padding;
#endif
    /** Event semaphore that is scheduled to be signaled upon leaving the
     * critical section. This is Ring-3 only of course. */
00197     RTSEMEVENT          EventToSignal;
    /** R0/GC lock contention. */
00199     STAMCOUNTER         StatContentionR0GCLock;
    /** R0/GC unlock contention. */
00201     STAMCOUNTER         StatContentionR0GCUnlock;
    /** R3 lock contention. */
00203     STAMCOUNTER         StatContentionR3;
    /** Profiling the time the section is locked. */
00205     STAMPROFILEADV      StatLocked;
} PDMCRITSECTINT, *PPDMCRITSECTINT;


/**
 * The usual device/driver/internal/external stuff.
 */
00212 typedef enum
{
    /** The usual invalid entry. */
00215     PDMTHREADTYPE_INVALID = 0,
    /** Device type. */
00217     PDMTHREADTYPE_DEVICE,
    /** USB Device type. */
00219     PDMTHREADTYPE_USB,
    /** Driver type. */
00221     PDMTHREADTYPE_DRIVER,
    /** Internal type. */
00223     PDMTHREADTYPE_INTERNAL,
    /** External type. */
00225     PDMTHREADTYPE_EXTERNAL,
    /** The usual 32-bit hack. */
00227     PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
} PDMTHREADTYPE;


/**
 * The internal structure for the thread.
 */
00234 typedef struct PDMTHREADINT
{
    /** The VM pointer. */
00237     PVMR3                           pVM;
    /** The event semaphore the thread blocks on. */
00239     RTSEMEVENTMULTI                 BlockEvent;
    /** Pointer to the next thread. */
    R3PTRTYPE(struct PDMTHREAD *)   pNext;
    /** The thread type. */
00243     PDMTHREADTYPE                   enmType;
} PDMTHREADINT;



/* Must be included after PDMDEVINSINT is defined. */
#define PDMDEVINSINT_DECLARED
#define PDMUSBINSINT_DECLARED
#define PDMDRVINSINT_DECLARED
#define PDMCRITSECTINT_DECLARED
#define PDMTHREADINT_DECLARED
#ifdef ___VBox_pdm_h
# error "Invalid header PDM order. Include PDMInternal.h before VBox/pdm.h!"
#endif
__END_DECLS
#include <VBox/pdm.h>
__BEGIN_DECLS

/**
 * PDM Logical Unit.
 *
 * This typically the representation of a physical port on a
 * device, like for instance the PS/2 keyboard port on the
 * keyboard controller device. The LUNs are chained on the
 * device the belong to (PDMDEVINSINT::pLunsHC).
 */
00269 typedef struct PDMLUN
{
    /** The LUN - The Logical Unit Number. */
00272     RTUINT              iLun;
    /** Pointer to the next LUN. */
00274     PPDMLUN             pNext;
    /** Pointer to the top driver in the driver chain. */
00276     PPDMDRVINS          pTop;
    /** Pointer to the device instance which the LUN belongs to.
     * Either this is set or pUsbIns is set. Both is never set at the same time. */
00279     PPDMDEVINS          pDevIns;
    /** Pointer to the USB device instance which the LUN belongs to. */
00281     PPDMUSBINS          pUsbIns;
    /** Pointer to the device base interface. */
00283     PPDMIBASE           pBase;
    /** Description of this LUN. */
00285     const char         *pszDesc;
} PDMLUN;


/**
 * PDM Device.
 */
00292 typedef struct PDMDEV
{
    /** Pointer to the next device (HC Ptr). */
    HCPTRTYPE(PPDMDEV)                  pNext;
    /** Device name length. (search optimization) */
00297     RTUINT                              cchName;
    /** Registration structure. */
    HCPTRTYPE(const struct PDMDEVREG *) pDevReg;
    /** Number of instances. */
00301     RTUINT                              cInstances;
    /** Pointer to chain of instances (HC Ptr). */
    HCPTRTYPE(PPDMDEVINS)               pInstances;
} PDMDEV;


/**
 * PDM USB Device.
 */
00310 typedef struct PDMUSB
{
    /** Pointer to the next device (R3 Ptr). */
    R3PTRTYPE(PPDMUSB)                  pNext;
    /** Device name length. (search optimization) */
00315     RTUINT                              cchName;
    /** Registration structure. */
    R3PTRTYPE(const struct PDMUSBREG *) pUsbReg;
    /** Next instance number. */
00319     RTUINT                              iNextInstance;
    /** Pointer to chain of instances (R3 Ptr). */
    R3PTRTYPE(PPDMUSBINS)               pInstances;
} PDMUSB;


/**
 * PDM Driver.
 */
00328 typedef struct PDMDRV
{
    /** Pointer to the next device. */
00331     PPDMDRV                             pNext;
    /** Registration structure. */
00333     const struct PDMDRVREG *            pDrvReg;
    /** Number of instances. */
00335     RTUINT                              cInstances;
} PDMDRV;


/**
 * PDM registered PIC device.
 */
00342 typedef struct PDMPIC
{
    /** Pointer to the PIC device instance - HC. */
    HCPTRTYPE(PPDMDEVINS)   pDevInsR3;
    /** @copydoc PDMPICREG::pfnSetIrqHC */
    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    /** @copydoc PDMPICREG::pfnGetInterruptHC */
    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));

    /** Pointer to the PIC device instance - R0. */
    R0PTRTYPE(PPDMDEVINS)   pDevInsR0;
    /** @copydoc PDMPICREG::pfnSetIrqHC */
    DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    /** @copydoc PDMPICREG::pfnGetInterruptHC */
    DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns));

    /** Pointer to the PIC device instance - GC. */
    GCPTRTYPE(PPDMDEVINS)   pDevInsGC;
    /** @copydoc PDMPICREG::pfnSetIrqHC */
    DECLGCCALLBACKMEMBER(void, pfnSetIrqGC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    /** @copydoc PDMPICREG::pfnGetInterruptHC */
    DECLGCCALLBACKMEMBER(int, pfnGetInterruptGC,(PPDMDEVINS pDevIns));
#if GC_ARCH_BITS == 32
    RTGCPTR                         GCPtrPadding; /**< Alignment padding. */
#endif
} PDMPIC;


/**
 * PDM registered APIC device.
 */
00373 typedef struct PDMAPIC
{
    /** Pointer to the APIC device instance - HC Ptr. */
00376     PPDMDEVINSHC                    pDevInsR3;
    /** @copydoc PDMAPICREG::pfnGetInterruptHC */
    DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetBaseHC */
    DECLR3CALLBACKMEMBER(void,      pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
    /** @copydoc PDMAPICREG::pfnGetBaseHC */
    DECLR3CALLBACKMEMBER(uint64_t,  pfnGetBaseR3,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetTPRHC */
    DECLR3CALLBACKMEMBER(void,      pfnSetTPRR3,(PPDMDEVINS pDevIns, uint8_t u8TPR));
    /** @copydoc PDMAPICREG::pfnGetTPRHC */
    DECLR3CALLBACKMEMBER(uint8_t,   pfnGetTPRR3,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnBusDeliverHC */
    DECLR3CALLBACKMEMBER(void,      pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));

    /** Pointer to the PIC device instance - R0. */
    R0PTRTYPE(PPDMDEVINS)           pDevInsR0;
    /** @copydoc PDMAPICREG::pfnGetInterruptHC */
    DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetBaseHC */
    DECLR0CALLBACKMEMBER(void,      pfnSetBaseR0,(PPDMDEVINS pDevIns, uint64_t u64Base));
    /** @copydoc PDMAPICREG::pfnGetBaseHC */
    DECLR0CALLBACKMEMBER(uint64_t,  pfnGetBaseR0,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetTPRHC */
    DECLR0CALLBACKMEMBER(void,      pfnSetTPRR0,(PPDMDEVINS pDevIns, uint8_t u8TPR));
    /** @copydoc PDMAPICREG::pfnGetTPRHC */
    DECLR0CALLBACKMEMBER(uint8_t,   pfnGetTPRR0,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnBusDeliverHC */
    DECLR0CALLBACKMEMBER(void,      pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));

    /** Pointer to the APIC device instance - GC Ptr. */
00408     PPDMDEVINSGC                    pDevInsGC;
    /** @copydoc PDMAPICREG::pfnGetInterruptHC */
    DECLGCCALLBACKMEMBER(int,       pfnGetInterruptGC,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetBaseHC */
    DECLGCCALLBACKMEMBER(void,      pfnSetBaseGC,(PPDMDEVINS pDevIns, uint64_t u64Base));
    /** @copydoc PDMAPICREG::pfnGetBaseHC */
    DECLGCCALLBACKMEMBER(uint64_t,  pfnGetBaseGC,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnSetTPRHC */
    DECLGCCALLBACKMEMBER(void,      pfnSetTPRGC,(PPDMDEVINS pDevIns, uint8_t u8TPR));
    /** @copydoc PDMAPICREG::pfnGetTPRHC */
    DECLGCCALLBACKMEMBER(uint8_t,   pfnGetTPRGC,(PPDMDEVINS pDevIns));
    /** @copydoc PDMAPICREG::pfnBusDeliverHC */
    DECLGCCALLBACKMEMBER(void,      pfnBusDeliverGC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
#if GC_ARCH_BITS == 32
    RTGCPTR                         GCPtrPadding; /**< Alignment padding. */
#endif
} PDMAPIC;


/**
 * PDM registered I/O APIC device.
 */
00431 typedef struct PDMIOAPIC
{
    /** Pointer to the APIC device instance - HC Ptr. */
00434     PPDMDEVINSHC                    pDevInsR3;
    /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));

    /** Pointer to the PIC device instance - R0. */
    R0PTRTYPE(PPDMDEVINS)   pDevInsR0;
    /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));

    /** Pointer to the APIC device instance - GC Ptr. */
00444     PPDMDEVINSGC                    pDevInsGC;
    /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
    DECLGCCALLBACKMEMBER(void,      pfnSetIrqGC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
} PDMIOAPIC;


/**
 * PDM PCI Bus instance.
 */
00453 typedef struct PDMPCIBUS
{
    /** PCI bus number. */
00456     RTUINT          iBus;
00457     RTUINT          uPadding0; /**< Alignment padding.*/

    /** Pointer to PCI Bus device instance. */
00460     PPDMDEVINSHC                    pDevInsR3;
    /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
    /** @copydoc PDMPCIBUSREG::pfnRegisterHC */
    DECLR3CALLBACKMEMBER(int,       pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
    /** @copydoc PDMPCIBUSREG::pfnIORegionRegisterHC */
    DECLR3CALLBACKMEMBER(int,       pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion,
                                                           PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
    /** @copydoc PDMPCIBUSREG::pfnSetConfigCallbacksHC */
    DECLR3CALLBACKMEMBER(void,      pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead,
                                                             PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
    /** @copydoc PDMPCIBUSREG::pfnSaveExecHC */
    DECLR3CALLBACKMEMBER(int,       pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
    /** @copydoc PDMPCIBUSREG::pfnLoadExecHC */
    DECLR3CALLBACKMEMBER(int,       pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
    /** @copydoc PDMPCIBUSREG::pfnFakePCIBIOSHC */
    DECLR3CALLBACKMEMBER(int,       pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));

    /** Pointer to the PIC device instance - R0. */
    R0PTRTYPE(PPDMDEVINS)           pDevInsR0;
    /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));

    /** Pointer to PCI Bus device instance. */
00484     PPDMDEVINSGC                    pDevInsGC;
    /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
    DECLGCCALLBACKMEMBER(void,      pfnSetIrqGC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
} PDMPCIBUS;


#ifdef IN_RING3
/**
 * PDM registered DMAC (DMA Controller) device.
 */
typedef struct PDMDMAC
{
    /** Pointer to the DMAC device instance. */
    PPDMDEVINS      pDevIns;
    /** Copy of the registration structure. */
    PDMDMACREG      Reg;
} PDMDMAC;


/**
 * PDM registered RTC (Real Time Clock) device.
 */
typedef struct PDMRTC
{
    /** Pointer to the RTC device instance. */
    PPDMDEVINS      pDevIns;
    /** Copy of the registration structure. */
    PDMRTCREG       Reg;
} PDMRTC;

#endif /* IN_RING3 */

/**
 * Module type.
 */
00519 typedef enum PDMMODTYPE
{
    /** Guest context module. */
00522     PDMMOD_TYPE_GC,
    /** Ring-0 (host) context module. */
00524     PDMMOD_TYPE_R0,
    /** Ring-3 (host) context module. */
00526     PDMMOD_TYPE_R3
} PDMMODTYPE, *PPDMMODTYPE;


/** The module name length including the terminator. */
00531 #define PDMMOD_NAME_LEN     32

/**
 * Loaded module instance.
 */
00536 typedef struct PDMMOD
{
    /** Module name. This is used for refering to
     * the module internally, sort of like a handle. */
00540     char            szName[PDMMOD_NAME_LEN];
    /** Module type. */
00542     PDMMODTYPE      eType;
    /** Loader module handle. Not used for R0 modules. */
00544     RTLDRMOD        hLdrMod;
    /** Loaded address.
     * This is the 'handle' for R0 modules. */
00547     RTUINTPTR       ImageBase;
    /** Old loaded address.
     * This is used during relocation of GC modules. Not used for R0 modules. */
00550     RTUINTPTR       OldImageBase;
    /** Where the R3 HC bits are stored.
     * This can be equal to ImageBase but doesn't have to. Not used for R0 modules. */
00553     void           *pvBits;

    /** Pointer to next module. */
00556     struct PDMMOD  *pNext;
    /** Module filename. */
00558     char            szFilename[1];
} PDMMOD;
/** Pointer to loaded module instance. */
00561 typedef PDMMOD *PPDMMOD;



/** Extra space in the free array. */
00566 #define PDMQUEUE_FREE_SLACK     16

/**
 * Queue type.
 */
00571 typedef enum PDMQUEUETYPE
{
    /** Device consumer. */
00574     PDMQUEUETYPE_DEV = 1,
    /** Driver consumer. */
00576     PDMQUEUETYPE_DRV,
    /** Internal consumer. */
00578     PDMQUEUETYPE_INTERNAL,
    /** External consumer. */
00580     PDMQUEUETYPE_EXTERNAL
} PDMQUEUETYPE;

/** Pointer to a PDM Queue. */
00584 typedef struct PDMQUEUE *PPDMQUEUE;

/**
 * PDM Queue.
 */
00589 typedef struct PDMQUEUE
{
    /** Pointer to the next queue in the list. */
    HCPTRTYPE(PPDMQUEUE)    pNext;
    /** Type specific data. */
    union
    {
        /** PDMQUEUETYPE_DEV */
        struct
        {
            /** Pointer to consumer function. */
            HCPTRTYPE(PFNPDMQUEUEDEV)   pfnCallback;
            /** Pointer to the device instance owning the queue. */
            HCPTRTYPE(PPDMDEVINS)       pDevIns;
        } Dev;
        /** PDMQUEUETYPE_DRV */
        struct
        {
            /** Pointer to consumer function. */
            HCPTRTYPE(PFNPDMQUEUEDRV)   pfnCallback;
            /** Pointer to the driver instance owning the queue. */
            HCPTRTYPE(PPDMDRVINS)       pDrvIns;
        } Drv;
        /** PDMQUEUETYPE_INTERNAL */
        struct
        {
            /** Pointer to consumer function. */
            HCPTRTYPE(PFNPDMQUEUEINT)   pfnCallback;
        } Int;
        /** PDMQUEUETYPE_EXTERNAL */
        struct
        {
            /** Pointer to consumer function. */
            HCPTRTYPE(PFNPDMQUEUEEXT)   pfnCallback;
            /** Pointer to user argument. */
            HCPTRTYPE(void *)           pvUser;
        } Ext;
    } u;
    /** Queue type. */
00628     PDMQUEUETYPE                            enmType;
    /** The interval between checking the queue for events.
     * The realtime timer below is used to do the waiting.
     * If 0, the queue will use the VM_FF_PDM_QUEUE forced action. */
00632     uint32_t                                cMilliesInterval;
    /** Interval timer. Only used if cMilliesInterval is non-zero. */
00634     PTMTIMERHC                              pTimer;
    /** Pointer to the VM. */
    HCPTRTYPE(PVM)                          pVMHC;
    /** LIFO of pending items - HC. */
    HCPTRTYPE(PPDMQUEUEITEMCORE) volatile   pPendingHC;
    /** Pointer to the GC VM and indicator for GC enabled queue.
     * If this is NULL, the queue cannot be used in GC.
     */
    GCPTRTYPE(PVM)                          pVMGC;
    /** LIFO of pending items - GC. */
    GCPTRTYPE(PPDMQUEUEITEMCORE)            pPendingGC;
    /** Item size (bytes). */
00646     RTUINT                                  cbItem;
    /** Number of items in the queue. */
00648     RTUINT                                  cItems;
    /** Index to the free head (where we insert). */
00650     uint32_t volatile                       iFreeHead;
    /** Index to the free tail (where we remove). */
00652     uint32_t volatile                       iFreeTail;
    /** Array of pointers to free items. Variable size. */
00654     struct PDMQUEUEFREEITEM
    {
        /** Pointer to the free item - HC Ptr. */
        HCPTRTYPE(PPDMQUEUEITEMCORE) volatile pItemHC;
        /** Pointer to the free item - GC Ptr. */
        GCPTRTYPE(PPDMQUEUEITEMCORE) volatile pItemGC;
#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32
        uint32_t                              Alignment0;
#endif
    }                                       aFreeItems[1];
} PDMQUEUE;


/**
 * Queue device helper task operation.
 */
00670 typedef enum PDMDEVHLPTASKOP
{
    /** The usual invalid 0 entry. */
00673     PDMDEVHLPTASKOP_INVALID = 0,
    /** ISASetIrq */
00675     PDMDEVHLPTASKOP_ISA_SET_IRQ,
    /** PCISetIrq */
00677     PDMDEVHLPTASKOP_PCI_SET_IRQ,
    /** PCISetIrq */
00679     PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
    /** The usual 32-bit hack. */
00681     PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
} PDMDEVHLPTASKOP;

/**
 * Queued Device Helper Task.
 */
00687 typedef struct PDMDEVHLPTASK
{
    /** The queue item core (don't touch). */
00690     PDMQUEUEITEMCORE        Core;
    /** Pointer to the device instance (HC Ptr). */
    HCPTRTYPE(PPDMDEVINS)   pDevInsHC;
    /** This operation to perform. */
00694     PDMDEVHLPTASKOP         enmOp;
#if HC_ARCH_BITS == 64
    uint32_t                Alignment0;
#endif
    /** Parameters to the operation. */
00699     union PDMDEVHLPTASKPARAMS
    {
        /**
         * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_PCI_SET_IRQ.
         */
00704         struct PDMDEVHLPTASKSETIRQ
        {
            /** The IRQ */
00707             int iIrq;
            /** The new level. */
00709             int iLevel;
        } SetIRQ;
    } u;
} PDMDEVHLPTASK;
/** Pointer to a queued Device Helper Task. */
00714 typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
/** Pointer to a const queued Device Helper Task. */
00716 typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;



/**
 * An USB hub registration record.
 */
00723 typedef struct PDMUSBHUB
{
    /** The USB versions this hub support.
     * Note that 1.1 hubs can take on 2.0 devices. */
00727     uint32_t            fVersions;
    /** The number of occupied ports. */
00729     uint32_t            cAvailablePorts;
    /** Pointer to the next hub in the list. */
00731     struct PDMUSBHUB   *pNext;
    /** The driver instance of the hub.. */
00733     PPDMDRVINS          pDrvIns;

} PDMUSBHUB;

/** Pointer to a const USB HUB registration record. */
00738 typedef const PDMUSBHUB *PCPDMUSBHUB;


/**
 * Converts a PDM pointer into a VM pointer.
 * @returns Pointer to the VM structure the PDM is part of.
 * @param   pPDM   Pointer to PDM instance data.
 */
00746 #define PDM2VM(pPDM)  ( (PVM)((char*)pPDM - pPDM->offVM) )


/**
 * PDM VM Instance data.
 * Changes to this must checked against the padding of the cfgm union in VM!
 */
00753 typedef struct PDM
{
    /** Offset to the VM structure.
     * See PDM2VM(). */
00757     RTUINT                          offVM;
00758     RTUINT                          uPadding0; /**< Alignment padding.*/

    /** Pointer to list of loaded modules. This is HC only! */
    HCPTRTYPE(PPDMMOD)              pModules;

    /** List of registered devices. (FIFO) */
    HCPTRTYPE(PPDMDEV)              pDevs;
    /** List of devices instances. (FIFO) */
    HCPTRTYPE(PPDMDEVINS)           pDevInstances;
    /** List of registered USB devices. (FIFO) */
    R3PTRTYPE(PPDMUSB)              pUsbDevs;
    /** List of USB devices instances. (FIFO) */
    R3PTRTYPE(PPDMUSBINS)           pUsbInstances;
    /** List of registered drivers. (FIFO) */
    HCPTRTYPE(PPDMDRV)              pDrvs;
    /** List of initialized critical sections. (LIFO) */
    HCPTRTYPE(PPDMCRITSECTINT)      pCritSects;
    /** PCI Buses. */
00776     PDMPCIBUS                       aPciBuses[1];
    /** The register PIC device. */
00778     PDMPIC                          Pic;
    /** The registerd APIC device. */
00780     PDMAPIC                         Apic;
    /** The registerd I/O APIC device. */
00782     PDMIOAPIC                       IoApic;
    /** The registered DMAC device. */
    HCPTRTYPE(PPDMDMAC)             pDmac;
    /** The registered RTC device. */
    HCPTRTYPE(PPDMRTC)              pRtc;
    /** The registered USB HUBs. (FIFO) */
    R3PTRTYPE(PPDMUSBHUB)           pUsbHubs;

    /** Queue in which devhlp tasks are queued for R3 execution - HC Ptr. */
    HCPTRTYPE(PPDMQUEUE)            pDevHlpQueueHC;
    /** Queue in which devhlp tasks are queued for R3 execution - GC Ptr. */
    GCPTRTYPE(PPDMQUEUE)            pDevHlpQueueGC;

    /** The number of entries in the apQueuedCritSectsLeaves table that's currnetly in use. */
00796     RTUINT                          cQueuedCritSectLeaves;
    /** Critical sections queued in GC/R0 because of contention preventing leave to complete. (R3 Ptrs)
     * We will return to Ring-3 ASAP, so this queue doesn't has to be very long. */
    R3PTRTYPE(PPDMCRITSECT)         apQueuedCritSectsLeaves[8];

    /** Linked list of timer driven PDM queues. */
    HCPTRTYPE(struct PDMQUEUE *)    pQueuesTimer;
    /** Linked list of force action driven PDM queues. */
    HCPTRTYPE(struct PDMQUEUE *)    pQueuesForced;
    /** Pointer to the queue which should be manually flushed - HCPtr.
     * Only touched by EMT. */
    HCPTRTYPE(struct PDMQUEUE *)    pQueueFlushHC;
    /** Pointer to the queue which should be manually flushed - GCPtr. */
    GCPTRTYPE(struct PDMQUEUE *)    pQueueFlushGC;
#if HC_ARCH_BITS == 64
    uint32_t                        padding0;
#endif

    /** Head of the PDM Thread list. (singly linked) */
    R3PTRTYPE(PPDMTHREAD)           pThreads;
    /** Tail of the PDM Thread list. (singly linked) */
    R3PTRTYPE(PPDMTHREAD)           pThreadsTail;

    /** TEMPORARY HACKS FOR NETWORK POLLING.
     * @todo fix NAT and kill this!
     * @{ */
00822     RTUINT                          cPollers;
#if HC_ARCH_BITS == 64
    RTUINT                          padding1;
#endif
    HCPTRTYPE(PFNPDMDRVPOLLER)      apfnPollers[16];
    HCPTRTYPE(PPDMDRVINS)           aDrvInsPollers[16];
    PTMTIMERHC                      pTimerPollers;
    /** @} */

#ifdef VBOX_WITH_PDM_LOCK
    /** The PDM lock.
     * This is used to protect everything that deals with interrupts, i.e.
     * the PIC, APIC, IOAPIC and PCI devices pluss some PDM functions. */
    PDMCRITSECT                     CritSect;
#endif


    /** Number of times a critical section leave requesed needed to be queued for ring-3 execution. */
00840     STAMCOUNTER                     StatQueuedCritSectLeaves;
} PDM;
/** Pointer to PDM VM instance data. */
00843 typedef PDM *PPDM;



/*******************************************************************************
*   Global Variables                                                           *
*******************************************************************************/
#ifdef IN_RING3
extern const PDMDRVHLP g_pdmR3DrvHlp;
#endif


/*******************************************************************************
*   Internal Functions                                                         *
*******************************************************************************/
#ifdef IN_RING3
int         pdmR3CritSectInit(PVM pVM);
int         pdmR3CritSectTerm(PVM pVM);
void        pdmR3CritSectRelocate(PVM pVM);
int         pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);
int         pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);

int         pdmR3DevInit(PVM pVM);
PPDMDEV     pdmR3DevLookup(PVM pVM, const char *pszName);
int         pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);

int         pdmR3UsbLoadModules(PVM pVM);
int         pdmR3UsbInstantiateDevices(PVM pVM);
int         pdmR3UsbInitComplete(PVM pVM);
PPDMUSB     pdmR3UsbLookup(PVM pVM, const char *pszName);
int         pdmR3UsbFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);

int         pdmR3DrvInit(PVM pVM);
int         pdmR3DrvDetach(PPDMDRVINS pDrvIns);
PPDMDRV     pdmR3DrvLookup(PVM pVM, const char *pszName);

int         pdmR3LdrInit(PVM pVM);
void        pdmR3LdrTerm(PVM pVM);
char *      pdmR3FileR3(const char *pszFile, bool fShared = false);
int         pdmR3LoadR3(PVM pVM, const char *pszFilename, const char *pszName);

void        pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);

int         pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
                                    PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
int         pdmR3ThreadCreateUsb(PVM pVM, PPDMDRVINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
                                 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
int         pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
                                    PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
int         pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
int         pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
int         pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
void        pdmR3ThreadDestroyAll(PVM pVM);
int         pdmR3ThreadResumeAll(PVM pVM);
int         pdmR3ThreadSuspendAll(PVM pVM);

#endif /* IN_RING3 */

#ifdef VBOX_WITH_PDM_LOCK
void        pdmLock(PVM pVM);
int         pdmLockEx(PVM pVM, int rc);
void        pdmUnlock(PVM pVM);
#else
# define pdmLock(pVM)       do {} while (0)
# define pdmLockEx(pVM, rc) (VINF_SUCCESS)
# define pdmUnlock(pVM)     do {} while (0)
#endif

/** @} */

__END_DECLS

#endif

Generated by  Doxygen 1.6.0   Back to index