VirtualBox

Changeset 50654 in vbox


Ignore:
Timestamp:
Feb 28, 2014 4:19:29 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92585
Message:

Add some comments and minor cosmetics to improve chances of mere
mortals to understand what's going on. No functional change intended.

File:
1 edited

Legend:

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

    r50638 r50654  
    100100#endif
    101101
    102      /** Config register. */
     102    /** Value latched in Configuration Address Port (0CF8h) */
    103103    uint32_t            uConfigReg;
    104104
     
    124124
    125125
     126/**
     127 * PCI configuration space address.
     128 */
    126129typedef struct
    127130{
     
    229232}
    230233
     234
    231235/**
    232236 * Port I/O Handler for PCI address OUT operations.
    233237 *
     238 * Emulates writes to Configuration Address Port at 0CF8h for
     239 * Configuration Mechanism #1.
     240 *
    234241 * @returns VBox status code.
    235242 *
    236  * @param   pDevIns     The device instance.
     243 * @param   pDevIns     ICH9 device instance.
    237244 * @param   pvUser      User argument - ignored.
    238245 * @param   uPort       Port number used for the OUT operation.
     
    240247 * @param   cb          The value size in bytes.
    241248 */
    242 PDMBOTHCBDECL(int)  ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
     249PDMBOTHCBDECL(int) ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    243250{
    244251    LogFlow(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     
    248255        PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
    249256
     257        /*
     258         * bits [1:0] are hard-wired, read-only and must return zeroes
     259         * when read.
     260         */
     261        u32 &= ~3;
     262
    250263        PCI_LOCK(pDevIns, VINF_IOM_R3_IOPORT_WRITE);
    251         pThis->uConfigReg = u32 & ~3; /* Bits 0-1 are reserved and we silently clear them */
     264        pThis->uConfigReg = u32;
    252265        PCI_UNLOCK(pDevIns);
    253266    }
     
    255268    return VINF_SUCCESS;
    256269}
     270
    257271
    258272/**
    259273 * Port I/O Handler for PCI address IN operations.
    260274 *
     275 * Emulates reads from Configuration Address Port at 0CF8h for
     276 * Configuration Mechanism #1.
     277 *
    261278 * @returns VBox status code.
    262279 *
    263  * @param   pDevIns     The device instance.
     280 * @param   pDevIns     ICH9 device instance.
    264281 * @param   pvUser      User argument - ignored.
    265282 * @param   uPort       Port number used for the IN operation.
     
    267284 * @param   cb          Number of bytes read.
    268285 */
    269 PDMBOTHCBDECL(int)  ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
     286PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    270287{
    271288    NOREF(pvUser);
     
    273290    {
    274291        PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
     292
    275293        PCI_LOCK(pDevIns, VINF_IOM_R3_IOPORT_READ);
    276294        *pu32 = pThis->uConfigReg;
    277295        PCI_UNLOCK(pDevIns);
     296
    278297        LogFlow(("ich9pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
    279298        return VINF_SUCCESS;
     
    281300
    282301    Log(("ich9pciIOPortAddressRead: Port=%#x cb=%d VERR_IOM_IOPORT_UNUSED\n", Port, cb));
    283 
    284302    return VERR_IOM_IOPORT_UNUSED;
    285303}
    286304
     305
     306/*
     307 * Perform configuration space write.
     308 */
    287309static int ich9pciDataWriteAddr(PICH9PCIGLOBALS pGlobals, PciAddress* pAddr,
    288310                                uint32_t val, int cb, int rcReschedule)
    289311{
    290312    int rc = VINF_SUCCESS;
    291 
    292     if (pAddr->iBus != 0)
     313#ifdef IN_RING3
     314    NOREF(rcReschedule);
     315#endif
     316
     317    if (pAddr->iBus != 0)       /* forward to subordinate bus */
    293318    {
    294319        if (pGlobals->aPciBus.cBridges)
     
    302327                                                          pAddr->iRegister, val, cb);
    303328            }
    304             else
    305             {
    306                 // do nothing, bridge not found
    307             }
    308             NOREF(rcReschedule);
    309329#else
    310330            rc = rcReschedule;
     
    312332        }
    313333    }
    314     else
    315     {
    316         if (pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc])
     334    else                    /* forward to directly connected device */
     335    {
     336        R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
     337        if (aDev)
    317338        {
    318339#ifdef IN_RING3
    319             R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
    320340            aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, cb);
    321341#else
     
    328348          pAddr->iBus, pAddr->iDeviceFunc >> 3, pAddr->iDeviceFunc & 0x7, pAddr->iRegister,
    329349          cb, val, rc));
    330 
    331350    return rc;
    332351}
    333352
     353
     354/*
     355 * Decode value latched in Configuration Address Port and perform
     356 * requsted write to the target configuration space register.
     357 *
     358 * XXX: This code should be probably moved to its only caller
     359 * (ich9pciIOPortDataWrite) to avoid prolifiration of confusingly
     360 * similarly named functions.
     361 */
    334362static int ich9pciDataWrite(PICH9PCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len)
    335363{
    336     PciAddress aPciAddr;
    337 
    338364    LogFlow(("ich9pciDataWrite: config=%08x val=%08x len=%d\n", pGlobals->uConfigReg, val, len));
    339365
     366    /* Configuration space mapping enabled? */
    340367    if (!(pGlobals->uConfigReg & (1 << 31)))
    341368        return VINF_SUCCESS;
    342369
    343     if ((pGlobals->uConfigReg & 0x3) != 0)
    344         return VINF_SUCCESS;
    345 
    346     /* Compute destination device */
     370    /* Decode target device and configuration space register */
     371    PciAddress aPciAddr;
    347372    ich9pciStateToPciAddr(pGlobals, addr, &aPciAddr);
    348373
     374    /* Perform configuration space write */
    349375    return ich9pciDataWriteAddr(pGlobals, &aPciAddr, val, len, VINF_IOM_R3_IOPORT_WRITE);
    350376}
    351377
    352 static void ich9pciNoMem(void* ptr, int cb)
    353 {
    354     for (int i = 0; i < cb; i++)
    355         ((uint8_t*)ptr)[i] = 0xff;
    356 }
    357378
    358379/**
    359380 * Port I/O Handler for PCI data OUT operations.
    360381 *
     382 * Emulates writes to Configuration Data Port at 0CFCh for
     383 * Configuration Mechanism #1.
     384 *
    361385 * @returns VBox status code.
    362386 *
    363  * @param   pDevIns     The device instance.
     387 * @param   pDevIns     ICH9 device instance.
    364388 * @param   pvUser      User argument - ignored.
    365389 * @param   uPort       Port number used for the OUT operation.
     
    367391 * @param   cb          The value size in bytes.
    368392 */
    369 PDMBOTHCBDECL(int)  ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
     393PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    370394{
    371395    LogFlow(("ich9pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     
    374398    if (!(Port % cb))
    375399    {
     400        PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
     401
    376402        PCI_LOCK(pDevIns, VINF_IOM_R3_IOPORT_WRITE);
    377         rc = ich9pciDataWrite(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), Port, u32, cb);
     403        rc = ich9pciDataWrite(pThis, Port, u32, cb);
    378404        PCI_UNLOCK(pDevIns);
    379405    }
     
    383409}
    384410
     411
     412static void ich9pciNoMem(void* ptr, int cb)
     413{
     414    for (int i = 0; i < cb; i++)
     415        ((uint8_t*)ptr)[i] = 0xff;
     416}
     417
     418
     419/*
     420 * Perform configuration space read.
     421 */
    385422static int ich9pciDataReadAddr(PICH9PCIGLOBALS pGlobals, PciAddress* pPciAddr, int cb,
    386423                               uint32_t *pu32, int rcReschedule)
    387424{
    388425    int rc = VINF_SUCCESS;
    389 
    390     if (pPciAddr->iBus != 0)
     426#ifdef IN_RING3
     427    NOREF(rcReschedule);
     428#endif
     429
     430    if (pPciAddr->iBus != 0)    /* forward to subordinate bus */
    391431    {
    392432        if (pGlobals->aPciBus.cBridges)
     
    401441            else
    402442                ich9pciNoMem(pu32, cb);
    403             NOREF(rcReschedule);
    404443#else
    405444            rc = rcReschedule;
    406445#endif
    407         } else
     446        }
     447        else
    408448            ich9pciNoMem(pu32, cb);
    409449    }
    410     else
    411     {
    412         if (pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc])
     450    else                    /* forward to directly connected device */
     451    {
     452        R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
     453        if (aDev)
    413454        {
    414455#ifdef IN_RING3
    415             R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
    416456            *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, cb);
    417457#else
     
    426466          pPciAddr->iBus, pPciAddr->iDeviceFunc >> 3, pPciAddr->iDeviceFunc & 0x7, pPciAddr->iRegister,
    427467          cb, *pu32, rc));
    428 
    429468    return rc;
    430469}
    431470
     471
     472/*
     473 * Decode value latched in Configuration Address Port and perform
     474 * requsted read from the target configuration space register.
     475 *
     476 * XXX: This code should be probably moved to its only caller
     477 * (ich9pciIOPortDataRead) to avoid prolifiration of confusingly
     478 * similarly named functions.
     479 */
    432480static int ich9pciDataRead(PICH9PCIGLOBALS pGlobals, uint32_t addr, int cb, uint32_t *pu32)
    433481{
    434     PciAddress aPciAddr;
    435 
    436482    LogFlow(("ich9pciDataRead: config=%x cb=%d\n",  pGlobals->uConfigReg, cb));
    437483
    438484    *pu32 = 0xffffffff;
    439485
     486    /* Configuration space mapping enabled? */
    440487    if (!(pGlobals->uConfigReg & (1 << 31)))
    441488        return VINF_SUCCESS;
    442489
    443     if ((pGlobals->uConfigReg & 0x3) != 0)
    444         return VINF_SUCCESS;
    445 
    446     /* Compute destination device */
     490    /* Decode target device and configuration space register */
     491    PciAddress aPciAddr;
    447492    ich9pciStateToPciAddr(pGlobals, addr, &aPciAddr);
    448493
     494    /* Perform configuration space read */
    449495    return ich9pciDataReadAddr(pGlobals, &aPciAddr, cb, pu32, VINF_IOM_R3_IOPORT_READ);
    450496}
     497
    451498
    452499/**
    453500 * Port I/O Handler for PCI data IN operations.
    454501 *
     502 * Emulates reads from Configuration Data Port at 0CFCh for
     503 * Configuration Mechanism #1.
     504 *
    455505 * @returns VBox status code.
    456506 *
    457  * @param   pDevIns     The device instance.
     507 * @param   pDevIns     ICH9 device instance.
    458508 * @param   pvUser      User argument - ignored.
    459509 * @param   uPort       Port number used for the IN operation.
     
    461511 * @param   cb          Number of bytes read.
    462512 */
    463 PDMBOTHCBDECL(int)  ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
     513PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    464514{
    465515    NOREF(pvUser);
    466516    if (!(Port % cb))
    467517    {
     518        PICH9PCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
     519
    468520        PCI_LOCK(pDevIns, VINF_IOM_R3_IOPORT_READ);
    469         int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), Port, cb, pu32);
     521        int rc = ich9pciDataRead(pThis, Port, cb, pu32);
    470522        PCI_UNLOCK(pDevIns);
     523
    471524        LogFlow(("ich9pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
    472525        return rc;
     
    475528    return VERR_IOM_IOPORT_UNUSED;
    476529}
     530
    477531
    478532/* Compute mapping of PCI slot and IRQ number to APIC interrupt line */
     
    593647}
    594648
    595 PDMBOTHCBDECL(int)  ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
     649
     650/**
     651 * Memory mapped I/O Handler for write operations.
     652 *
     653 * Emulates writes to configuration space.
     654 *
     655 * @returns VBox status code.
     656 *
     657 * @param   pDevIns     The device instance.
     658 * @param   pvUser      User argument.
     659 * @param   GCPhysAddr  Physical address (in GC) where the read starts.
     660 * @param   pv          Where to fetch the result.
     661 * @param   cb          Number of bytes to write.
     662 * @remarks Caller enters the device critical section.
     663 */
     664PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
    596665{
    597666    PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
    598     PciAddress aDest;
    599667    uint32_t u32 = 0;
    600668    NOREF(pvUser);
     
    604672    PCI_LOCK(pDevIns, VINF_IOM_R3_MMIO_WRITE);
    605673
     674    /* Decode target device and configuration space register */
     675    PciAddress aDest;
    606676    ich9pciPhysToPciAddr(pGlobals, GCPhysAddr, &aDest);
    607677
     
    621691            break;
    622692    }
     693
     694    /* Perform configuration space write */
    623695    int rc = ich9pciDataWriteAddr(pGlobals, &aDest, u32, cb, VINF_IOM_R3_MMIO_WRITE);
    624696    PCI_UNLOCK(pDevIns);
     
    627699}
    628700
    629 PDMBOTHCBDECL(int)  ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
     701
     702/**
     703 * Memory mapped I/O Handler for read operations.
     704 *
     705 * Emulates reads from configuration space.
     706 *
     707 * @returns VBox status code.
     708 *
     709 * @param   pDevIns     The device instance.
     710 * @param   pvUser      User argument.
     711 * @param   GCPhysAddr  Physical address (in GC) where the read starts.
     712 * @param   pv          Where to store the result.
     713 * @param   cb          Number of bytes read.
     714 * @remarks Caller enters the device critical section.
     715 */
     716PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
    630717{
    631718    PICH9PCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS);
    632     PciAddress  aDest;
    633719    uint32_t    rv;
    634720    NOREF(pvUser);
     
    638724    PCI_LOCK(pDevIns, VINF_IOM_R3_MMIO_READ);
    639725
     726    /* Decode target device and configuration space register */
     727    PciAddress aDest;
    640728    ich9pciPhysToPciAddr(pGlobals, GCPhysAddr, &aDest);
    641729
     730    /* Perform configuration space read */
    642731    int rc = ich9pciDataReadAddr(pGlobals, &aDest, cb, &rv, VINF_IOM_R3_MMIO_READ);
    643732
     
    14741563}
    14751564
     1565
     1566/*
     1567 * Perform imeediate read of configuration space register.
     1568 * Cannot be rescheduled, as already in R3.
     1569 */
    14761570static uint32_t ich9pciConfigRead(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t len)
    14771571{
    1478     /* Will only work in LSB case */
    1479     uint32_t   u32Val;
    14801572    PciAddress aPciAddr;
    1481 
    14821573    aPciAddr.iBus = uBus;
    14831574    aPciAddr.iDeviceFunc = uDevFn;
    14841575    aPciAddr.iRegister = addr;
    14851576
    1486     /* cannot be rescheduled, as already in R3 */
     1577    uint32_t u32Val;
    14871578    int rc = ich9pciDataReadAddr(pGlobals, &aPciAddr, len, &u32Val, VERR_INTERNAL_ERROR);
    14881579    AssertRC(rc);
     1580
    14891581    return u32Val;
    14901582}
    14911583
     1584
     1585/*
     1586 * Perform imeediate write to configuration space register.
     1587 * Cannot be rescheduled, as already in R3.
     1588 */
    14921589static void ich9pciConfigWrite(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint32_t addr, uint32_t val, uint32_t len)
    14931590{
    14941591    PciAddress aPciAddr;
    1495 
    14961592    aPciAddr.iBus = uBus;
    14971593    aPciAddr.iDeviceFunc = uDevFn;
    14981594    aPciAddr.iRegister = addr;
    14991595
    1500     /* cannot be rescheduled, as already in R3 */
    15011596    int rc = ich9pciDataWriteAddr(pGlobals, &aPciAddr, val, len, VERR_INTERNAL_ERROR);
    15021597    AssertRC(rc);
    15031598}
     1599
    15041600
    15051601static void ich9pciSetRegionAddress(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint64_t addr)
     
    18381934}
    18391935
     1936
     1937/*
     1938 * Configuration space read callback (PCIDEVICEINT::pfnConfigRead) for
     1939 * connected devices.
     1940 */
    18401941static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len)
    18411942{
     
    18811982}
    18821983
     1984
    18831985DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset, uint8_t u8Val)
    18841986{
     
    19242026}
    19252027
     2028
    19262029/**
    1927  * See paragraph 7.5 of PCI Express specification (p. 349) for definition of
    1928  * registers and their writability policy.
     2030 * Configuration space write callback (PCIDEVICEINT::pfnConfigWrite)
     2031 * for connected devices.
     2032 *
     2033 * See paragraph 7.5 of PCI Express specification (p. 349) for
     2034 * definition of registers and their writability policy.
    19292035 */
    19302036static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Address,
     
    21392245static int ich9pciRegisterInternal(PICH9PCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName)
    21402246{
    2141     PciAddress aPosition = {0, 0, 0};
     2247    PciAddress aPosition;
     2248    aPosition.iBus = 0;
     2249    aPosition.iDeviceFunc = 0;
     2250    aPosition.iRegister = 0;
    21422251
    21432252    /*
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