VirtualBox

Changeset 35357 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 27, 2010 10:38:34 PM (14 years ago)
Author:
vboxsync
Message:

VMM, Main: PCI passthrough work

Location:
trunk/src/VBox
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r35353 r35357  
    296296{
    297297    int rc = VINF_SUCCESS;
    298 
    299     if (pAddr->iRegister > 0xff)
    300     {
    301         LogRel(("PCI: attempt to write extended register: %x (%d) <- val\n", pAddr->iRegister, cb, val));
    302         goto out;
    303     }
    304298
    305299    if (pAddr->iBus != 0)
     
    933927static DECLCALLBACK(int) ich9pciGenericSaveExec(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSM)
    934928{
     929    Assert(!PCIIsPassthrough(pPciDev));
    935930    return SSMR3PutMem(pSSM, &pPciDev->config[0], sizeof(pPciDev->config));
    936931}
     
    11851180     */
    11861181    uint8_t const fBridge = fIsBridge ? 2 : 1;
     1182    Assert(!PCIIsPassthrough(pDev));
    11871183    uint8_t *pbDstConfig = &pDev->config[0];
     1184
    11881185    for (uint32_t i = 0; i < RT_ELEMENTS(s_aFields); i++)
    11891186        if (s_aFields[i].fBridge & fBridge)
     
    13791376
    13801377        /* commit the loaded device config. */
     1378        Assert(!PCIIsPassthrough(pDev));
    13811379        pciR3CommonRestoreConfig(pDev, &DevTmp.config[0], false ); /** @todo fix bridge fun! */
    13821380
     
    14101408static DECLCALLBACK(int) ich9pciGenericLoadExec(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSM)
    14111409{
     1410    Assert(!PCIIsPassthrough(pPciDev));
    14121411    return SSMR3GetMem(pSSM, &pPciDev->config[0], sizeof(pPciDev->config));
    14131412}
     
    16251624
    16261625            AssertMsg(pGlobals->uBus < 255, ("Too many bridges on the bus\n"));
     1626#if 0
     1627            /* We assign bridges starting from 16, to allow real PCI
     1628               device assignment into lower slots */
     1629            if (pGlobals->uBus == 0)
     1630                pGlobals->uBus = 16;
     1631            else
     1632                pGlobals->uBus++;
     1633#else
    16271634            pGlobals->uBus++;
     1635#endif
    16281636            ich9pciBiosInitBridge(pGlobals, uBus, uDevFn, cBridgeDepth, paBridgePositions);
    16291637            break;
     
    17351743    }
    17361744
     1745    AssertMsgReturn(u32Address + len <= 256, ("Read after end of PCI config space\n"),
     1746                    0);
     1747
     1748
    17371749    if (   PCIIsMsiCapable(aDev)
    17381750        && (u32Address >= aDev->Int.s.u8MsiCapOffset)
     
    17511763    }
    17521764
    1753     AssertMsgReturn(u32Address + len <= 256, ("Read after end of PCI config space\n"),
    1754                     0);
    17551765    switch (len)
    17561766    {
     
    18081818{
    18091819    Assert(len <= 4);
     1820    Assert(!PCIIsPassthrough(aDev));
    18101821
    18111822    if ((u32Address + len) > 256 && (u32Address + len) < 4096)
    18121823    {
    1813         AssertMsgReturnVoid(false, ("Write to extended registers falled back to generic code\n"));
     1824        LogRel(("Write to extended registers falled back to the generic code: %s register %d len=%d\n",
     1825                aDev->name, u32Address, len));
     1826        return;
    18141827    }
    18151828
     
    21302143        if (pPciDev != NULL)
    21312144        {
     2145            if (PCIIsPassthrough(pPciDev))
     2146            {
     2147                printIndent(pHlp, iIndent);
     2148                /**
     2149                 * For passthrough devices MSI/MSI-X mostly reflects the way interrupts delivered to the guest,
     2150                 * as host driver handles real devices interrupts.
     2151                 */
     2152                pHlp->pfnPrintf(pHlp, "%02x:%02x:%02x %s: %s%s - PASSTHROUGH\n",
     2153                                pBus->iBus, (iDev >> 3) & 0xff, iDev & 0x7,
     2154                                pPciDev->name,
     2155                                PCIIsMsiCapable(pPciDev)  ? " MSI" : "",
     2156                                PCIIsMsixCapable(pPciDev) ? " MSI-X" : ""
     2157                                );
     2158                continue;
     2159            }
     2160
    21322161            printIndent(pHlp, iIndent);
    21332162            pHlp->pfnPrintf(pHlp, "%02x:%02x:%02x %s: %04x-%04x%s%s",
  • trunk/src/VBox/Devices/Bus/DevPciRaw.cpp

    r35353 r35357  
    2020*******************************************************************************/
    2121#define LOG_GROUP LOG_GROUP_DEV_PCI
     22#include <VBox/log.h>
     23#define PCI_INCLUDE_PRIVATE
     24#include <VBox/pci.h>
    2225#include <VBox/vmm/pdmdev.h>
    23 #include <VBox/log.h>
    2426#include <VBox/vmm/stam.h>
     27#include <VBox/vmm/pdmpci.h>
    2528#include <iprt/assert.h>
    2629#include <iprt/string.h>
     30#include <iprt/uuid.h>
     31
    2732
    2833#include "VBoxDD.h"
     
    3843 *******************************************************************************/
    3944
    40 /* Temporary PDM stubs */
    41 typedef struct PDMPCIRAWREG
    42 {
    43     /** Struct version+magic number (PDM_PCIRAWREG_VERSION). */
    44     uint32_t            u32Version;
    45 
    46 } PDMPCIRAWREG;
    47 /** Pointer to a raw PCI registration structure. */
    48 typedef PDMPCIRAWREG *PPDMPCIRAWREG;
    49 
    50 /** Current PDMPCIRAWREG version number. */
    51 #define PDM_PCIRAWREG_VERSION                     PDM_VERSION_MAKE(0xffe3, 1, 0)
    52 
    53 struct PDMPCIRAWHLPRC
    54 {
    55     uint32_t u32Version;
    56 };
    57 typedef RCPTRTYPE(PDMPCIRAWHLPRC *) PPDMPCIRAWHLPRC;
    58 typedef RCPTRTYPE(const PDMPCIRAWHLPRC *) PCPDMPCIRAWHLPRC;
    59 
    60 struct PDMPCIRAWHLPR0
    61 {
    62     uint32_t u32Version;
    63 };
    64 typedef R0PTRTYPE(PDMPCIRAWHLPR0 *) PPDMPCIRAWHLPR0;
    65 typedef R0PTRTYPE(const PDMPCIRAWHLPR0 *) PCPDMPCIRAWHLPR0;
    66 
    67 struct PDMPCIRAWHLPR3
    68 {
    69     uint32_t u32Version;
    70     /**
    71      * Gets the address of the RC PCI raw helpers.
    72      *
    73      * This should be called at both construction and relocation time
    74      * to obtain the correct address of the RC helpers.
    75      *
    76      * @returns RC pointer to the PCI raw helpers.
    77      * @param   pDevIns         Device instance of the raw PCI device.
    78      */
    79     DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
    80 
    81     /**
    82      * Gets the address of the R0 PCI raw helpers.
    83      *
    84      * This should be called at both construction and relocation time
    85      * to obtain the correct address of the R0 helpers.
    86      *
    87      * @returns R0 pointer to the PCI raw helpers.
    88      * @param   pDevIns         Device instance of the raw PCI device.
    89      */
    90     DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
    91 
    92     /** Just a safety precaution. */
    93     uint32_t                u32TheEnd;
    94 };
    95 /** Pointer to raw PCI R3 helpers. */
    96 typedef R3PTRTYPE(PDMPCIRAWHLPR3 *) PPDMPCIRAWHLPR3;
    97 /** Pointer to const raw PCI R3 helpers. */
    98 typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
    99 
    100 /**
    101  * @copydoc PDMDEVHLPR3::pfnPciRawRegister
    102  */
    103 DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
    104 {
    105     //return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
    106     return VINF_SUCCESS;
    107 }
    108 
    109 /* End of PDM stubs */
    110 
    11145typedef struct PciRawState
    11246{
     
    12963    PCIDEVICE            aPciDevice;
    13064
     65    /* Device name, as provided by Main */
     66    char                 szDeviceName[64];
    13167    /* Address of device on the host */
    132     PciBusAddress        aHostDeviceAddress;
     68    int32_t              i32HostDeviceAddress;
    13369    /* Address of device in the guest */
    134     PciBusAddress        aGuestDeviceAddress;
    135 
    136     /* Global device lock */
     70    int32_t              i32GuestDeviceAddress;
     71
     72     /* Global device lock */
    13773    PDMCRITSECT          csLock;
     74
     75    /**
     76     * Device port - LUN#0.
     77     *
     78     * @implements  PDMIBASE
     79     * @implements  PDMIPCIRAW
     80     */
     81    struct
     82    {
     83        /** The base interface for the PCI device port. */
     84        PDMIBASE                            IBase;
     85        /** The device port base interface. */
     86        PDMIPCIRAW                          IDevice;
     87
     88        /** The base interface of the attached raw PCI driver. */
     89        R3PTRTYPE(PPDMIBASE)                pDrvBase;
     90        /** The device interface of the attached raw PCI driver. */
     91        R3PTRTYPE(PPDMIPCIRAWCONNECTOR)     pDrv;
     92    } Lun0;
    13893} PciRawState;
    13994
     95/** Pointer to the raw PCI instance data. */
     96typedef PciRawState *PPciRawState;
    14097
    14198#ifndef VBOX_DEVICE_STRUCT_TESTCASE
     
    150107RT_C_DECLS_END
    151108
    152 /*
    153  * Temporary control to disable locking if problems found
    154  */
    155109DECLINLINE(int) pcirawLock(PciRawState* pThis, int rcBusy)
    156110{
     
    162116    PDMCritSectLeave(&pThis->csLock);
    163117}
    164 
    165118
    166119PDMBOTHCBDECL(int)  pcirawMMIORead(PPDMDEVINS pDevIns,
     
    212165
    213166    rc = pcirawLock(pThis, VINF_IOM_HC_MMIO_WRITE);
    214     if (RT_UNLIKELY(rc != VINF_SUCCESS))
    215167        return rc;
    216168
     
    331283}
    332284
     285static DECLCALLBACK(int) pcirawAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     286{
     287    PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
     288
     289    LogFlow(("pcirawAttach: LUN%d\n", iLUN));
     290    /* Not yet used */
     291    return 0;
     292}
     293
     294static DECLCALLBACK(void) pcirawDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     295{
     296    PciRawState *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
     297
     298    LogFlow(("pcirawDetach: LUN%d\n", iLUN));
     299    /* Not yet used */
     300}
     301
     302
    333303/**
    334304 * Initialization routine.
     
    337307 * @param   pDevIns     The device instance data.
    338308 */
    339 static int pcirawInit(PPDMDEVINS pDevIns, PciBusAddress hostAddress)
     309static int pcirawInit(PPDMDEVINS pDevIns, PciBusAddress hostAddress, PciBusAddress guestAddress)
    340310{
    341311    unsigned   i;
     
    349319    pThis->pDevInsRC  = PDMDEVINS_2_RCPTR(pDevIns);
    350320
    351     pThis->aHostDeviceAddress.init(hostAddress);
     321    pThis->i32HostDeviceAddress = hostAddress.asLong();
     322    pThis->i32GuestDeviceAddress = guestAddress.asLong();
    352323
    353324    pcirawReset(pDevIns);
    354325
    355326    return VINF_SUCCESS;
     327}
     328
     329
     330static uint32_t pcirawConfigRead(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb)
     331{
     332    PPDMDEVINS pDevIns = pPciDev->pDevIns;
     333    PciRawState*  pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
     334
     335    Log2(("rawpci: PCI config read: 0x%x (%d)\n", Address, cb));
     336
     337    return 0;
     338}
     339
     340static void pcirawConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb)
     341{
     342    PPDMDEVINS  pDevIns = pPciDev->pDevIns;
     343    PciRawState  *pThis = PDMINS_2_DATA(pDevIns, PciRawState *);
     344
     345    Log2(("rawpci: PCI config write: 0x%x -> 0x%x (%d)\n", u32Value, Address, cb));
     346}
     347
     348
     349/**
     350 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     351 */
     352static DECLCALLBACK(void *) pcirawQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     353{
     354    PciRawState* pThis = RT_FROM_CPP_MEMBER(pInterface, PciRawState, Lun0.IBase);
     355    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,   &pThis->Lun0.IBase);
     356    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIPCIRAW, &pThis->Lun0.IDevice);
     357    return NULL;
     358}
     359
     360static DECLCALLBACK(int) pcirawFoo(PPDMIPCIRAW pInterface)
     361{
     362    return 0;
    356363}
    357364
     
    373380                              "GCEnabled\0"
    374381                              "R0Enabled\0"
     382                              "DeviceName\0"
     383                              "GuestPCIBusNo\0"
     384                              "GuestPCIDeviceNo\0"
     385                              "GuestPCIFunctionNo\0"
    375386                              "HostPCIBusNo\0"
    376387                              "HostPCIDeviceNo\0"
     
    390401                                N_("Configuration error: failed to read R0Enabled as boolean"));
    391402
    392     /* Obtain host device address */
    393     uint32_t u32Bus, u32Device, u32Fn;
    394     rc = CFGMR3QueryU32(pCfg, "HostPCIBusNo", &u32Bus);
     403    rc = CFGMR3QueryString(pCfg, "DeviceName", pThis->szDeviceName, sizeof(pThis->szDeviceName));
    395404    if (RT_FAILURE(rc))
    396405        return PDMDEV_SET_ERROR(pDevIns, rc,
    397                                 N_("Configuration error: Querying \"HostPCIBusNo\" as a int failed"));
    398     rc = CFGMR3QueryU32(pCfg, "HostPCIDeviceNo", &u32Device);
    399     if (RT_FAILURE(rc))
    400         return PDMDEV_SET_ERROR(pDevIns, rc,
    401                                 N_("Configuration error: Querying \"HostPCIDeviceNo\" as a int failed"));
    402     rc = CFGMR3QueryU32(pCfg, "HostPCIFunctionNo", &u32Fn);
    403     if (RT_FAILURE(rc))
    404         return PDMDEV_SET_ERROR(pDevIns, rc,
    405                                 N_("Configuration error: Querying \"HostPCIFunctionNo\" as a int failed"));
    406 
    407 
    408     /* Initialize the device state */
    409     rc = pcirawInit(pDevIns, PciBusAddress(u32Bus, u32Device, u32Fn));
    410     if (RT_FAILURE(rc))
    411         return rc;
    412 
    413     pThis->pDevInsR3 = pDevIns;
    414     pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    415     pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    416 
    417     /*
    418      * Register the raw device and get helpers.
    419      */
    420     PciRawReg.u32Version  = PDM_PCIRAWREG_VERSION;
    421     rc = PDMDevHlpPciRawRegister(pDevIns, &PciRawReg, &pThis->pPciRawHlpR3);
    422     if (RT_FAILURE(rc))
    423     {
    424         AssertMsgRC(rc, ("Cannot PciRawRegister: %Rrc\n", rc));
    425         return rc;
    426     }
    427 
    428     /*
    429      * Initialize critical section.
    430      */
    431     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "PCIRAW");
    432     if (RT_FAILURE(rc))
    433         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Raw PCI device cannot initialize critical section"));
    434 
    435 #if 0
    436     /*
    437      * Register IO/MMIO ranges for guest, basing on real device ranges.
    438      */
    439     for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
    440     {
    441 
    442     }
     406                                N_("Configuration error: failed to read DeviceName as string"));
     407
     408    PciBusAddress hostAddress, guestAddress;
     409
     410    /* Obtain device address info */
     411    uint32_t u32Bus, u32Device, u32Fn;
     412
     413    do {
     414        rc = CFGMR3QueryU32(pCfg, "HostPCIBusNo", &u32Bus);
     415        if (RT_FAILURE(rc))
     416        {
     417            PDMDEV_SET_ERROR(pDevIns, rc,
     418                             N_("Configuration error: Querying \"HostPCIBusNo\" as a int failed"));
     419            break;
     420        }
     421        rc = CFGMR3QueryU32(pCfg, "HostPCIDeviceNo", &u32Device);
     422        if (RT_FAILURE(rc))
     423        {
     424            PDMDEV_SET_ERROR(pDevIns, rc,
     425                             N_("Configuration error: Querying \"HostPCIDeviceNo\" as a int failed"));
     426            break;
     427        }
     428        rc = CFGMR3QueryU32(pCfg, "HostPCIFunctionNo", &u32Fn);
     429        if (RT_FAILURE(rc))
     430        {
     431            PDMDEV_SET_ERROR(pDevIns, rc,
     432                             N_("Configuration error: Querying \"HostPCIFunctionNo\" as a int failed"));
     433            break;
     434        }
     435        hostAddress = PciBusAddress(u32Bus, u32Device, u32Fn);
     436
     437        rc = CFGMR3QueryU32(pCfg, "GuestPCIBusNo", &u32Bus);
     438        if (RT_FAILURE(rc))
     439        {
     440            PDMDEV_SET_ERROR(pDevIns, rc,
     441                             N_("Configuration error: Querying \"GuestPCIBusNo\" as a int failed"));
     442            break;
     443        }
     444        rc = CFGMR3QueryU32(pCfg, "GuestPCIDeviceNo", &u32Device);
     445        if (RT_FAILURE(rc))
     446        {
     447            PDMDEV_SET_ERROR(pDevIns, rc,
     448                             N_("Configuration error: Querying \"GuestPCIDeviceNo\" as a int failed"));
     449            break;
     450        }
     451        rc = CFGMR3QueryU32(pCfg, "GuestPCIFunctionNo", &u32Fn);
     452        if (RT_FAILURE(rc))
     453        {
     454            PDMDEV_SET_ERROR(pDevIns, rc,
     455                             N_("Configuration error: Querying \"GuestPCIFunctionNo\" as a int failed"));
     456            break;
     457        }
     458        guestAddress = PciBusAddress(u32Bus, u32Device, u32Fn);
     459
     460        /* Initialize the device state */
     461        rc = pcirawInit(pDevIns, hostAddress, guestAddress);
     462        if (RT_FAILURE(rc))
     463            break;
     464
     465        pThis->pDevInsR3 = pDevIns;
     466        pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     467        pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     468
     469        /*
     470         * Register the raw device and get helpers.
     471         */
     472        PciRawReg.u32Version  = PDM_PCIRAWREG_VERSION;
     473        rc = PDMDevHlpPciRawRegister(pDevIns, &PciRawReg, &pThis->pPciRawHlpR3);
     474        if (RT_FAILURE(rc))
     475        {
     476            AssertMsgRC(rc, ("Cannot PciRawRegister: %Rrc\n", rc));
     477            break;
     478        }
     479
     480        /*
     481         * Initialize critical section.
     482         */
     483        rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "PCIRAW");
     484        if (RT_FAILURE(rc))
     485        {
     486            PDMDEV_SET_ERROR(pDevIns, rc, N_("Raw PCI device cannot initialize critical section"));
     487            break;
     488        }
     489
     490        /* Mark device as passthrough */
     491        PCISetPassthrough(&pThis->aPciDevice);
     492
     493        /* IBase */
     494        pThis->Lun0.IBase.pfnQueryInterface = pcirawQueryInterface;
     495        pThis->Lun0.IDevice.pfnFoo          = pcirawFoo;
     496
     497        /*
     498         * Attach to the Main driver.
     499         */
     500        rc = pDevIns->pHlpR3->pfnDriverAttach(pDevIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Device Port");
     501        if (RT_FAILURE(rc))
     502        {
     503            rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Raw PCI failed to attach Main driver"));
     504            break;
     505        }
     506
     507        pThis->Lun0.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pDrvBase, PDMIPCIRAWCONNECTOR);
     508        if (!pThis->Lun0.pDrv)
     509        {
     510            rc = PDMDevHlpVMSetError(pDevIns, VERR_PDM_MISSING_INTERFACE, RT_SRC_POS, N_("Raw PCI failed to query interface"));
     511            break;
     512        }
     513
     514        /* Just a safety measure, this data shall never be reached */
     515        PCIDevSetVendorId(&pThis->aPciDevice, 0xdead);
     516        PCIDevSetDeviceId(&pThis->aPciDevice, 0xbeef);
     517
     518        rc = PDMDevHlpPCIRegister(pDevIns, &pThis->aPciDevice);
     519        if (RT_FAILURE(rc))
     520            break;
     521
     522        PDMDevHlpPCISetConfigCallbacks(pDevIns, &pThis->aPciDevice,
     523                                       pcirawConfigRead,  NULL /* we don't care about old ones */,
     524                                       pcirawConfigWrite, NULL /* we don't care about old ones */);
     525
     526#if 1
     527        /*
     528         * Register IO/MMIO ranges for the guest, basing on real device ranges.
     529         */
     530        for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
     531        {
     532            RTHCPHYS RegStart;
     533            uint64_t iRegSize;
     534            bool     fMmio;
     535
     536            if (pThis->Lun0.pDrv->pfnGetRegionInfo(pThis->Lun0.pDrv, hostAddress.asLong(), iRegion,
     537                                                   &RegStart, &iRegSize, &fMmio))
     538            {
     539                /* If region is present, register callbacks in guest.
     540                   @todo: replace it with direct region access with remap */
     541                // @todo: check if host's PA make sense for the guest
     542                if (fMmio)
     543                {
     544                    rc = PDMDevHlpMMIORegister(pDevIns, RegStart, iRegSize, NULL,
     545                                               pcirawMMIOWrite, pcirawMMIORead, NULL,
     546                                               "Raw PCI MMIO regions");
     547                    if (RT_FAILURE(rc))
     548                    {
     549                        AssertMsgRC(rc, ("Cannot register MMIO: %Rrc\n", rc));
     550                        break;
     551                    }
     552                }
     553                else
     554                {
     555                    rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)RegStart, iRegSize, NULL,
     556                                                 pcirawIOPortWrite, pcirawIOPortRead, NULL, NULL,
     557                                                 "Raw PCI IO regions");
     558                    if (RT_FAILURE(rc))
     559                    {
     560                        AssertMsgRC(rc, ("Cannot register IO: %Rrc\n", rc));
     561                        break;
     562                    }
     563                }
     564            }
     565        }
     566
     567        if (RT_FAILURE(rc))
     568            break;
    443569#endif
    444570
    445     if (fRCEnabled)
    446     {
    447         pThis->pPciRawHlpRC = pThis->pPciRawHlpR3->pfnGetRCHelpers(pDevIns);
    448         if (!pThis->pPciRawHlpRC)
    449         {
    450             AssertReleaseMsgFailed(("cannot get RC helper\n"));
    451             return VERR_INTERNAL_ERROR;
    452         }
    453     }
    454     if (fR0Enabled)
    455     {
    456         pThis->pPciRawHlpR0 = pThis->pPciRawHlpR3->pfnGetR0Helpers(pDevIns);
    457         if (!pThis->pPciRawHlpR0)
    458         {
    459             AssertReleaseMsgFailed(("cannot get R0 helper\n"));
    460             return VERR_INTERNAL_ERROR;
    461         }
    462     }
    463 
    464     /* Register SSM callbacks */
    465     rc = PDMDevHlpSSMRegister3(pDevIns, PCIRAW_SAVED_STATE_VERSION, sizeof(*pThis), pcirawLiveExec, pcirawSaveExec, pcirawLoadExec);
    466     if (RT_FAILURE(rc))
    467         return rc;
    468 
    469     return VINF_SUCCESS;
     571        if (fRCEnabled)
     572        {
     573            pThis->pPciRawHlpRC = pThis->pPciRawHlpR3->pfnGetRCHelpers(pDevIns);
     574            if (!pThis->pPciRawHlpRC)
     575            {
     576                AssertReleaseMsgFailed(("cannot get RC helper\n"));
     577                rc = VERR_INTERNAL_ERROR;
     578                break;
     579                }
     580        }
     581        if (fR0Enabled)
     582        {
     583            pThis->pPciRawHlpR0 = pThis->pPciRawHlpR3->pfnGetR0Helpers(pDevIns);
     584            if (!pThis->pPciRawHlpR0)
     585                {
     586                    AssertReleaseMsgFailed(("cannot get R0 helper\n"));
     587                    rc = VERR_INTERNAL_ERROR;
     588                    break;
     589                }
     590        }
     591
     592        /* Register SSM callbacks */
     593        rc = PDMDevHlpSSMRegister3(pDevIns, PCIRAW_SAVED_STATE_VERSION, sizeof(*pThis), pcirawLiveExec, pcirawSaveExec, pcirawLoadExec);
     594        if (RT_FAILURE(rc))
     595            break;
     596    } while (0);
     597    /* Notify Main about result of PCI device  attach attempt */
     598    if (pThis->Lun0.pDrv != NULL)
     599        pThis->Lun0.pDrv->pfnPciDeviceConstructComplete(pThis->Lun0.pDrv, hostAddress.asLong(), guestAddress.asLong(),
     600                                                        rc, pThis->szDeviceName);
     601
     602    return rc;
    470603}
    471604
     
    511644    NULL,
    512645    /* pfnAttach */
    513     NULL,
     646    NULL , //pcirawAttach,
    514647    /* pfnDetach */
    515     NULL,
     648    NULL, //pcirawDetach,
    516649    /* pfnQueryInterface. */
    517650    NULL,
  • trunk/src/VBox/Devices/Bus/PCIInternal.h

    r34331 r35357  
    8787    /** Flag whether the device is capable of MSI-X.
    8888     * This one is set by MsixInit().  */
    89     PCIDEV_FLAG_MSIX_CAPABLE       = 1<<4
     89    PCIDEV_FLAG_MSIX_CAPABLE       = 1<<4,
     90    /** Flag if device represents real physical device in passthrough mode. */
     91    PCIDEV_FLAG_PASSTHROUGH        = 1<<5
    9092};
    9193
  • trunk/src/VBox/Devices/Makefile.kmk

    r35355 r35357  
    512512 Bus/DevPCI.cpp_INCS      = Bus
    513513 Bus/DevPciIch9.cpp_INCS  = Bus
    514  Bus/MsiCommon.cpp_INCS  = Bus
     514 Bus/MsiCommon.cpp_INCS   = Bus
    515515 Bus/MsixCommon.cpp_INCS  = Bus
     516 Bus/DevPciRaw.cpp_INCS   = Bus
     517
    516518
    517519 # For finding and generating vbetables.h (see Graphics/BIOS/Makefile.kmk).
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r35346 r35357  
    307307                    break;
    308308                mConsole->onNATRedirectRuleChange(ulSlot, fRemove, proto, hostIp.raw(), hostPort, guestIp.raw(), guestPort);
     309                break;
    309310            }
    310             break;
     311            case VBoxEventType_OnHostPciDevicePlug:
     312            {
     313                // handle if needed
     314                break;
     315            }
    311316            default:
    312317                AssertFailed();
     
    484489        com::SafeArray<VBoxEventType_T> eventTypes;
    485490        eventTypes.push_back(VBoxEventType_OnNATRedirect);
     491        eventTypes.push_back(VBoxEventType_OnHostPciDevicePlug);
    486492        rc = pES->RegisterListener(mVmListner, ComSafeArrayAsInParam(eventTypes), true);
    487493        AssertComRC(rc);
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r35346 r35357  
    3434#include "VMMDev.h"
    3535#include "Global.h"
     36#include "PciRawDevImpl.h"
    3637
    3738// generated header
     
    455456
    456457
     458static HRESULT attachRawPciDevices(BusAssignmentManager* BusMgr,
     459                                   PCFGMNODE             pDevices,
     460                                   Console*              pConsole)
     461{
     462    HRESULT hrc = S_OK;
     463    PCFGMNODE pDev, pInst, pCfg, pLunL0;
     464
     465    SafeIfaceArray<IPciDeviceAttachment> assignments;
     466    ComPtr<IMachine> aMachine =  pConsole->machine();
     467
     468    hrc = aMachine->COMGETTER(PciDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
     469    if (hrc != S_OK)
     470        return hrc;
     471
     472    for (size_t iDev = 0; iDev < assignments.size(); iDev++)
     473    {
     474        PciBusAddress HostPciAddress, GuestPciAddress;
     475        ComPtr<IPciDeviceAttachment> assignment = assignments[iDev];
     476        LONG host, guest;
     477        Bstr aDevName;
     478
     479        assignment->COMGETTER(HostAddress)(&host);
     480        assignment->COMGETTER(GuestAddress)(&guest);
     481        assignment->COMGETTER(Name)(aDevName.asOutParam());
     482
     483        InsertConfigNode(pDevices,     "pciraw",  &pDev);
     484        InsertConfigNode(pDev,          Utf8StrFmt("%d", iDev).c_str(), &pInst);
     485        InsertConfigInteger(pInst,     "Trusted", 1);
     486
     487        HostPciAddress.fromLong(host);
     488        Assert(HostPciAddress.valid());
     489        InsertConfigNode(pInst,        "Config",  &pCfg);
     490        InsertConfigString(pCfg,       "DeviceName",  aDevName);
     491
     492        InsertConfigInteger(pCfg,      "HostPCIBusNo",      HostPciAddress.iBus);
     493        InsertConfigInteger(pCfg,      "HostPCIDeviceNo",   HostPciAddress.iDevice);
     494        InsertConfigInteger(pCfg,      "HostPCIFunctionNo", HostPciAddress.iFn);
     495
     496        GuestPciAddress.fromLong(guest);
     497        Assert(GuestPciAddress.valid());
     498        hrc = BusMgr->assignPciDevice("pciraw", pInst, GuestPciAddress, true);
     499        if (hrc != S_OK)
     500            return hrc;
     501        InsertConfigInteger(pCfg,      "GuestPCIBusNo",      GuestPciAddress.iBus);
     502        InsertConfigInteger(pCfg,      "GuestPCIDeviceNo",   GuestPciAddress.iDevice);
     503        InsertConfigInteger(pCfg,      "GuestPCIFunctionNo", GuestPciAddress.iFn);
     504
     505        /* the Main driver */
     506        PciRawDev* pMainDev = new PciRawDev(pConsole);
     507        InsertConfigNode(pInst,        "LUN#0",   &pLunL0);
     508        InsertConfigString(pLunL0,     "Driver",  "PciRawMain");
     509        InsertConfigNode(pLunL0,       "Config" , &pCfg);
     510        InsertConfigInteger(pCfg,      "Object", (uintptr_t)pMainDev);
     511    }
     512
     513    return hrc;
     514}
     515
    457516/**
    458517 *  Construct the VM configuration tree (CFGM).
     
    911970            InsertConfigInteger(pCfg,  "McfgLength", u32McfgLength);
    912971
    913 
    914972            /* And register 2 bridges */
    915973            InsertConfigNode(pDevices, "ich9pcibridge", &pDev);
     
    921979            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    922980            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);                               H();
     981
     982            /* Add PCI passthrough devices */
     983            hrc = attachRawPciDevices(BusMgr, pDevices, pConsole);                               H();
    923984        }
    924985
    925986        /*
    926          * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests
     987         * Enable 3 following devices: HPET, SMC, LPC on MacOS X guests or on ICH9
    927988         */
    928989        /*
  • trunk/src/VBox/Main/GuestCtrlImpl.cpp

    r35346 r35357  
    206206        {
    207207            rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
    208                                                  Guest::tr("Source file \"%s\" does not exist"),
     208                                                 Guest::tr("Source file \"%s\" does not exist, or is not a file"),
    209209                                                 aTask->strSource.c_str());
    210210        }
  • trunk/src/VBox/Main/MachineImpl.cpp

    r35346 r35357  
    5050#include "DisplayUtils.h"
    5151#include "BandwidthControlImpl.h"
     52#include "VBoxEvents.h"
    5253
    5354#ifdef VBOX_WITH_USB
     
    58105811}
    58115812
    5812 
    5813 STDMETHODIMP Machine::AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, IEventContext * /*eventContext*/, BOOL /*tryToUnbind*/)
    5814 {
    5815     AutoCaller autoCaller(this);
    5816     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    5817     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    5818 
    5819     ComObjPtr<PciDeviceAttachment> pda;
    5820     char name[32];
    5821 
    5822     pda.createObject();
    5823     RTStrPrintf(name, sizeof(name), "host%02x:%02x.%x", (hostAddress>>8) & 0xff, (hostAddress & 0xf8) >> 3, hostAddress & 7);
    5824     Bstr bname(name);
    5825     pda.createObject();
    5826     pda->init(this, bname,  hostAddress, desiredGuestAddress, TRUE);
    5827 
    5828     mPciDeviceAssignments.push_back(pda);
    5829     return S_OK;
    5830 }
    5831 
    5832 STDMETHODIMP Machine::DetachHostPciDevice(LONG /*hostAddress*/)
    5833 {
    5834     AutoCaller autoCaller(this);
    5835     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    5836     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    5837 
    5838     return E_NOTIMPL;
     5813/**
     5814 * Currently this method doesn't attach device to the running VM,
     5815 * just makes sure it's plugged on next VM start.
     5816 */
     5817STDMETHODIMP Machine::AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL /*tryToUnbind*/)
     5818{
     5819    AutoCaller autoCaller(this);
     5820    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5821
     5822    // lock scope
     5823    {
     5824        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     5825
     5826        //HRESULT rc = checkStateDependency(MutableStateDep);
     5827        //if (FAILED(rc)) return rc;
     5828
     5829        ComObjPtr<PciDeviceAttachment> pda;
     5830        char name[32];
     5831
     5832        RTStrPrintf(name, sizeof(name), "host%02x:%02x.%x", (hostAddress>>8) & 0xff, (hostAddress & 0xf8) >> 3, hostAddress & 7);
     5833        Bstr bname(name);
     5834        pda.createObject();
     5835        pda->init(this, bname,  hostAddress, desiredGuestAddress, TRUE);
     5836        setModified(IsModified_MachineData);
     5837        mHWData.backup();
     5838        mHWData->mPciDeviceAssignments.push_back(pda);
     5839    }
     5840
     5841    // do we need it?
     5842    //saveSettings(NULL);
     5843    mHWData.commit();
     5844
     5845    return S_OK;
     5846}
     5847
     5848/**
     5849 * Currently this method doesn't detach device from the running VM,
     5850 * just makes sure it's not plugged on next VM start.
     5851 */
     5852STDMETHODIMP Machine::DetachHostPciDevice(LONG hostAddress)
     5853{
     5854    AutoCaller autoCaller(this);
     5855    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     5856
     5857    ComObjPtr<PciDeviceAttachment> pAttach;
     5858    bool fRemoved = false;
     5859    HRESULT rc;
     5860
     5861    // lock scope
     5862    {
     5863        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     5864
     5865        rc = checkStateDependency(MutableStateDep);
     5866        if (FAILED(rc)) return rc;
     5867
     5868        for (HWData::PciDeviceAssignmentList::iterator it =  mHWData->mPciDeviceAssignments.begin();
     5869             it !=  mHWData->mPciDeviceAssignments.end();
     5870             ++it)
     5871        {
     5872            LONG iHostAddress = -1;
     5873            pAttach = *it;           
     5874            pAttach->COMGETTER(HostAddress)(&iHostAddress);
     5875            if (iHostAddress  != -1  && iHostAddress == hostAddress)
     5876            {
     5877                setModified(IsModified_MachineData);
     5878                mHWData.backup();
     5879                mHWData->mPciDeviceAssignments.remove(pAttach);
     5880                fRemoved = true;
     5881                break;
     5882            }
     5883        }
     5884        // Indeed under lock?
     5885        mHWData.commit();
     5886
     5887        // do we need it?
     5888        // saveSettings(NULL);
     5889    }
     5890
     5891
     5892    /* Fire event outside of the lock */
     5893    if (fRemoved)
     5894    {
     5895        Assert(!pAttach.isNull());
     5896        ComPtr<IEventSource> es;
     5897        rc = mParent->COMGETTER(EventSource)(es.asOutParam());
     5898        Assert(SUCCEEDED(rc));
     5899        Bstr mid;
     5900        rc = this->COMGETTER(Id)(mid.asOutParam());
     5901        Assert(SUCCEEDED(rc));
     5902        fireHostPciDevicePlugEvent(es, mid.raw(), false /* unplugged */, true /* success */, pAttach, NULL);
     5903    }
     5904
     5905    return S_OK;
    58395906}
    58405907
     
    58485915    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    58495916
    5850     SafeIfaceArray<IPciDeviceAttachment> assignments(mPciDeviceAssignments);
     5917    SafeIfaceArray<IPciDeviceAttachment> assignments(mHWData->mPciDeviceAssignments);
    58515918    assignments.detachTo(ComSafeArrayOutArg(aAssignments));
    58525919
     
    64626529
    64636530    HRESULT rc = S_OK;
    6464 
    64656531    // Ensure the settings are saved. If we are going to be registered and
    64666532    // no config file exists yet, create it by calling saveSettings() too.
  • trunk/src/VBox/Main/Makefile.kmk

    r35305 r35357  
    653653        BusAssignmentManager.cpp \
    654654        PciDeviceAttachmentImpl.cpp \
     655        PciRawDevImpl.cpp \
    655656        $(VBOX_AUTOGEN_EVENT_CPP) \
    656657        $(VBOX_XML_SCHEMADEFS_CPP) \
  • trunk/src/VBox/Main/PciDeviceAttachmentImpl.cpp

    r34331 r35357  
    2525struct PciDeviceAttachment::Data
    2626{
    27     Data(Machine      *aParent,
    28          const Bstr   &aDevName,
    29          LONG          aHostAddress,
    30          LONG          aGuestAddress,
    31          BOOL          afPhysical)
     27    Data(Machine        *aParent,
     28         const Bstr     &aDevName,
     29         LONG           aHostAddress,
     30         LONG           aGuestAddress,
     31         BOOL           afPhysical)
    3232        : pMachine(aParent),
    3333          HostAddress(aHostAddress), GuestAddress(aGuestAddress),
     
    6161// public initializer/uninitializer for internal purposes only
    6262/////////////////////////////////////////////////////////////////////////////
    63 HRESULT PciDeviceAttachment::init(Machine      *aParent,
    64                                   const Bstr   &aDevName,
    65                                   LONG          aHostAddress,
    66                                   LONG          aGuestAddress,
    67                                   BOOL          fPhysical)
     63HRESULT PciDeviceAttachment::init(Machine       *aParent,
     64                                  const Bstr    &aDevName,
     65                                  LONG           aHostAddress,
     66                                  LONG           aGuestAddress,
     67                                  BOOL           fPhysical)
    6868{
    6969    m = new Data(aParent, aDevName, aHostAddress, aGuestAddress, fPhysical);
  • trunk/src/VBox/Main/VBoxDriversRegister.cpp

    r35346 r35357  
    2626#include "AudioSnifferInterface.h"
    2727#include "ConsoleImpl.h"
     28#include "PciRawDevImpl.h"
    2829
    2930#include "Logging.h"
     
    6768    if (RT_FAILURE(rc))
    6869        return rc;
     70
     71    rc = pCallbacks->pfnRegister(pCallbacks, &PciRawDev::DrvReg);
     72    if (RT_FAILURE(rc))
     73        return rc;
     74
    6975    return VINF_SUCCESS;
    7076}
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r35273 r35357  
    47054705        <desc>Desired position of this device on guest PCI bus.</desc>
    47064706      </param>
    4707       <param name="eventContext" type="IEventContext" dir="in">
    4708         <desc>Context passed into IHostPciDevicePlugEvent event.</desc>
    4709       </param>
    47104707      <param name="tryToUnbind" type="boolean" dir="in">
    47114708        <desc>If VMM shall try to unbind existing drivers from the
     
    47184715        Detach host PCI device from the virtual machine.
    47194716        Also HostPciDevicePlugEvent on IVirtualBox event source
    4720         will be delivered.
    4721 
    4722         <note>
    4723           Not yet implemented.
    4724         </note>
     4717        will be delivered. As currently we don't support hot device
     4718        unplug, IHostPciDevicePlugEvent event is delivered immediately.
    47254719
    47264720        <see>IHostPciDevicePlugEvent</see>
     
    1659716591    >
    1659816592    <desc>
    16599       Notification when host PCI device is plugged/unplugged.
     16593      Notification when host PCI device is plugged/unplugged. Plugging
     16594      usually takes place on VM startup, unplug - when
     16595      IMachine::DetachHostPciDevice is called.
     16596      <see>
     16597        IMachine::DetachHostPciDevice
     16598      </see>
    1660016599    </desc>
    1660116600
     
    1661616615      <desc>
    1661716616        Attachment info for this device.
    16618       </desc>
    16619     </attribute>
    16620 
    16621     <attribute name="eventContext" type="IEventContext" readonly="yes">
    16622       <desc>
    16623         Context object, passed into attachHostPciDevice() and
    16624         attachHostPciDevice().
    1662516617      </desc>
    1662616618    </attribute>
  • trunk/src/VBox/Main/include/MachineImpl.h

    r35175 r35357  
    291291        BOOL                 mIoCacheEnabled;
    292292        ULONG                mIoCacheSize;
     293
     294        typedef std::list< ComObjPtr<PciDeviceAttachment> > PciDeviceAssignmentList;
     295        PciDeviceAssignmentList mPciDeviceAssignments;
    293296    };
    294297
     
    523526    STDMETHOD(QueryLogFilename(ULONG aIdx, BSTR *aName));
    524527    STDMETHOD(ReadLog(ULONG aIdx, LONG64 aOffset, LONG64 aSize, ComSafeArrayOut(BYTE, aData)));
    525     STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, IEventContext *eventContext, BOOL tryToUnbind));
     528    STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL tryToUnbind));
    526529    STDMETHOD(DetachHostPciDevice(LONG hostAddress));
    527530    STDMETHOD(COMGETTER(PciDeviceAssignments))(ComSafeArrayOut(IPciDeviceAttachment *, aAssignments));
     
    870873    typedef std::list< ComObjPtr<StorageController> > StorageControllerList;
    871874    Backupable<StorageControllerList> mStorageControllers;
    872 
    873     typedef std::list< ComObjPtr<PciDeviceAttachment> > PciDeviceAssignmentList;
    874     PciDeviceAssignmentList mPciDeviceAssignments;
    875875
    876876    friend class SessionMachine;
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r35346 r35357  
    4848extern DECLEXPORT(const PDMPCIHLPR0)    g_pdmR0PciHlp;
    4949extern DECLEXPORT(const PDMHPETHLPR0)   g_pdmR0HpetHlp;
     50extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp;
    5051extern DECLEXPORT(const PDMDRVHLPR0)    g_pdmR0DrvHlp;
    5152RT_C_DECLS_END
     
    678679};
    679680
     681/**
     682 * The Ring-0 PCI raw Helper Callbacks.
     683 */
     684extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp =
     685{
     686    PDM_PCIRAWHLPR0_VERSION,
     687    PDM_PCIRAWHLPR0_VERSION, /* the end */
     688};
     689
    680690/** @} */
    681691
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r35346 r35357  
    28092809    *ppHpetHlpR3 = &g_pdmR3DevHpetHlp;
    28102810    LogFlow(("pdmR3DevHlp_HPETRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     2811    return VINF_SUCCESS;
     2812}
     2813
     2814/** @interface_method_impl{PDMDEVHLPR3,pfnPciRawRegister} */
     2815static DECLCALLBACK(int) pdmR3DevHlp_PciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
     2816{
     2817    PDMDEV_ASSERT_DEVINS(pDevIns);
     2818    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     2819    LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d:\n"));
     2820
     2821    /*
     2822     * Validate input.
     2823     */
     2824    if (pPciRawReg->u32Version != PDM_PCIRAWREG_VERSION)
     2825    {
     2826        AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciRawReg->u32Version, PDM_PCIRAWREG_VERSION));
     2827        LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     2828        return VERR_INVALID_PARAMETER;
     2829    }
     2830
     2831    if (!ppPciRawHlpR3)
     2832    {
     2833        Assert(ppPciRawHlpR3);
     2834        LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppApicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     2835        return VERR_INVALID_PARAMETER;
     2836    }
     2837
     2838    /* set the helper pointer and return. */
     2839    *ppPciRawHlpR3 = &g_pdmR3DevPciRawHlp;
     2840    LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    28112841    return VINF_SUCCESS;
    28122842}
     
    31823212    pdmR3DevHlp_IOAPICRegister,
    31833213    pdmR3DevHlp_HPETRegister,
     3214    pdmR3DevHlp_PciRawRegister,
    31843215    pdmR3DevHlp_DMACRegister,
    31853216    pdmR3DevHlp_DMARegister,
     
    33923423    pdmR3DevHlp_IOAPICRegister,
    33933424    pdmR3DevHlp_HPETRegister,
     3425    pdmR3DevHlp_PciRawRegister,
    33943426    pdmR3DevHlp_DMACRegister,
    33953427    pdmR3DevHlp_DMARegister,
     
    34693501
    34703502/** @} */
    3471 
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r35346 r35357  
    652652
    653653
     654/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
     655static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
     656{
     657    PDMDEV_ASSERT_DEVINS(pDevIns);
     658    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     659    RTRCPTR pRCHelpers = 0;
     660    int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
     661    AssertReleaseRC(rc);
     662    AssertRelease(pRCHelpers);
     663    LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
     664             pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
     665    return pRCHelpers;
     666}
     667
     668
     669/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
     670static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
     671{
     672    PDMDEV_ASSERT_DEVINS(pDevIns);
     673    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     674    PCPDMHPETHLPR0 pR0Helpers = 0;
     675    int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
     676    AssertReleaseRC(rc);
     677    AssertRelease(pR0Helpers);
     678    LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
     679             pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
     680    return pR0Helpers;
     681}
     682
     683/**
     684 * Raw PCI Device Helpers.
     685 */
     686const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
     687{
     688    PDM_PCIRAWHLPR3_VERSION,
     689    pdmR3PciRawHlp_GetRCHelpers,
     690    pdmR3PciRawHlp_GetR0Helpers,
     691    PDM_PCIRAWHLPR3_VERSION, /* the end */
     692};
    654693
    655694/* none yet */
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r35346 r35357  
    10851085extern const PDMRTCHLP      g_pdmR3DevRtcHlp;
    10861086extern const PDMHPETHLPR3   g_pdmR3DevHpetHlp;
     1087extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
    10871088#endif
    10881089
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette