VirtualBox

Ignore:
Timestamp:
Oct 25, 2011 2:47:02 PM (13 years ago)
Author:
vboxsync
Message:

IOM,PDM: Working on moving unaligned and non-dword MMIO access splitting and buffering up into IOM (from the device emulation).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r39078 r39111  
    7676
    7777/**
     78 * Deals with complicated MMIO writes.
     79 *
     80 * Complicatd means unaligned or non-dword/qword align accesses depending on
     81 * the MMIO region's access mode flags.
     82 *
     83 * @returns Strict VBox status code. Any EM scheduling status code,
     84 *          VINF_IOM_HC_MMIO_WRITE, VINF_IOM_HC_MMIO_READ_WRITE or
     85 *          VINF_IOM_HC_MMIO_READ may be returned.
     86 *
     87 * @param   pRange              The range to write to.
     88 * @param   GCPhys              The physical address to start writing.
     89 * @param   pvValue             Where to store the value.
     90 * @param   cbValue             The size of the value to write.
     91 */
     92static VBOXSTRICTRC iomMMIODoComplicatedWrite(PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void const *pvValue, unsigned cbValue)
     93{
     94    AssertReturn(   (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) != IOMMMIO_FLAGS_WRITE_PASSTHRU
     95                 || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) <= IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING,
     96                 VERR_INTERNAL_ERROR_5);
     97    AssertReturn(cbValue != 0 && cbValue <= 16, VERR_INTERNAL_ERROR_4);
     98    RTGCPHYS const GCPhysStart  = GCPhys; NOREF(GCPhysStart);
     99    bool const     fReadMissing = (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) >= IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING;
     100
     101    /*
     102     * Split and conquer.
     103     */
     104    int rc = VINF_SUCCESS;
     105    for (;;)
     106    {
     107        unsigned const  offAccess  = GCPhys & 3;
     108        unsigned        cbThisPart = 4 - offAccess;
     109        if (cbThisPart > cbValue)
     110            cbThisPart = cbValue;
     111
     112        /*
     113         * Get the missing bits (if any).
     114         */
     115        uint32_t u32MissingValue = 0;
     116        if (fReadMissing && cbThisPart != 4)
     117        {
     118            int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
     119                                                        GCPhys & ~(RTGCPHYS)3, &u32MissingValue, sizeof(u32MissingValue));
     120            switch (rc2)
     121            {
     122                case VINF_SUCCESS:
     123                    break;
     124                case VINF_IOM_MMIO_UNUSED_FF:
     125                    u32MissingValue = UINT32_C(0xffffffff);
     126                    break;
     127                case VINF_IOM_MMIO_UNUSED_00:
     128                    u32MissingValue = 0;
     129                    break;
     130                case VINF_IOM_HC_MMIO_READ:
     131                case VINF_IOM_HC_MMIO_READ_WRITE:
     132                case VINF_IOM_HC_MMIO_WRITE:
     133                    /** @todo What if we've split a transfer and already read
     134                     * something?  Since reads can have sideeffects we could be
     135                     * kind of screwed here... */
     136                    LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2));
     137                    return rc2;
     138                default:
     139                    if (RT_FAILURE(rc2))
     140                    {
     141                        Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2));
     142                        return rc2;
     143                    }
     144                    AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
     145                    if (rc == VINF_SUCCESS || rc2 < rc)
     146                        rc = rc2;
     147                    break;
     148            }
     149        }
     150
     151        /*
     152         * Merge missing and given bits.
     153         */
     154        uint32_t u32GivenMask;
     155        uint32_t u32GivenValue;
     156        switch (cbThisPart)
     157        {
     158            case 1:
     159                u32GivenValue = *(uint8_t  const *)pvValue;
     160                u32GivenMask  = UINT32_C(0x000000ff);
     161                break;
     162            case 2:
     163                u32GivenValue = *(uint16_t const *)pvValue;
     164                u32GivenMask  = UINT32_C(0x0000ffff);
     165                break;
     166            case 3:
     167                u32GivenValue = RT_MAKE_U32_FROM_U8(((uint8_t const *)pvValue)[0], ((uint8_t const *)pvValue)[1],
     168                                                    ((uint8_t const *)pvValue)[2], 0);
     169                u32GivenMask  = UINT32_C(0x00ffffff);
     170                break;
     171            case 4:
     172                u32GivenValue = *(uint32_t const *)pvValue;
     173                u32GivenMask  = UINT32_C(0xffffffff);
     174                break;
     175            default:
     176                AssertFailedReturn(VERR_INTERNAL_ERROR_3);
     177        }
     178        if (offAccess)
     179        {
     180            u32GivenValue <<= offAccess * 8;
     181            u32GivenMask <<= offAccess * 8;
     182        }
     183
     184        uint32_t u32Value = (u32MissingValue & ~u32GivenMask)
     185                          | (u32GivenValue & u32GivenMask);
     186
     187        /*
     188         * Do DWORD write to the device.
     189         */
     190        int rc2 = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
     191                                                     GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value));
     192        switch (rc2)
     193        {
     194            case VINF_SUCCESS:
     195                break;
     196            case VINF_IOM_HC_MMIO_READ:
     197            case VINF_IOM_HC_MMIO_READ_WRITE:
     198            case VINF_IOM_HC_MMIO_WRITE:
     199                /** @todo What if we've split a transfer and already read
     200                 * something?  Since reads can have sideeffects we could be
     201                 * kind of screwed here... */
     202                LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2));
     203                return rc2;
     204            default:
     205                if (RT_FAILURE(rc2))
     206                {
     207                    Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2));
     208                    return rc2;
     209                }
     210                AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
     211                if (rc == VINF_SUCCESS || rc2 < rc)
     212                    rc = rc2;
     213                break;
     214        }
     215
     216        /*
     217         * Advance.
     218         */
     219        cbValue -= cbThisPart;
     220        if (!cbValue)
     221            break;
     222        GCPhys += cbThisPart;
     223        pvValue = (uint8_t const *)pvValue + cbThisPart;
     224    }
     225
     226    return rc;
     227}
     228
     229
     230
     231
     232/**
    78233 * Wrapper which does the write and updates range statistics when such are enabled.
    79234 * @warning RT_SUCCESS(rc=VINF_IOM_HC_MMIO_WRITE) is TRUE!
     
    87242
    88243    STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
    89     int rc;
     244    VBOXSTRICTRC rc;
    90245    if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback)))
    91         rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
    92                                                 GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */
     246    {
     247        if (   (cb == 4 && !(GCPhysFault & 3))
     248            || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_PASSTHRU
     249            || (cb == 8 && !(GCPhysFault & 7)) )
     250            rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
     251                                                    GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */
     252        else
     253            rc = iomMMIODoComplicatedWrite(pRange, GCPhysFault, pvData, cb);
     254    }
    93255    else
    94256        rc = VINF_SUCCESS;
    95257    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
    96258    STAM_COUNTER_INC(&pStats->Accesses);
     259    return VBOXSTRICTRC_TODO(rc);
     260}
     261
     262
     263/**
     264 * Deals with complicated MMIO reads.
     265 *
     266 * Complicatd means unaligned or non-dword/qword align accesses depending on
     267 * the MMIO region's access mode flags.
     268 *
     269 * @returns Strict VBox status code. Any EM scheduling status code,
     270 *          VINF_IOM_HC_MMIO_READ, VINF_IOM_HC_MMIO_READ_WRITE or
     271 *          VINF_IOM_HC_MMIO_WRITE may be returned.
     272 *
     273 * @param   pRange              The range to read from.
     274 * @param   GCPhys              The physical address to start reading.
     275 * @param   pvValue             Where to store the value.
     276 * @param   cbValue             The size of the value to read.
     277 */
     278static VBOXSTRICTRC iomMMIODoComplicatedRead(PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue)
     279{
     280    AssertReturn(   (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD
     281                 || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD_QWORD,
     282                 VERR_INTERNAL_ERROR_5);
     283    AssertReturn(cbValue != 0 && cbValue <= 16, VERR_INTERNAL_ERROR_4);
     284    RTGCPHYS const GCPhysStart = GCPhys; NOREF(GCPhysStart);
     285
     286    /*
     287     * Split and conquer.
     288     */
     289    int rc = VINF_SUCCESS;
     290    for (;;)
     291    {
     292        /*
     293         * Do DWORD read from the device.
     294         */
     295        uint32_t u32Value;
     296        int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
     297                                                    GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value));
     298        switch (rc2)
     299        {
     300            case VINF_SUCCESS:
     301                break;
     302            case VINF_IOM_MMIO_UNUSED_FF:
     303                u32Value = UINT32_C(0xffffffff);
     304                break;
     305            case VINF_IOM_MMIO_UNUSED_00:
     306                u32Value = 0;
     307                break;
     308            case VINF_IOM_HC_MMIO_READ:
     309            case VINF_IOM_HC_MMIO_READ_WRITE:
     310            case VINF_IOM_HC_MMIO_WRITE:
     311                /** @todo What if we've split a transfer and already read
     312                 * something?  Since reads can have sideeffects we could be
     313                 * kind of screwed here... */
     314                LogFlow(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2));
     315                return rc2;
     316            default:
     317                if (RT_FAILURE(rc2))
     318                {
     319                    Log(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2));
     320                    return rc2;
     321                }
     322                AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
     323                if (rc == VINF_SUCCESS || rc2 < rc)
     324                    rc = rc2;
     325                break;
     326        }
     327        u32Value >>= (GCPhys & 3) * 8;
     328
     329        /*
     330         * Write what we've read.
     331         */
     332        unsigned cbThisPart = 4 - (GCPhys & 3);
     333        if (cbThisPart > cbValue)
     334            cbThisPart = cbValue;
     335
     336        switch (cbThisPart)
     337        {
     338            case 1:
     339                *(uint8_t *)pvValue = (uint8_t)u32Value;
     340                break;
     341            case 2:
     342                *(uint16_t *)pvValue = (uint16_t)u32Value;
     343                break;
     344            case 3:
     345                ((uint8_t *)pvValue)[0] = RT_BYTE1(u32Value);
     346                ((uint8_t *)pvValue)[1] = RT_BYTE2(u32Value);
     347                ((uint8_t *)pvValue)[2] = RT_BYTE3(u32Value);
     348                break;
     349            case 4:
     350                *(uint32_t *)pvValue = u32Value;
     351                break;
     352        }
     353
     354        /*
     355         * Advance.
     356         */
     357        cbValue -= cbThisPart;
     358        if (!cbValue)
     359            break;
     360        GCPhys += cbThisPart;
     361        pvValue = (uint8_t *)pvValue + cbThisPart;
     362    }
     363
    97364    return rc;
     365}
     366
     367
     368/**
     369 * Implements VINF_IOM_MMIO_UNUSED_FF.
     370 *
     371 * @returns VINF_SUCCESS.
     372 * @param   pvValue             Where to store the zeros.
     373 * @param   cbValue             How many bytes to read.
     374 */
     375static int iomMMIODoReadFFs(void *pvValue, unsigned cbValue)
     376{
     377    switch (cbValue)
     378    {
     379        case 1: *(uint8_t  *)pvValue = UINT8_C(0xff); break;
     380        case 2: *(uint16_t *)pvValue = UINT16_C(0xffff); break;
     381        case 4: *(uint32_t *)pvValue = UINT32_C(0xffffffff); break;
     382        case 8: *(uint64_t *)pvValue = UINT64_C(0xffffffffffffffff); break;
     383        default:
     384        {
     385            uint8_t *pb = (uint8_t *)pvValue;
     386            while (cbValue--)
     387                *pb++ = UINT8_C(0xff);
     388            break;
     389        }
     390    }
     391    return VINF_SUCCESS;
     392}
     393
     394
     395/**
     396 * Implements VINF_IOM_MMIO_UNUSED_00.
     397 *
     398 * @returns VINF_SUCCESS.
     399 * @param   pvValue             Where to store the zeros.
     400 * @param   cbValue             How many bytes to read.
     401 */
     402static int iomMMIODoRead00s(void *pvValue, unsigned cbValue)
     403{
     404    switch (cbValue)
     405    {
     406        case 1: *(uint8_t  *)pvValue = UINT8_C(0x00); break;
     407        case 2: *(uint16_t *)pvValue = UINT16_C(0x0000); break;
     408        case 4: *(uint32_t *)pvValue = UINT32_C(0x00000000); break;
     409        case 8: *(uint64_t *)pvValue = UINT64_C(0x0000000000000000); break;
     410        default:
     411        {
     412            uint8_t *pb = (uint8_t *)pvValue;
     413            while (cbValue--)
     414                *pb++ = UINT8_C(0x00);
     415            break;
     416        }
     417    }
     418    return VINF_SUCCESS;
    98419}
    99420
     
    107428    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange);
    108429    Assert(pStats);
    109 #endif
    110 
    111430    STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a);
    112     int rc;
     431#endif
     432
     433    VBOXSTRICTRC rc;
    113434    if (RT_LIKELY(pRange->CTX_SUFF(pfnReadCallback)))
    114         rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pvValue, cbValue);
     435    {
     436        if (   (cbValue == 4 && !(GCPhys & 3))
     437            || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_PASSTHRU
     438            || (cbValue == 8 && !(GCPhys & 7)) )
     439            rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pvValue, cbValue);
     440        else
     441            rc = iomMMIODoComplicatedRead(pRange, GCPhys, pvValue, cbValue);
     442    }
    115443    else
    116444        rc = VINF_IOM_MMIO_UNUSED_FF;
    117445    if (rc != VINF_SUCCESS)
    118446    {
    119         switch (rc)
    120         {
    121             case VINF_IOM_MMIO_UNUSED_FF:
    122                 switch (cbValue)
    123                 {
    124                     case 1: *(uint8_t  *)pvValue = UINT8_C(0xff); break;
    125                     case 2: *(uint16_t *)pvValue = UINT16_C(0xffff); break;
    126                     case 4: *(uint32_t *)pvValue = UINT32_C(0xffffffff); break;
    127                     case 8: *(uint64_t *)pvValue = UINT64_C(0xffffffffffffffff); break;
    128                     default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
    129                 }
    130                 rc = VINF_SUCCESS;
    131                 break;
    132 
    133             case VINF_IOM_MMIO_UNUSED_00:
    134                 switch (cbValue)
    135                 {
    136                     case 1: *(uint8_t  *)pvValue = UINT8_C(0x00); break;
    137                     case 2: *(uint16_t *)pvValue = UINT16_C(0x0000); break;
    138                     case 4: *(uint32_t *)pvValue = UINT32_C(0x00000000); break;
    139                     case 8: *(uint64_t *)pvValue = UINT64_C(0x0000000000000000); break;
    140                     default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
    141                 }
    142                 rc = VINF_SUCCESS;
    143                 break;
     447        switch (VBOXSTRICTRC_VAL(rc))
     448        {
     449            case VINF_IOM_MMIO_UNUSED_FF: rc = iomMMIODoReadFFs(pvValue, cbValue); break;
     450            case VINF_IOM_MMIO_UNUSED_00: rc = iomMMIODoRead00s(pvValue, cbValue); break;
    144451        }
    145452    }
    146453    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
    147454    STAM_COUNTER_INC(&pStats->Accesses);
    148     return rc;
     455    return VBOXSTRICTRC_VAL(rc);
    149456}
    150457
     
    14381745{
    14391746    /* Take the IOM lock before performing any MMIO. */
    1440     int rc = IOM_LOCK(pVM);
     1747    VBOXSTRICTRC rc = IOM_LOCK(pVM);
    14411748#ifndef IN_RING3
    14421749    if (rc == VERR_SEM_BUSY)
    14431750        return VINF_IOM_HC_MMIO_WRITE;
    14441751#endif
    1445     AssertRC(rc);
     1752    AssertRC(VBOXSTRICTRC_VAL(rc));
    14461753#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
    14471754    IEMNotifyMMIORead(pVM, GCPhys, cbValue);
     
    14911798         */
    14921799        STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a);
    1493         rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pu32Value, (unsigned)cbValue);
     1800        if (   (cbValue == 4 && !(GCPhys & 3))
     1801            || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_PASSTHRU
     1802            || (cbValue == 8 && !(GCPhys & 7)) )
     1803            rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys,
     1804                                                   pu32Value, (unsigned)cbValue);
     1805        else
     1806            rc = iomMMIODoComplicatedRead(pRange, GCPhys, pu32Value, (unsigned)cbValue);
    14941807        STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
    1495         switch (rc)
     1808        switch (VBOXSTRICTRC_VAL(rc))
    14961809        {
    14971810            case VINF_SUCCESS:
     
    15061819#endif
    15071820            default:
    1508                 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
     1821                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
    15091822                iomMmioReleaseRange(pVM, pRange);
    15101823                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
     
    15121825
    15131826            case VINF_IOM_MMIO_UNUSED_00:
    1514                 switch (cbValue)
    1515                 {
    1516                     case 1: *(uint8_t  *)pu32Value = UINT8_C(0x00); break;
    1517                     case 2: *(uint16_t *)pu32Value = UINT16_C(0x0000); break;
    1518                     case 4: *(uint32_t *)pu32Value = UINT32_C(0x00000000); break;
    1519                     case 8: *(uint64_t *)pu32Value = UINT64_C(0x0000000000000000); break;
    1520                     default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
    1521                 }
    1522                 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
     1827                iomMMIODoRead00s(pu32Value, cbValue);
     1828                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
    15231829                iomMmioReleaseRange(pVM, pRange);
    15241830                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
     
    15261832
    15271833            case VINF_IOM_MMIO_UNUSED_FF:
    1528                 switch (cbValue)
    1529                 {
    1530                     case 1: *(uint8_t  *)pu32Value = UINT8_C(0xff); break;
    1531                     case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break;
    1532                     case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
    1533                     case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break;
    1534                     default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
    1535                 }
    1536                 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));
     1834                iomMMIODoReadFFs(pu32Value, cbValue);
     1835                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
    15371836                iomMmioReleaseRange(pVM, pRange);
    15381837                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
     
    15551854    STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); /** @todo STAM_PROFILE_ADD_ZERO_PERIOD */
    15561855    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
    1557     switch (cbValue)
    1558     {
    1559         case 1: *(uint8_t  *)pu32Value = UINT8_C(0xff); break;
    1560         case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break;
    1561         case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break;
    1562         case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break;
    1563         default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break;
    1564     }
     1856    iomMMIODoReadFFs(pu32Value, cbValue);
    15651857    Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
    15661858    IOM_UNLOCK(pVM);
     
    15821874{
    15831875    /* Take the IOM lock before performing any MMIO. */
    1584     int rc = IOM_LOCK(pVM);
     1876    VBOXSTRICTRC rc = IOM_LOCK(pVM);
    15851877#ifndef IN_RING3
    15861878    if (rc == VERR_SEM_BUSY)
    15871879        return VINF_IOM_HC_MMIO_WRITE;
    15881880#endif
    1589     AssertRC(rc);
     1881    AssertRC(VBOXSTRICTRC_VAL(rc));
    15901882#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
    15911883    IEMNotifyMMIOWrite(pVM, GCPhys, u32Value, cbValue);
     
    16351927         */
    16361928        STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
    1637         rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
    1638                                                 GCPhys, &u32Value, (unsigned)cbValue);
     1929        if (   (cbValue == 4 && !(GCPhys & 3))
     1930            || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_PASSTHRU
     1931            || (cbValue == 8 && !(GCPhys & 7)) )
     1932            rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
     1933                                                    GCPhys, &u32Value, (unsigned)cbValue);
     1934        else
     1935            rc = iomMMIODoComplicatedWrite(pRange, GCPhys, &u32Value, (unsigned)cbValue);
    16391936        STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
    16401937#ifndef IN_RING3
     
    16431940            STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3));
    16441941#endif
    1645         Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, rc));
     1942        Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
    16461943        iomMmioReleaseRange(pVM, pRange);
    16471944        PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
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