VirtualBox

Changeset 87319 in vbox


Ignore:
Timestamp:
Jan 20, 2021 10:44:22 AM (4 years ago)
Author:
vboxsync
Message:

Audio/HDA: Implemented FIFO watermark support. ticketoem2ref:36

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

Legend:

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

    r87314 r87319  
    536536
    537537
    538 
    539 
    540 /**
    541  * Retrieves the number of bytes of a FIFOW register.
    542  *
    543  * @return Number of bytes of a given FIFOW register.
    544  */
    545 DECLINLINE(uint8_t) hdaSDFIFOWToBytes(uint32_t u32RegFIFOW)
    546 {
    547     uint32_t cb;
    548     switch (u32RegFIFOW)
    549     {
    550         case HDA_SDFIFOW_8B:  cb = 8;  break;
    551         case HDA_SDFIFOW_16B: cb = 16; break;
    552         case HDA_SDFIFOW_32B: cb = 32; break;
    553         default:              cb = 0;  break;
    554     }
    555 
    556     Assert(RT_IS_POWER_OF_TWO(cb));
    557     return cb;
    558 }
    559 
    560538#ifdef IN_RING3
    561539/**
     
    15631541    }
    15641542
    1565     uint32_t u32FIFOW = 0;
     1543    uint32_t u16FIFOW = 0;
    15661544    switch (u32Value)
    15671545    {
     
    15691547        case HDA_SDFIFOW_16B:
    15701548        case HDA_SDFIFOW_32B:
    1571             u32FIFOW = u32Value;
     1549            u16FIFOW = u32Value;
    15721550            break;
    15731551        default:
    15741552            ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing unsupported FIFOW (0x%zx) to stream #%RU8, defaulting to 32 bytes\n",
    15751553                                            u32Value, idxStream));
    1576             u32FIFOW = HDA_SDFIFOW_32B;
     1554            u16FIFOW = HDA_SDFIFOW_32B;
    15771555            break;
    15781556    }
    15791557
    1580     pThis->aStreams[idxStream].u16FIFOW = hdaSDFIFOWToBytes(u32FIFOW);
    1581     LogFunc(("[SD%zu] Updating FIFOW to %u bytes\n", idxStream, pThis->aStreams[idxStream].u16FIFOW));
    1582     return hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOW);
     1558    pThis->aStreams[idxStream].u8FIFOW = hdaSDFIFOWToBytes(u16FIFOW);
     1559    LogFunc(("[SD%zu] Updating FIFOW to %RU8 bytes\n", idxStream, pThis->aStreams[idxStream].u8FIFOW));
     1560    return hdaRegWriteU16(pDevIns, pThis, iReg, u16FIFOW);
    15831561}
    15841562
  • trunk/src/VBox/Devices/Audio/DevHDACommon.cpp

    r87266 r87319  
    7979        pThis->u8IRQL = 0;
    8080    }
     81}
     82
     83/**
     84 * Retrieves the number of bytes of a FIFOW register.
     85 *
     86 * @return Number of bytes of a given FIFOW register.
     87 * @param  u16RegFIFOS         FIFOW register to convert.
     88 */
     89uint8_t hdaSDFIFOWToBytes(uint16_t u16RegFIFOW)
     90{
     91    uint32_t cb;
     92    switch (u16RegFIFOW)
     93    {
     94        case HDA_SDFIFOW_8B:  cb = 8;  break;
     95        case HDA_SDFIFOW_16B: cb = 16; break;
     96        case HDA_SDFIFOW_32B: cb = 32; break;
     97        default:
     98            AssertFailedStmt(cb = 32); /* Paranoia. */
     99            break;
     100    }
     101
     102    Assert(RT_IS_POWER_OF_TWO(cb));
     103    return cb;
    81104}
    82105
     
    334357    while (cbLeft)
    335358    {
    336         uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS);
     359        uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u8FIFOS);
    337360
    338361        rc = PDMDevHlpPhysRead(pDevIns, GCPhysChunk, (uint8_t *)pvBuf + cbReadTotal, cbChunk);
     
    409432    while (cbLeft)
    410433    {
    411         uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS);
     434        uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u8FIFOS);
    412435
    413436        /* Sanity checks. */
  • trunk/src/VBox/Devices/Audio/HDAStream.cpp

    r87267 r87319  
    242242    const uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, uSD);
    243243    const uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, uSD);
    244     const uint16_t u16FIFOS   = HDA_STREAM_REG(pThis, FIFOS, uSD) + 1;
     244    const uint8_t  u8FIFOS    = HDA_STREAM_REG(pThis, FIFOS, uSD) + 1;
     245          uint8_t  u8FIFOW    = hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, uSD));
    245246    const uint16_t u16FMT     = HDA_STREAM_REG(pThis, FMT, uSD);
    246247
     
    250251        || !u16LVI
    251252        || !u32CBL
    252         || !u16FIFOS
     253        || !u8FIFOS
     254        || !u8FIFOW
    253255        || !u16FMT)
    254256    {
     
    326328        && u16LVI     == pStreamShared->u16LVI
    327329        && u32CBL     == pStreamShared->u32CBL
    328         && u16FIFOS   == pStreamShared->u16FIFOS
     330        && u8FIFOS    == pStreamShared->u8FIFOS
     331        && u8FIFOW    == pStreamShared->u8FIFOW
    329332        && u16FMT     == pStreamShared->u16FMT)
    330333    {
     
    332335        return VINF_NO_CHANGE;
    333336    }
     337
     338    /* Make sure the guest behaves regarding the stream's FIFO. */
     339    ASSERT_GUEST_LOGREL_MSG_STMT(u8FIFOW <= u8FIFOS,
     340                                 ("Guest tried setting a bigger FIFOW (%RU8) than FIFOS (%RU8), limiting\n", u8FIFOW, u8FIFOS),
     341                                 u8FIFOW = u8FIFOS /* ASSUMES that u8FIFOS has been validated. */);
    334342
    335343    pStreamShared->u8SD       = uSD;
     
    339347    pStreamShared->u16LVI     = u16LVI;
    340348    pStreamShared->u32CBL     = u32CBL;
    341     pStreamShared->u16FIFOS   = u16FIFOS;
     349    pStreamShared->u8FIFOS    = u8FIFOS;
     350    pStreamShared->u8FIFOW    = u8FIFOW;
    342351    pStreamShared->u16FMT     = u16FMT;
    343352
     
    387396        pCfg->Device.cMsSchedulingHint = 1000 /* ms */ / pStreamShared->State.uTimerHz;
    388397
    389     LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n",
    390              uSD, pStreamShared->u64BDLBase, pStreamShared->u32CBL, pStreamShared->u16LVI, pStreamShared->u16FIFOS));
     398    LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU8\n",
     399             uSD, pStreamShared->u64BDLBase, pStreamShared->u32CBL, pStreamShared->u16LVI, pStreamShared->u8FIFOS));
    391400
    392401    if (RT_SUCCESS(rc))
     
    987996    Assert(pStreamShared->u64BDLBase);
    988997    Assert(pStreamShared->u32CBL);
    989     Assert(pStreamShared->u16FIFOS);
     998    Assert(pStreamShared->u8FIFOS);
    990999
    9911000    /* State sanity checks. */
     
    10211030    {
    10221031        /* Limit the chunk to the stream's FIFO size and what's left to process. */
    1023         uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS);
     1032        uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u8FIFOS);
    10241033
    10251034        /* Limit the chunk to the remaining data of the current BDLE. */
     
    12381247        if (cbDMA)
    12391248        {
     1249            const size_t cbCircBufUsed = RTCircBufUsed(pCircBuf);
     1250
     1251            Log3Func(("[SD%RU8] cbDMA=%RU32, cbUsed=%zu, uFIFOW=%RU8, uFIFOS=%RU8\n",
     1252                      uSD, cbDMA, cbCircBufUsed, pStreamShared->u8FIFOW, pStreamShared->u8FIFOS));
     1253
    12401254            /* We always increment the position of DMA buffer counter because we're always reading
    12411255             * into an intermediate DMA buffer. */
     
    12531267            }
    12541268
    1255             /*
    1256              * Update the stream's current position.
    1257              * Do this as accurate and close to the actual data transfer as possible.
    1258              * All guetsts rely on this, depending on the mechanism they use (LPIB register or DMA counters).
    1259              */
    1260             uint32_t cbStreamPos = hdaR3StreamGetPosition(pThis, pStreamShared);
    1261             if (cbStreamPos == pStreamShared->u32CBL)
    1262                 cbStreamPos = 0;
    1263 
    1264             hdaR3StreamSetPosition(pStreamShared, pDevIns, pThis, cbStreamPos + cbDMA);
     1269            /* Only set the new DMA position if we at least reached the stream's FIFO watermark.
     1270             * This by default is 32 bytes. */
     1271            if (cbCircBufUsed >= pStreamShared->u8FIFOW)
     1272            {
     1273                /*
     1274                 * Update the stream's current position.
     1275                 * Do this as accurate and close to the actual data transfer as possible.
     1276                 * All guetsts rely on this, depending on the mechanism they use (LPIB register or DMA counters).
     1277                 */
     1278                uint32_t cbStreamPos = hdaR3StreamGetPosition(pThis, pStreamShared);
     1279                if (cbStreamPos == pStreamShared->u32CBL)
     1280                    cbStreamPos = 0;
     1281
     1282                hdaR3StreamSetPosition(pStreamShared, pDevIns, pThis, cbStreamPos + cbDMA);
     1283            }
    12651284        }
    12661285
  • trunk/src/VBox/Devices/Audio/HDAStream.h

    r87267 r87319  
    203203     *  Will be updated in hdaR3StreamInit(). */
    204204    uint16_t                    u16FMT;
    205     /** FIFO Size (FIFOS).
     205    /** FIFO Size (checked + translated in bytes, FIFOS).
    206206     *  Maximum number of bytes that may have been DMA'd into
    207207     *  memory but not yet transmitted on the link.
    208208     *
    209209     *  Will be updated in hdaR3StreamInit(). */
    210     uint16_t                    u16FIFOS;
    211     /** FIFO Watermark. */
    212     uint16_t                    u16FIFOW;
     210    uint8_t                     u8FIFOS;
     211    /** FIFO Watermark (checked + translated in bytes, FIFOW). */
     212    uint8_t                     u8FIFOW;
     213    uint8_t                     abPadding1[2];
    213214    /** FIFO scratch buffer, to avoid intermediate (re-)allocations. */
    214215    uint8_t                     abFIFO[HDA_FIFO_MAX + 1];
     
    216217     *  Will be updated in hdaR3StreamInit(). */
    217218    uint16_t                    u16LVI;
    218     uint16_t                    au16Padding1[2];
    219219    /** The timer for pumping data thru the attached LUN drivers. */
    220220    TMTIMERHANDLE               hTimer;
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