VirtualBox

Changeset 81181 in vbox


Ignore:
Timestamp:
Oct 9, 2019 12:09:24 PM (5 years ago)
Author:
vboxsync
Message:

Audio/HDA: Added more SD register checks (bugref:9569).

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevHDA.cpp

    r81031 r81181  
    402402    /* Offset 0x88 (SD0) */ \
    403403    { offset + 0x8,  0x00004, 0xFFFFFFFF, 0xFFFFFFFF, HDA_RD_FLAG_NONE,         hdaRegReadU32 , hdaRegWriteSDCBL  , HDA_REG_IDX_STRM(name, CBL)  , #name " Cyclic Buffer Length" }, \
    404     /* Offset 0x8C (SD0) */ \
    405     { offset + 0xC,  0x00002, 0x0000FFFF, 0x0000FFFF, HDA_RD_FLAG_NONE,         hdaRegReadU16 , hdaRegWriteSDLVI  , HDA_REG_IDX_STRM(name, LVI)  , #name " Last Valid Index" }, \
     404    /* Offset 0x8C (SD0) -- upper 8 bits are reserved */ \
     405    { offset + 0xC,  0x00002, 0x0000FFFF, 0x000000FF, HDA_RD_FLAG_NONE,         hdaRegReadU16 , hdaRegWriteSDLVI  , HDA_REG_IDX_STRM(name, LVI)  , #name " Last Valid Index" }, \
    406406    /* Reserved: FIFO Watermark. ** @todo Document this! */ \
    407407    { offset + 0xE,  0x00002, 0x00000007, 0x00000007, HDA_RD_FLAG_NONE,         hdaRegReadU16 , hdaRegWriteSDFIFOW, HDA_REG_IDX_STRM(name, FIFOW), #name " FIFO Watermark" }, \
     
    13681368            hdaR3StreamLock(pStream);
    13691369
    1370             int rc2;
     1370            int rc2 = VINF_SUCCESS;
    13711371
    13721372# ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     
    14201420            }
    14211421
    1422             /* Enable/disable the stream. */
    1423             rc2 = hdaR3StreamEnable(pStream, fRun /* fEnable */);
    1424             AssertRC(rc2);
    1425 
    1426             if (fRun)
     1422            if (RT_SUCCESS(rc2))
    14271423            {
    1428                 /* Keep track of running streams. */
    1429                 pThis->cStreamsActive++;
    1430 
    1431                 /* (Re-)init the stream's period. */
    1432                 hdaR3StreamPeriodInit(&pStream->State.Period,
    1433                                       pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.Cfg);
    1434 
    1435                 /* Begin a new period for this stream. */
    1436                 rc2 = hdaR3StreamPeriodBegin(&pStream->State.Period, hdaWalClkGetCurrent(pThis)/* Use current wall clock time */);
     1424                /* Enable/disable the stream. */
     1425                rc2 = hdaR3StreamEnable(pStream, fRun /* fEnable */);
    14371426                AssertRC(rc2);
    14381427
    1439                 rc2 = hdaR3TimerSet(pThis, pStream, TMTimerGet(pThis->pTimer[pStream->u8SD]) + pStream->State.cTransferTicks, false /* fForce */);
    1440                 AssertRC(rc2);
    1441             }
    1442             else
    1443             {
    1444                 /* Keep track of running streams. */
    1445                 Assert(pThis->cStreamsActive);
    1446                 if (pThis->cStreamsActive)
    1447                     pThis->cStreamsActive--;
    1448 
    1449                 /* Make sure to (re-)schedule outstanding (delayed) interrupts. */
    1450                 hdaR3ReschedulePendingInterrupts(pThis);
    1451 
    1452                 /* Reset the period. */
    1453                 hdaR3StreamPeriodReset(&pStream->State.Period);
     1428                if (fRun)
     1429                {
     1430                    /* Keep track of running streams. */
     1431                    pThis->cStreamsActive++;
     1432
     1433                    /* (Re-)init the stream's period. */
     1434                    hdaR3StreamPeriodInit(&pStream->State.Period,
     1435                                          pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.Cfg);
     1436
     1437                    /* Begin a new period for this stream. */
     1438                    rc2 = hdaR3StreamPeriodBegin(&pStream->State.Period, hdaWalClkGetCurrent(pThis)/* Use current wall clock time */);
     1439                    AssertRC(rc2);
     1440
     1441                    rc2 = hdaR3TimerSet(pThis, pStream, TMTimerGet(pThis->pTimer[pStream->u8SD]) + pStream->State.cTransferTicks,
     1442                                        false /* fForce */);
     1443                    AssertRC(rc2);
     1444                }
     1445                else
     1446                {
     1447                    /* Keep track of running streams. */
     1448                    Assert(pThis->cStreamsActive);
     1449                    if (pThis->cStreamsActive)
     1450                        pThis->cStreamsActive--;
     1451
     1452                    /* Make sure to (re-)schedule outstanding (delayed) interrupts. */
     1453                    hdaR3ReschedulePendingInterrupts(pThis);
     1454
     1455                    /* Reset the period. */
     1456                    hdaR3StreamPeriodReset(&pStream->State.Period);
     1457                }
    14541458            }
    14551459
     
    15971601    DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    15981602
     1603    const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);
     1604
    15991605#ifdef HDA_USE_DMA_ACCESS_HANDLER
    1600     uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);
    1601 
    16021606    if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
    16031607    {
     
    16131617    }
    16141618#endif
     1619
     1620    ASSERT_GUEST_LOGREL_MSG(u32Value <= UINT8_MAX, /* Should be covered by the register write mask, but just to make sure. */
     1621                            ("LVI for stream #%RU8 must not be bigger than %RU8\n", uSD, UINT8_MAX - 1));
    16151622
    16161623    int rc2 = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value);
  • trunk/src/VBox/Devices/Audio/HDAStream.cpp

    r80692 r81181  
    2626#include <iprt/semaphore.h>
    2727
     28#include <VBox/AssertGuest.h>
    2829#include <VBox/vmm/pdmdev.h>
    2930#include <VBox/vmm/pdmaudioifs.h>
     
    239240    AssertRCReturn(rc, rc);
    240241
     242    ASSERT_GUEST_LOGREL_MSG_RETURN(u32CBL % pStream->State.Mapping.cbFrameSize == 0,
     243                                   ("CBL for stream #%RU8 does not align to frame size\n", pStream->u8SD),
     244                                   VERR_INVALID_PARAMETER);
     245
    241246    /*
    242247     * Set the stream's timer Hz rate, based on the stream channel count.
     
    344349             pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS));
    345350
    346     /* Make sure that mandatory parameters are set up correctly. */
    347     AssertStmt(pStream->u32CBL %  pStream->State.Mapping.cbFrameSize == 0, rc = VERR_INVALID_PARAMETER);
    348     AssertStmt(pStream->u16LVI >= 1,                                       rc = VERR_INVALID_PARAMETER);
    349 
    350351    if (RT_SUCCESS(rc))
    351352    {
     
    357358        /* Figure out how many transfer fragments we're going to use for this stream. */
    358359        /** @todo Use a more dynamic fragment size? */
    359         Assert(pStream->u16LVI <= UINT8_MAX - 1);
    360360        uint8_t cFragments = pStream->u16LVI + 1;
    361361        if (cFragments <= 1)
     
    446446        Assert(pStream->State.cbTransferSize);
    447447        Assert(pStream->State.cbTransferSize % pStream->State.Mapping.cbFrameSize == 0);
    448 
    449         /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration.
    450          * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */
    451         pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pStream->State.uTimerHz) * pStream->State.Mapping.cbFrameSize;
    452         Assert(pStream->State.cbTransferChunk);
    453         Assert(pStream->State.cbTransferChunk % pStream->State.Mapping.cbFrameSize == 0);
    454 
    455         /* Make sure that the transfer chunk does not exceed the overall transfer size. */
    456         if (pStream->State.cbTransferChunk > pStream->State.cbTransferSize)
    457             pStream->State.cbTransferChunk = pStream->State.cbTransferSize;
    458 
    459         const uint64_t cTicksPerHz = TMTimerGetFreq(pStream->pTimer) / pStream->State.uTimerHz;
    460 
    461         /* Calculate the timer ticks per byte for this stream. */
    462         pStream->State.cTicksPerByte = cTicksPerHz / pStream->State.cbTransferChunk;
    463         Assert(pStream->State.cTicksPerByte);
    464 
    465         /* Calculate timer ticks per transfer. */
    466         pStream->State.cTransferTicks     = pStream->State.cbTransferChunk * pStream->State.cTicksPerByte;
    467         Assert(pStream->State.cTransferTicks);
    468 
    469         LogFunc(("[SD%RU8] Timer %uHz (%RU64 ticks per Hz), cTicksPerByte=%RU64, cbTransferChunk=%RU32, cTransferTicks=%RU64, " \
    470                  "cbTransferSize=%RU32\n",
    471                  pStream->u8SD, pStream->State.uTimerHz, cTicksPerHz, pStream->State.cTicksPerByte,
    472                  pStream->State.cbTransferChunk, pStream->State.cTransferTicks, pStream->State.cbTransferSize));
    473 
    474         /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */
    475         hdaR3StreamSetPosition(pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD));
     448        ASSERT_GUEST_LOGREL_MSG_STMT(pStream->State.cbTransferSize,
     449                                     ("Transfer size for stream #%RU8 is invalid\n", pStream->u8SD), rc = VERR_INVALID_PARAMETER);
     450        if (RT_SUCCESS(rc))
     451        {
     452            /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration.
     453             * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */
     454            pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pStream->State.uTimerHz) * pStream->State.Mapping.cbFrameSize;
     455            Assert(pStream->State.cbTransferChunk);
     456            Assert(pStream->State.cbTransferChunk % pStream->State.Mapping.cbFrameSize == 0);
     457            ASSERT_GUEST_LOGREL_MSG_STMT(pStream->State.cbTransferChunk,
     458                                         ("Transfer chunk for stream #%RU8 is invalid\n", pStream->u8SD),
     459                                         rc = VERR_INVALID_PARAMETER);
     460            if (RT_SUCCESS(rc))
     461            {
     462                /* Make sure that the transfer chunk does not exceed the overall transfer size. */
     463                if (pStream->State.cbTransferChunk > pStream->State.cbTransferSize)
     464                    pStream->State.cbTransferChunk = pStream->State.cbTransferSize;
     465
     466                const uint64_t cTicksPerHz = TMTimerGetFreq(pStream->pTimer) / pStream->State.uTimerHz;
     467
     468                /* Calculate the timer ticks per byte for this stream. */
     469                pStream->State.cTicksPerByte = cTicksPerHz / pStream->State.cbTransferChunk;
     470                Assert(pStream->State.cTicksPerByte);
     471
     472                /* Calculate timer ticks per transfer. */
     473                pStream->State.cTransferTicks = pStream->State.cbTransferChunk * pStream->State.cTicksPerByte;
     474                Assert(pStream->State.cTransferTicks);
     475
     476                LogFunc(("[SD%RU8] Timer %uHz (%RU64 ticks per Hz), cTicksPerByte=%RU64, cbTransferChunk=%RU32, " \
     477                         "cTransferTicks=%RU64, cbTransferSize=%RU32\n",
     478                         pStream->u8SD, pStream->State.uTimerHz, cTicksPerHz, pStream->State.cTicksPerByte,
     479                         pStream->State.cbTransferChunk, pStream->State.cTransferTicks, pStream->State.cbTransferSize));
     480
     481                /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */
     482                hdaR3StreamSetPosition(pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD));
    476483
    477484#ifdef LOG_ENABLED
    478         hdaR3BDLEDumpAll(pThis, pStream->u64BDLBase, pStream->u16LVI + 1);
     485                hdaR3BDLEDumpAll(pThis, pStream->u64BDLBase, pStream->u16LVI + 1);
    479486#endif
     487            }
     488        }
    480489    }
    481490
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