VirtualBox

Changeset 64800 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 7, 2016 10:20:50 AM (8 years ago)
Author:
vboxsync
Message:

Audio/DevHDA.cpp: Added HDABDLEDESC to fetch BDL descriptions in hdaBDLEFetch().

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

Legend:

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

    r64792 r64800  
    547547#define HDA_RMX_SD7BDPU             (HDA_STREAM_RMX_DEF(BDPU, 0) + 70)
    548548
     549#define HDA_BDLE_FLAG_IOC           RT_BIT(0) /* Interrupt on completion (IOC). */
     550
    549551#define HDA_CODEC_CAD_SHIFT         28
    550552/* Encodes the (required) LUN into a codec command. */
     
    575577
    576578/**
    577  * Buffer Descriptor List Entry (BDLE) (3.6.3).
    578  *
    579  * Contains only register values which do *not* change until a
    580  * stream reset occurs.
    581  */
    582 typedef struct HDABDLE
     579 * BDL description structure.
     580 * Do not touch this, as this must match to the HDA specs.
     581 */
     582typedef struct HDABDLEDESC
    583583{
    584584    /** Starting address of the actual buffer. Must be 128-bit aligned. */
     
    586586    /** Size of the actual buffer (in bytes). */
    587587    uint32_t     u32BufSize;
    588     /** Interrupt on completion; the controller will generate
     588    /** Bit 0: Interrupt on completion; the controller will generate
    589589     *  an interrupt when the last byte of the buffer has been
    590      *  fetched by the DMA engine. */
    591     bool         fIntOnCompletion;
     590     *  fetched by the DMA engine.
     591     *
     592     *  Rest is reserved for further use and must be 0. */
     593    uint32_t     fFlags;
     594} HDABDLEDESC, *PHDABDLEDESC;
     595AssertCompileSize(HDABDLEDESC, 16); /* Always 16 byte. Also must be aligned on 128-byte boundary. */
     596
     597/**
     598 * Buffer Descriptor List Entry (BDLE) (3.6.3).
     599 */
     600typedef struct HDABDLE
     601{
     602    /** The actual BDL description. */
     603    HDABDLEDESC  Desc;
    592604    /** Internal state of this BDLE.
    593605     *  Not part of the actual BDLE registers. */
     
    11411153
    11421154#ifdef IN_RING3
    1143 /** HDABDLE field descriptors for the v6+ saved state. */
    1144 static SSMFIELD const g_aSSMBDLEFields6[] =
    1145 {
    1146     SSMFIELD_ENTRY(HDABDLE, u64BufAdr),
    1147     SSMFIELD_ENTRY(HDABDLE, u32BufSize),
    1148     SSMFIELD_ENTRY(HDABDLE, fIntOnCompletion),
     1155/** HDABDLEDESC field descriptors for the v6+ saved state. */
     1156static SSMFIELD const g_aSSMBDLEDescFields6[] =
     1157{
     1158    SSMFIELD_ENTRY(HDABDLEDESC, u64BufAdr),
     1159    SSMFIELD_ENTRY(HDABDLEDESC, u32BufSize),
     1160    SSMFIELD_ENTRY(HDABDLEDESC, fFlags),
    11491161    SSMFIELD_ENTRY_TERM()
    11501162};
     
    12551267    bool     fWrapAround = false;
    12561268
    1257     AssertMsg(pBDLE->State.u32BufOff == pBDLE->u32BufSize, ("BDLE not finished yet: %R[bdle]\n", pBDLE));
     1269    AssertMsg(pBDLE->State.u32BufOff == pBDLE->Desc.u32BufSize, ("BDLE not finished yet: %R[bdle]\n", pBDLE));
    12581270
    12591271    /*
     
    31393151    /** @todo Compare u16Entry with LVI. */
    31403152
    3141     uint8_t uBundleEntry[16]; /** @todo Define a BDLE length. */
    3142     int rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + u16Entry * 16, /** @todo Define a BDLE length. */
    3143                                uBundleEntry, RT_ELEMENTS(uBundleEntry));
     3153    int rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + u16Entry * sizeof(HDABDLEDESC),
     3154                               &pBDLE->Desc, sizeof(pBDLE->Desc));
    31443155    if (RT_FAILURE(rc))
    31453156        return rc;
    31463157
    3147     RT_BZERO(pBDLE, sizeof(HDABDLE));
     3158    /* Clear internal state. */
     3159    RT_BZERO(&pBDLE->State, sizeof(HDABDLESTATE));
    31483160
    31493161    pBDLE->State.u32BDLIndex = u16Entry;
    3150     pBDLE->u64BufAdr         = *(uint64_t *) uBundleEntry;
    3151     pBDLE->u32BufSize        = *(uint32_t *)&uBundleEntry[8];
    3152     if (pBDLE->u32BufSize < sizeof(uint16_t)) /* Must be at least one word. */
    3153         return VERR_INVALID_STATE;
    3154 
    3155     pBDLE->fIntOnCompletion  = (*(uint32_t *)&uBundleEntry[12]) & RT_BIT(0);
    31563162
    31573163    return VINF_SUCCESS;
     
    31793185
    31803186    /* Limit to the available free space of the current BDLE. */
    3181     cbData = RT_MIN(cbData, pBDLE->u32BufSize - pBDLE->State.u32BufOff);
    3182     AssertMsg(cbData, ("No BDLE space left (%RU32/%RU32): %R[bdle]\n", pBDLE->State.u32BufOff, pBDLE->u32BufSize, pBDLE));
     3187    cbData = RT_MIN(cbData, pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff);
     3188    AssertMsg(cbData, ("No BDLE space left (%RU32/%RU32): %R[bdle]\n", pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize, pBDLE));
    31833189
    31843190    /* Make sure we only transfer as many bytes as requested. */
     
    32133219        return;
    32143220
    3215     Assert(pBDLE->u32BufSize >= cbProcessed);
     3221    Assert(pBDLE->Desc.u32BufSize >= cbProcessed);
    32163222
    32173223    /* Fewer than cbBelowFIFOW bytes were copied.
     
    32273233    {
    32283234        LogFlowFunc(("BDLE(cbUnderFifoW:%RU32, off:%RU32, size:%RU32)\n",
    3229                      pBDLE->State.cbBelowFIFOW, pBDLE->State.u32BufOff, pBDLE->u32BufSize));
     3235                     pBDLE->State.cbBelowFIFOW, pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize));
    32303236    }
    32313237#endif
     
    32363242    /* We always increment the position of DMA buffer counter because we're always reading
    32373243     * into an intermediate buffer. */
    3238     Assert(pBDLE->u32BufSize >= (pBDLE->State.u32BufOff + cbProcessed));
     3244    Assert(pBDLE->Desc.u32BufSize >= (pBDLE->State.u32BufOff + cbProcessed));
    32393245    pBDLE->State.u32BufOff += cbProcessed;
    32403246
     
    33653371     * the CBL limit or our internal DMA buffer is full. */
    33663372    bool fNeedsNextBDLE   = (   fCBLLimitReached
    3367                              || (pBDLE->State.u32BufOff >= pBDLE->u32BufSize));
     3373                             || (pBDLE->State.u32BufOff >= pBDLE->Desc.u32BufSize));
    33683374
    33693375    Assert(u32LPIB                <= pStream->u32CBL);
    3370     Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize);
     3376    Assert(pBDLE->State.u32BufOff <= pBDLE->Desc.u32BufSize);
    33713377
    33723378    LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, fCBLLimitReached=%RTbool, fNeedsNextBDLE=%RTbool, %R[bdle]\n",
     
    34093415
    34103416    /* Check if the current BDLE entry is complete (full). */
    3411     if (pBDLE->State.u32BufOff >= pBDLE->u32BufSize)
    3412     {
    3413         Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize);
     3417    if (pBDLE->State.u32BufOff >= pBDLE->Desc.u32BufSize)
     3418    {
     3419        Assert(pBDLE->State.u32BufOff <= pBDLE->Desc.u32BufSize);
    34143420
    34153421        if (/* IOC (Interrupt On Completion) bit set? */
    3416                pBDLE->fIntOnCompletion
     3422               pBDLE->Desc.fFlags & HDA_BDLE_FLAG_IOC
    34173423            /* All data put into the DMA FIFO? */
    34183424            && pBDLE->State.cbBelowFIFOW == 0
     
    34733479        Assert(cbRead <= cbToRead);
    34743480        Assert(cbRead <= sizeof(pBDLE->State.au8FIFO));
    3475         Assert(cbRead <= pBDLE->u32BufSize - pBDLE->State.u32BufOff);
     3481        Assert(cbRead <= pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff);
    34763482
    34773483        /*
     
    34793485         */
    34803486        rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),
    3481                                    pBDLE->u64BufAdr + pBDLE->State.u32BufOff,
     3487                                   pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff,
    34823488                                   pBDLE->State.au8FIFO, cbRead);
    34833489        AssertRC(rc);
     
    34923498        if (pBDLE->State.cbBelowFIFOW + cbRead > hdaStreamGetFIFOW(pThis, pStream))
    34933499        {
    3494             Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize);
     3500            Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->Desc.u32BufSize);
    34953501            pBDLE->State.u32BufOff    += cbRead;
    34963502            pBDLE->State.cbBelowFIFOW  = 0;
     
    34993505        else
    35003506        {
    3501             Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize);
     3507            Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->Desc.u32BufSize);
    35023508            pBDLE->State.u32BufOff    += cbRead;
    35033509            pBDLE->State.cbBelowFIFOW += cbRead;
     
    35513557         */
    35523558        rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),
    3553                                pBDLE->u64BufAdr + pBDLE->State.u32BufOff,
     3559                               pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff,
    35543560                               pvBuf, cbBuf);
    35553561        AssertRC(rc);
     
    36493655            AssertFailed();
    36503656
    3651             Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE->u32BufSize);
     3657            Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE->Desc.u32BufSize);
    36523658            pBDLE->State.u32BufOff    += cbWritten;
    36533659            pBDLE->State.cbBelowFIFOW += cbWritten;
     
    43164322            {
    43174323                PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),
    4318                                   pBDLE->u64BufAdr + pBDLE->State.u32BufOff,
     4324                                  pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff,
    43194325                                  (uint8_t *)pvBuf + cbTotal, cbChunk);
    43204326            }
     
    43224328            {
    43234329                PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns),
    4324                                    pBDLE->u64BufAdr + pBDLE->State.u32BufOff,
     4330                                   pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff,
    43254331                                   (uint8_t *)pvBuf + cbTotal, cbChunk);
    43264332            }
     
    43404346
    43414347        LogFunc(("DMA: Entry %RU32 Pos %RU32/%RU32 Chunk %RU32\n",
    4342                  pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->u32BufSize, cbChunk));
     4348                 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize, cbChunk));
    43434349
    43444350        Assert(cbLeft >= cbChunkProcessed);
     
    48504856
    48514857    rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE),
    4852                           0 /*fFlags*/, g_aSSMBDLEFields6, NULL);
     4858                          0 /*fFlags*/, g_aSSMBDLEDescFields6, NULL);
    48534859    AssertRCReturn(rc, rc);
    48544860
     
    48674873        AssertRC(rc);
    48684874
    4869         Assert(curBDLE.u32BufSize       == pBDLE->u32BufSize);
    4870         Assert(curBDLE.u64BufAdr        == pBDLE->u64BufAdr);
    4871         Assert(curBDLE.fIntOnCompletion == pBDLE->fIntOnCompletion);
     4875        Assert(curBDLE.Desc.u32BufSize == pBDLE->Desc.u32BufSize);
     4876        Assert(curBDLE.Desc.u64BufAdr  == pBDLE->Desc.u64BufAdr);
     4877        Assert(curBDLE.Desc.fFlags     == pBDLE->Desc.fFlags);
    48724878    }
    48734879    else
    48744880    {
    4875         Assert(pBDLE->u64BufAdr  == 0);
    4876         Assert(pBDLE->u32BufSize == 0);
     4881        Assert(pBDLE->Desc.u64BufAdr  == 0);
     4882        Assert(pBDLE->Desc.u32BufSize == 0);
    48774883    }
    48784884#endif
     
    49884994     *       according to the spec).
    49894995     */
    4990 #define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x)                            \
    4991     rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* Begin marker */   \
    4992     AssertRCReturn(rc, rc);                                             \
    4993     rc = SSMR3GetU64(pSSM, &x.u64BufAdr);          /* u64BdleCviAddr */ \
    4994     AssertRCReturn(rc, rc);                                             \
    4995     rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* u32BdleMaxCvi */  \
    4996     AssertRCReturn(rc, rc);                                             \
    4997     rc = SSMR3GetU32(pSSM, &x.State.u32BDLIndex);  /* u32BdleCvi */     \
    4998     AssertRCReturn(rc, rc);                                             \
    4999     rc = SSMR3GetU32(pSSM, &x.u32BufSize);         /* u32BdleCviLen */  \
    5000     AssertRCReturn(rc, rc);                                             \
    5001     rc = SSMR3GetU32(pSSM, &x.State.u32BufOff);    /* u32BdleCviPos */  \
    5002     AssertRCReturn(rc, rc);                                             \
    5003     rc = SSMR3GetBool(pSSM, &x.fIntOnCompletion);  /* fBdleCviIoc */    \
    5004     AssertRCReturn(rc, rc);                                             \
    5005     rc = SSMR3GetU32(pSSM, &x.State.cbBelowFIFOW); /* cbUnderFifoW */   \
    5006     AssertRCReturn(rc, rc);                                             \
    5007     rc = SSMR3Skip(pSSM, sizeof(uint8_t) * 256);   /* FIFO */           \
    5008     AssertRCReturn(rc, rc);                                             \
    5009     rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* End marker */     \
    5010     AssertRCReturn(rc, rc);                                             \
     4996#define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x)                                \
     4997    {                                                                       \
     4998        rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* Begin marker */   \
     4999        AssertRCReturn(rc, rc);                                             \
     5000        rc = SSMR3GetU64(pSSM, &x.Desc.u64BufAdr);     /* u64BdleCviAddr */ \
     5001        AssertRCReturn(rc, rc);                                             \
     5002        rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* u32BdleMaxCvi */  \
     5003        AssertRCReturn(rc, rc);                                             \
     5004        rc = SSMR3GetU32(pSSM, &x.State.u32BDLIndex);  /* u32BdleCvi */     \
     5005        AssertRCReturn(rc, rc);                                             \
     5006        rc = SSMR3GetU32(pSSM, &x.Desc.u32BufSize);    /* u32BdleCviLen */  \
     5007        AssertRCReturn(rc, rc);                                             \
     5008        rc = SSMR3GetU32(pSSM, &x.State.u32BufOff);    /* u32BdleCviPos */  \
     5009        AssertRCReturn(rc, rc);                                             \
     5010        bool fIOC;                                                          \
     5011        rc = SSMR3GetBool(pSSM, &fIOC);                /* fBdleCviIoc */    \
     5012        AssertRCReturn(rc, rc);                                             \
     5013        x.Desc.fFlags = fIOC ? HDA_BDLE_FLAG_IOC : 0;                       \
     5014        rc = SSMR3GetU32(pSSM, &x.State.cbBelowFIFOW); /* cbUnderFifoW */   \
     5015        AssertRCReturn(rc, rc);                                             \
     5016        rc = SSMR3Skip(pSSM, sizeof(uint8_t) * 256);   /* FIFO */           \
     5017        AssertRCReturn(rc, rc);                                             \
     5018        rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* End marker */     \
     5019        AssertRCReturn(rc, rc);                                             \
     5020    }                                                                       \
    50115021
    50125022    /*
     
    51415151
    51425152                    rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE),
    5143                                           0 /* fFlags */, g_aSSMBDLEFields6, NULL);
     5153                                          0 /* fFlags */, g_aSSMBDLEDescFields6, NULL);
    51445154                    if (RT_FAILURE(rc))
    51455155                        break;
     
    52135223    return RTStrFormat(pfnOutput,  pvArgOutput, NULL, 0,
    52145224                       "BDLE(idx:%RU32, off:%RU32, fifow:%RU32, IOC:%RTbool, DMA[%RU32 bytes @ 0x%x])",
    5215                        pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->State.cbBelowFIFOW,  pBDLE->fIntOnCompletion,
    5216                        pBDLE->u32BufSize, pBDLE->u64BufAdr);
     5225                       pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->State.cbBelowFIFOW,
     5226                       pBDLE->Desc.fFlags & HDA_BDLE_FLAG_IOC, pBDLE->Desc.u32BufSize, pBDLE->Desc.u64BufAdr);
    52175227}
    52185228
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r64761 r64800  
    18441844    GEN_CHECK_OFF(HDABDLESTATE, u32BufOff);
    18451845
     1846    GEN_CHECK_SIZE(HDABDLEDESC);
     1847    GEN_CHECK_OFF(HDABDLEDESC, u64BufAdr);
     1848    GEN_CHECK_OFF(HDABDLEDESC, u32BufSize);
     1849    GEN_CHECK_OFF(HDABDLEDESC, fFlags);
     1850
    18461851    GEN_CHECK_SIZE(HDABDLE);
    1847     GEN_CHECK_OFF(HDABDLE, u64BufAdr);
    1848     GEN_CHECK_OFF(HDABDLE, u32BufSize);
    1849     GEN_CHECK_OFF(HDABDLE, fIntOnCompletion);
     1852    GEN_CHECK_OFF(HDABDLE, Desc);
    18501853    GEN_CHECK_OFF(HDABDLE, State);
    18511854
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