VirtualBox

Changeset 44574 in vbox


Ignore:
Timestamp:
Feb 6, 2013 5:48:18 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
83644
Message:

DevAHCI: Let IOM do the complicated reads. Let IOM filter out unaligned and odd sized writes as well, though we still need to split QWORD writes our selves.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r44571 r44574  
    11/* $Id$ */
    22/** @file
    3  * VBox storage devices: AHCI controller device (disk and cdrom).
    4  *                       Implements the AHCI standard 1.1
     3 * DevAHCI - AHCI controller device (disk and cdrom).
     4 *
     5 * Implements the AHCI standard 1.1
    56 */
    67
     
    21562157 *
    21572158 * @param   pAhci       The AHCI instance.
    2158  * @param   uReg        The register to write.
    2159  * @param   pv          Where to fetch the result.
    2160  * @param   cb          Number of bytes to write.
    2161  */
    2162 static int ahciRegisterWrite(PAHCI pAhci, uint32_t uReg, void const *pv, unsigned cb)
    2163 {
    2164     int rc = VINF_SUCCESS;
     2159 * @param   offReg      The offset of the register to write to.
     2160 * @param   u32Value    The value to write.
     2161 */
     2162static int ahciRegisterWrite(PAHCI pAhci, uint32_t offReg, uint32_t u32Value)
     2163{
     2164    int rc;
    21652165    uint32_t iReg;
    21662166
    2167     if (uReg < AHCI_HBA_GLOBAL_SIZE)
     2167    /*
     2168     * If the access offset is smaller than 100h the guest accesses the global registers.
     2169     * Otherwise it accesses the registers of a port.
     2170     */
     2171    if (offReg < AHCI_HBA_GLOBAL_SIZE)
    21682172    {
    21692173        Log3(("Write global HBA register\n"));
    2170         iReg = uReg >> 2;
     2174        iReg = offReg >> 2;
    21712175        if (iReg < RT_ELEMENTS(g_aOpRegs))
    21722176        {
    21732177            const AHCIOPREG *pReg = &g_aOpRegs[iReg];
    2174             rc = pReg->pfnWrite(pAhci, iReg, *(uint32_t *)pv);
     2178            rc = pReg->pfnWrite(pAhci, iReg, u32Value);
    21752179        }
    21762180        else
     
    21852189        Log3(("Write Port register\n"));
    21862190        /* Calculate accessed port. */
    2187         uReg -= AHCI_HBA_GLOBAL_SIZE;
    2188         iPort = uReg / AHCI_PORT_REGISTER_SIZE;
    2189         iReg  = (uReg % AHCI_PORT_REGISTER_SIZE) >> 2;
     2191        offReg -= AHCI_HBA_GLOBAL_SIZE;
     2192        iPort   =  offReg / AHCI_PORT_REGISTER_SIZE;
     2193        iReg    = (offReg % AHCI_PORT_REGISTER_SIZE) >> 2;
    21902194        Log3(("%s: Trying to write to port %u and register %u\n", __FUNCTION__, iPort, iReg));
    21912195        if (RT_LIKELY(   iPort < pAhci->cPortsImpl
     
    21932197        {
    21942198            const AHCIPORTOPREG *pPortReg = &g_aPortOpRegs[iReg];
    2195             rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, *(uint32_t *)pv);
     2199            rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, u32Value);
    21962200        }
    21972201        else
     
    22192223{
    22202224    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    2221     int   rc = VINF_SUCCESS;
    2222 
    2223     /* Break up 64 bits reads into two dword reads. */
    2224     if (cb == 8)
    2225     {
    2226         rc = ahciMMIORead(pDevIns, pvUser, GCPhysAddr, pv, 4);
    2227         if (RT_FAILURE(rc))
    2228             return rc;
    2229 
    2230         return ahciMMIORead(pDevIns, pvUser, GCPhysAddr + 4, (uint8_t *)pv + 4, 4);
    2231     }
    2232 
    2233     Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n",
    2234           pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr, rc));
    2235 
    2236     uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase);
    2237     rc = ahciRegisterRead(pAhci, uOffset, pv, cb);
     2225    Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n",
     2226          pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr));
     2227
     2228    int rc = ahciRegisterRead(pAhci, GCPhysAddr - pAhci->MMIOBase, pv, cb);
    22382229
    22392230    Log2(("#%d ahciMMIORead: return pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n",
     
    22572248{
    22582249    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    2259     int   rc = VINF_SUCCESS;
     2250    Assert(cb == 4 || cb == 8);
     2251    Assert(!(GCPhysAddr & (cb - 1)));
    22602252
    22612253    /* Break up 64 bits writes into two dword writes. */
     2254    /** @todo Eliminate this code once the IOM/EM starts taking care of these
     2255         *    situations. */
    22622256    if (cb == 8)
    22632257    {
     
    22692263         * which can cause errors in the guest.
    22702264         */
     2265        int rc = VINF_SUCCESS;
    22712266        if (!pAhci->f8ByteMMIO4BytesWrittenSuccessfully)
    22722267        {
     
    22892284    }
    22902285
    2291     Log2(("#%d ahciMMIOWrite: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n",
    2292           pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr));
    2293 
    2294     /* Validate access. */
    2295     if (cb != sizeof(uint32_t))
    2296     {
    2297         Log2(("%s: Bad write size!!! GCPhysAddr=%RGp cb=%d\n", __FUNCTION__, GCPhysAddr, cb));
    2298         return VINF_SUCCESS;
    2299     }
    2300     if (GCPhysAddr & 0x3)
    2301     {
    2302         Log2(("%s: Unaligned write!!! GCPhysAddr=%RGp cb=%d\n", __FUNCTION__, GCPhysAddr, cb));
    2303         return VINF_SUCCESS;
    2304     }
    2305 
    2306     /*
    2307      * If the access offset is smaller than 100h the guest accesses the global registers.
    2308      * Otherwise it accesses the registers of a port.
    2309      */
    2310     uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase);
    2311     rc = ahciRegisterWrite(pAhci, uOffset, pv, cb);
    2312 
    2313     return rc;
     2286    /* Do the access. */
     2287    Log2(("#%d ahciMMIOWrite: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n", pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr));
     2288    return ahciRegisterWrite(pAhci, GCPhysAddr - pAhci->MMIOBase, *(uint32_t const *)pv);
    23142289}
    23152290
     
    23552330        else
    23562331        {
     2332            /** @todo range check? */
    23572333            Assert(iReg == 1);
    2358             rc = ahciRegisterWrite(pAhci, pAhci->regIdx, &u32, cb);
     2334            rc = ahciRegisterWrite(pAhci, pAhci->regIdx, u32);
    23592335            if (rc == VINF_IOM_R3_MMIO_WRITE)
    23602336                rc = VINF_IOM_R3_IOPORT_WRITE;
     
    23982374        {
    23992375            Assert(iReg == 1);
     2376            /** @todo range check? */
    24002377            rc = ahciRegisterRead(pAhci, pAhci->regIdx, pu32, cb);
    24012378            if (rc == VINF_IOM_R3_MMIO_READ)
     
    24252402
    24262403    /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */
     2404    /** @todo change this to IOMMMIO_FLAGS_WRITE_ONLY_DWORD once EM/IOM starts
     2405     * handling 2nd DWORD failures on split accesses correctly. */
    24272406    rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    2428                                IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     2407                               IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD,
    24292408                               ahciMMIOWrite, ahciMMIORead, "AHCI");
    24302409    if (RT_FAILURE(rc))
     
    58285807 * @param   rcReq        IPRT Status code of the completed request.
    58295808 */
    5830 static DECLCALLBACK(int) ahciTransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq)
     5809static DECLCALLBACK(int) ahciR3TransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq)
    58315810{
    58325811    PAHCIPort pAhciPort = PDMIBLOCKASYNCPORT_2_PAHCIPORT(pInterface);
     
    71887167 * @param   pInterface      Pointer to the interface structure containing the called function pointer.
    71897168 */
    7190 static DECLCALLBACK(void) ahciMountNotify(PPDMIMOUNTNOTIFY pInterface)
     7169static DECLCALLBACK(void) ahciR3MountNotify(PPDMIMOUNTNOTIFY pInterface)
    71917170{
    71927171    PAHCIPort pAhciPort = PDMIMOUNTNOTIFY_2_PAHCIPORT(pInterface);
     
    72177196 * @param   pInterface      Pointer to the interface structure containing the called function pointer.
    72187197 */
    7219 static DECLCALLBACK(void) ahciUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
     7198static DECLCALLBACK(void) ahciR3UnmountNotify(PPDMIMOUNTNOTIFY pInterface)
    72207199{
    72217200    PAHCIPort pAhciPort = PDMIMOUNTNOTIFY_2_PAHCIPORT(pInterface);
     
    81088087         */
    81098088        pAhciPort->IBase.pfnQueryInterface              = ahciR3PortQueryInterface;
    8110         pAhciPort->IPortAsync.pfnTransferCompleteNotify = ahciTransferCompleteNotify;
     8089        pAhciPort->IPortAsync.pfnTransferCompleteNotify = ahciR3TransferCompleteNotify;
    81118090        pAhciPort->IPort.pfnQueryDeviceLocation         = ahciR3PortQueryDeviceLocation;
    8112         pAhciPort->IMountNotify.pfnMountNotify          = ahciMountNotify;
    8113         pAhciPort->IMountNotify.pfnUnmountNotify        = ahciUnmountNotify;
     8091        pAhciPort->IMountNotify.pfnMountNotify          = ahciR3MountNotify;
     8092        pAhciPort->IMountNotify.pfnUnmountNotify        = ahciR3UnmountNotify;
    81148093        pAhciPort->fAsyncIOThreadIdle                   = true;
    81158094
     
    81878166        return PDMDEV_SET_ERROR(pDevIns, rc, N_("AHCI cannot attach to status driver"));
    81888167    }
    8189     rc = PDMDevHlpSSMRegisterEx(pDevIns, AHCI_SAVED_STATE_VERSION, sizeof(*pThis)+cbTotalBufferSize, NULL,
     8168    rc = PDMDevHlpSSMRegisterEx(pDevIns, AHCI_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBufferSize, NULL,
    81908169                                NULL,           ahciR3LiveExec, NULL,
    81918170                                ahciR3SavePrep, ahciR3SaveExec, NULL,
Note: See TracChangeset for help on using the changeset viewer.

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