VirtualBox

Changeset 34146 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Nov 17, 2010 8:41:56 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67866
Message:

Audio/HDA: hda{Read,Write}Audio respects SDnFIFO{S,W} registers.

File:
1 edited

Legend:

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

    r34062 r34146  
    301301#define ICH6_HDA_REG_SD7FIFOW   (HDA_STREAM_REG_DEF(FIFOW, 0) + 70) /* 0x16E */
    302302
     303/*
     304 * ICH6 datasheet defined limits for FIFOW values (18.2.38)
     305 */
     306#define HDA_SDFIFOW_8B       (0x2)
     307#define HDA_SDFIFOW_16B      (0x3)
     308#define HDA_SDFIFOW_32B      (0x4)
     309#define SDFIFOW(pState, num) HDA_REG((pState), SD(FIFOW, num))
     310
    303311#define ICH6_HDA_REG_SD0FIFOS   38 /* 0x90 */
    304312#define ICH6_HDA_REG_SD1FIFOS   (HDA_STREAM_REG_DEF(FIFOS, 0) + 10) /* 0xB0 */
     
    376384    uint32_t    u32BdleCviPos;
    377385    bool        fBdleCviIoc;
     386    uint32_t    cbUnderFifoW;
     387    uint8_t     au8HdaBuffer[HDA_SDONFIFO_256B + 1];
    378388} HDABDLEDESC, *PHDABDLEDESC;
    379389
     
    430440} PCIINTELHDLinkState;
    431441
     442
    432443DECLCALLBACK(int)hdaRegReadUnimplemented(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value);
    433444DECLCALLBACK(int)hdaRegWriteUnimplemented(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value);
     
    452463DECLCALLBACK(int)hdaRegWriteSDSTS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
    453464DECLCALLBACK(int)hdaRegWriteSDLVI(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
     465DECLCALLBACK(int)hdaRegWriteSDFIFOW(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
    454466DECLCALLBACK(int)hdaRegWriteSDFIFOS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
    455467DECLCALLBACK(int)hdaRegWriteSDBDPL(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
     
    530542    { 0x00088, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "ISD0CBL"  , "ISD0 Cyclic Buffer Length" },
    531543    { 0x0008C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "ISD0LVI"  , "ISD0 Last Valid Index" },
    532     { 0x0008E, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "ISD0FIFOW", "ISD0 FIFO Watermark" },
     544    { 0x0008E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "ISD0FIFOW", "ISD0 FIFO Watermark" },
    533545    { 0x00090, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16          , hdaRegWriteU16          , "ISD0FIFOS", "ISD0 FIFO Size" },
    534546    { 0x00092, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "ISD0FMT"  , "ISD0 Format" },
     
    541553    { 0x000A8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "ISD1CBL"  , "ISD1 Cyclic Buffer Length" },
    542554    { 0x000AC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "ISD1LVI"  , "ISD1 Last Valid Index" },
    543     { 0x000AE, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "ISD1FIFOW", "ISD1 FIFO Watermark" },
     555    { 0x000AE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "ISD1FIFOW", "ISD1 FIFO Watermark" },
    544556    { 0x000B0, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16          , hdaRegWriteU16          , "ISD1FIFOS", "ISD1 FIFO Size" },
    545557    { 0x000B2, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "ISD1FMT"  , "ISD1 Format" },
     
    552564    { 0x000C8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "ISD2CBL"  , "ISD2 Cyclic Buffer Length" },
    553565    { 0x000CC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "ISD2LVI"  , "ISD2 Last Valid Index" },
    554     { 0x000CE, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "ISD2FIFOW", "ISD2 FIFO Watermark" },
     566    { 0x000CE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "ISD2FIFOW", "ISD2 FIFO Watermark" },
    555567    { 0x000D0, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16          , hdaRegWriteU16          , "ISD2FIFOS", "ISD2 FIFO Size" },
    556568    { 0x000D2, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "ISD2FMT"  , "ISD2 Format" },
     
    574586    { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "OSD0CBL"  , "OSD0 Cyclic Buffer Length" },
    575587    { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "OSD0LVI"  , "OSD0 Last Valid Index" },
    576     { 0x0010E, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "OSD0FIFOW", "OSD0 FIFO Watermark" },
     588    { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "OSD0FIFOW", "OSD0 FIFO Watermark" },
    577589    { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS      , "OSD0FIFOS", "OSD0 FIFO Size" },
    578590    { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "OSD0FMT"  , "OSD0 Format" },
     
    585597    { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "OSD1CBL"  , "OSD1 Cyclic Buffer Length" },
    586598    { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "OSD1LVI"  , "OSD1 Last Valid Index" },
    587     { 0x0012E, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "OSD1FIFOW", "OSD1 FIFO Watermark" },
     599    { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "OSD1FIFOW", "OSD1 FIFO Watermark" },
    588600    { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS      , "OSD1FIFOS", "OSD1 FIFO Size" },
    589601    { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "OSD1FMT"  , "OSD1 Format" },
     
    596608    { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "OSD2CBL"  , "OSD2 Cyclic Buffer Length" },
    597609    { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "OSD2LVI"  , "OSD2 Last Valid Index" },
    598     { 0x0014E, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "OSD2FIFOW", "OSD2 FIFO Watermark" },
     610    { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "OSD2FIFOW", "OSD2 FIFO Watermark" },
    599611    { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS      , "OSD2FIFOS", "OSD2 FIFO Size" },
    600612    { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "OSD2FMT"  , "OSD2 Format" },
     
    607619    { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32          , "OSD3CBL"  , "OSD3 Cyclic Buffer Length" },
    608620    { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI        , "OSD3LVI"  , "OSD3 Last Valid Index" },
    609     { 0x0016E, 0x00002, 0x00000005, 0x00000005, hdaRegReadU16          , hdaRegWriteU16          , "OSD3FIFOW", "OSD3 FIFO Watermark" },
     621    { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW      , "OSD3FIFOW", "OSD3 FIFO Watermark" },
    610622    { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS      , "OSD3FIFOS", "OSD3 FIFO Size" },
    611623    { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteU16          , "OSD3FMT"  , "OSD3 Format" },
     
    613625    { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU       , "OSD3BDPU" , "OSD3 Buffer Descriptor List Pointer-Upper Base Address" },
    614626};
     627
     628static uint32_t inline hdaFifoWToSz(INTELHDLinkState *pState, int iNum)
     629{
     630    switch (ICH6_HDA_REG_SD0FIFOW + 10*iNum)
     631    {
     632        case ICH6_HDA_REG_SD0FIFOW:
     633        case ICH6_HDA_REG_SD1FIFOW:
     634        case ICH6_HDA_REG_SD2FIFOW:
     635        case ICH6_HDA_REG_SD3FIFOW:
     636        case ICH6_HDA_REG_SD4FIFOW:
     637        case ICH6_HDA_REG_SD5FIFOW:
     638        case ICH6_HDA_REG_SD6FIFOW:
     639        case ICH6_HDA_REG_SD7FIFOW:
     640            switch(HDA_REG_IND(pState, ICH6_HDA_REG_SD0FIFOW + 10*iNum))
     641            {
     642                case HDA_SDFIFOW_8B: return 8;
     643                case HDA_SDFIFOW_16B: return 16;
     644                case HDA_SDFIFOW_32B: return 32;
     645                default:
     646                    AssertMsgFailed(("hda: unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pState, iNum), iNum));
     647            }
     648        default:
     649            AssertMsgFailed(("hda: Not SDnFIFOW register"));
     650            return 0;
     651    }
     652}
    615653
    616654static int hdaProcessInterrupt(INTELHDLinkState* pState)
     
    10051043        if (offset == 0x100)
    10061044        {
    1007             uint64_t u64BaseDMA = SDBDPL(pState, 4);
    1008             u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32);
     1045            uint64_t u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4));
    10091046            if (u64BaseDMA)
    10101047                AUD_set_active_out(OSD0FMT_TO_AUDIO_SELECTOR(pState), 1);
     
    10561093}
    10571094
     1095DECLCALLBACK(int)hdaRegWriteSDFIFOW(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
     1096{
     1097    switch (u32Value)
     1098    {
     1099        case HDA_SDFIFOW_8B:
     1100        case HDA_SDFIFOW_16B:
     1101        case HDA_SDFIFOW_32B:
     1102            return hdaRegWriteU16(pState, offset, index, u32Value);
     1103        default:
     1104            Log(("hda: Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value));
     1105            return hdaRegWriteU16(pState, offset, index, HDA_SDFIFOW_32B);
     1106    }
     1107    return VINF_SUCCESS;
     1108}
    10581109/*
    10591110 * Note this method could be called for changing value on Output Streams only (ICH6 datacheet 18.2.39)
     
    12421293        len = *(uint32_t *)&bdle[8];
    12431294        ioc = *(uint32_t *)&bdle[12];
    1244         Log(("hda: %s bdle[%d] a:%lx, len:%x, ioc:%d\n",  (i == pBdle->u32BdleCvi? "[C]": "   "), i, addr, len, ioc));
     1295        Log(("hda: %s bdle[%d] a:%lx, len:%d, ioc:%d\n",  (i == pBdle->u32BdleCvi? "[C]": "   "), i, addr, len, ioc & 0x1));
    12451296        sum += len;
    12461297    }
     
    12641315}
    12651316
    1266 static uint32_t hdaReadAudio(INTELHDLinkState *pState, int avail, bool *fStop)
    1267 {
    1268     uint8_t tmpbuf[256];
    1269     uint32_t temp;
    1270     uint32_t u32Rest = 0;
    1271     uint32_t cbRead = 0;
    1272     uint32_t to_copy = 0;
    1273     /* todo: add input line detection */
     1317static uint32_t hdaReadAudio(INTELHDLinkState *pState, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit)
     1318{
    12741319    PHDABDLEDESC pBdle = &pState->stInBdle;
    1275     SWVoiceIn *voice = ISD0FMT_TO_AUDIO_SELECTOR(pState);
    1276     u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
    1277     temp = audio_MIN(u32Rest, (uint32_t)avail);
    1278     if (!temp)
    1279     {
    1280         *fStop = true;
    1281         return cbRead;
    1282     }
    1283     while (temp)
    1284     {
    1285         int copied;
    1286         to_copy = audio_MIN(temp, SDFIFOS(pState, 4) + 1);
    1287         copied = AUD_read (voice, tmpbuf, to_copy);
    1288         Log (("hda: read_audio max=%x to_copy=%x copied=%x\n",
    1289               avail, to_copy, copied));
    1290         if (!copied)
    1291         {
     1320    uint32_t cbTransfered = 0;
     1321    while(   *pu32Avail
     1322          && pBdle->u32BdleCviPos < pBdle->u32BdleCviLen)
     1323    {
     1324        uint32_t cb2Copy = 0;
     1325        uint32_t cbBackendCopy = 0;
     1326        bool fUnderFifoCleared = false;
     1327        if (   !pBdle->u32BdleCviLen
     1328            || (*pu32Avail < hdaFifoWToSz(pState, 0)))
     1329        {
     1330            *fStop = true;
     1331            return 0;
     1332        }
     1333        Log(("hda:ra: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1334        Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */
     1335        cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
     1336        cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 0) + 1 - pBdle->cbUnderFifoW); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */
     1337        Assert((*pu32Avail > 0));
     1338        cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* sanity check to avoid overriding sound backend buffer */
     1339        cb2Copy = RT_MIN(cb2Copy, u32CblLimit);
     1340        if (   !cb2Copy
     1341            || cb2Copy < pBdle->cbUnderFifoW)
     1342        {
     1343            *fStop = true;
     1344            return 0;
     1345        }
     1346
     1347        /*
     1348         * read from backend input line
     1349         */
     1350        cbBackendCopy = AUD_read (ISD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy);
     1351        /*
     1352         * write on the HDA DMA
     1353         */
     1354        PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer, cbBackendCopy);
     1355
     1356        Assert((cbBackendCopy == cb2Copy && (*pu32Avail) >= cb2Copy)); /* sanity */
     1357        *pu32Avail -= cb2Copy;
     1358        pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy);
     1359        if (pBdle->cbUnderFifoW + cbBackendCopy > hdaFifoWToSz(pState, 0))
     1360        {
     1361            Log(("hda:ra: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1362            cbTransfered += cbBackendCopy + pBdle->cbUnderFifoW;
     1363            pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy);
     1364            Assert(!pBdle->cbUnderFifoW); /* we assume, we've read Under FIFO W fully */
     1365        }
     1366        else
     1367        {
     1368            Log(("hda:ra: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1369            pBdle->cbUnderFifoW += RT_MIN(cbBackendCopy, cb2Copy);
     1370            Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 0)));
    12921371            *fStop = true;
    12931372            break;
    12941373        }
    1295         PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, copied);
    1296         temp    -= copied;
    1297         cbRead += copied;
    1298         pBdle->u32BdleCviPos += copied;
    1299     }
    1300     return cbRead;
    1301 }
    1302 static uint32_t hdaWriteAudio(INTELHDLinkState *pState, int avail, bool *fStop)
    1303 {
    1304     uint8_t tmpbuf[256];
    1305     uint32_t temp;
    1306     uint32_t u32Rest;
    1307     uint32_t written = 0;
    1308     int to_copy = 0;
     1374        Log(("hda:ra: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1375        if (   cbTransfered == (SDFIFOS(pState, 0) + 1)
     1376            || pBdle->u32BdleCviLen == pBdle->u32BdleCviPos)
     1377            break;
     1378    }
     1379    Assert((cbTransfered <= (SDFIFOS(pState, 0) + 1)));
     1380    Log(("hda:ra: cbTransfered: %d\n", cbTransfered));
     1381    return cbTransfered;
     1382}
     1383
     1384static uint32_t hdaWriteAudio(INTELHDLinkState *pState, uint32_t *pu32Avail, bool *fStop, uint32_t u32LcblLimit)
     1385{
    13091386    PHDABDLEDESC pBdle = &pState->stOutBdle;
    1310     u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
    1311     temp = audio_MIN(u32Rest, (uint32_t)avail);
    1312     if (!temp)
    1313     {
    1314         *fStop = true;
    1315         return written;
    1316     }
    1317     while (temp)
    1318     {
    1319         int copied;
    1320         to_copy = audio_MIN(SDFIFOS(pState, 4) + 1, temp);
    1321         PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, to_copy);
    1322         copied = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), tmpbuf, to_copy);
    1323         Log(("hda: write_audio max=%x to_copy=%x copied=%x\n",
    1324              avail, to_copy, copied));
    1325         if (!copied)
    1326         {
     1387    uint32_t cbTransfered = 0;
     1388    /*
     1389     * We're coping data from DMA using chuks of size FIFOS(pState, 4) + 1
     1390     */
     1391    while(   *pu32Avail
     1392          && pBdle->u32BdleCviPos < pBdle->u32BdleCviLen)
     1393    {
     1394        uint32_t cb2Copy = 0; /* local byte counter (on local buffer) */
     1395        uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */
     1396        Log(("hda:wa: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1397        /* border check assert */
     1398        if (   (   !pBdle->u32BdleCviLen
     1399                && (pBdle->cbUnderFifoW < hdaFifoWToSz(pState, 4)))
     1400            ||  *pu32Avail < hdaFifoWToSz(pState, 4))
     1401        {
     1402            /* buffer length is 0, to little data on marked as "under FIFOW" to send to backed.*/
     1403            Log(("hda:wa: exits CVI(iAvail:%d, cbUnderFifoW:%d, len:%d)\n", *pu32Avail, pBdle->u32BdleCviLen, pBdle->cbUnderFifoW));
    13271404            *fStop = true;
     1405            return 0;
     1406        }
     1407        /*
     1408         * Amounts of bytes depends on current position in buffer (u32BdleCviLen-u32BdleCviPos)
     1409         */
     1410        if (pBdle->u32BdleCviLen)
     1411        {
     1412            Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */
     1413            cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
     1414            cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 4) + 1 - pBdle->cbUnderFifoW); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */
     1415            cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* sanity check to avoid overriding sound backend buffer */
     1416            cb2Copy = RT_MIN(cb2Copy, u32LcblLimit); /* avoid LCBL overrun */
     1417        }
     1418        if (   cb2Copy == 0
     1419            && pBdle->cbUnderFifoW < hdaFifoWToSz(pState, 4))
     1420        {
     1421            Log(("hda:wa: amount of bytes to copy is zero and (cbUnderFifoW:%d < %d)\n", pBdle->cbUnderFifoW, hdaFifoWToSz(pState, 4)));
     1422            *fStop = true;
     1423            return 0;
     1424        }
     1425       
     1426        /*
     1427         * Copy from DMA to the corresponding hdaBuffer (if there exists some bytes from the previous not reported transfer we write to ''pBdle->cbUnderFifoW'' offset)
     1428         */
     1429        if (cb2Copy)
     1430            PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy);
     1431        /*
     1432         * Write to audio backend.
     1433         */
     1434        if (cb2Copy >= hdaFifoWToSz(pState, 4))
     1435        {
     1436            cbBackendCopy = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
     1437            Assert((cbBackendCopy));
     1438            /* Assertion!!! It was copied less than cbUnderFifoW
     1439             * Probably we need to move the buffer, but it rather hard to imagine situation
     1440             * why it may happen.
     1441             */
     1442            Assert((cbBackendCopy == pBdle->cbUnderFifoW + cb2Copy)); /* we assume that we write whole buffer including not reported bytes */
     1443            if (   pBdle->cbUnderFifoW
     1444                && pBdle->cbUnderFifoW <= cbBackendCopy)
     1445                Log(("hda:wa: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1446            pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy);
     1447            pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy);
     1448            Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32Avail >= cbBackendCopy)); /* sanity */
     1449            *pu32Avail -= cbBackendCopy;
     1450            cbTransfered += cbBackendCopy;
     1451        }
     1452        else
     1453        {
     1454            Log(("hda:wa: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     1455            pBdle->cbUnderFifoW += cb2Copy;
     1456            pBdle->u32BdleCviPos += cb2Copy;
     1457            Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 4)));
    13281458            break;
    13291459        }
    1330         temp    -= copied;
    1331         written += copied;
    1332         pBdle->u32BdleCviPos += copied;
    1333     }
    1334     return written;
     1460        Log(("hda:wa: CVI(pos:%d, len:%d, cbTransfered:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransfered));
     1461
     1462        Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1)));
     1463        if (   cbTransfered == (SDFIFOS(pState, 4) + 1)
     1464            || pBdle->u32BdleCviLen == pBdle->u32BdleCviPos)
     1465            break;
     1466    }
     1467    Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1)));
     1468    Log(("hda:wa: cbTransfered: %d\n", cbTransfered));
     1469    return cbTransfered;
    13351470}
    13361471
     
    13541489    uint32_t u32Lcbl;
    13551490    uint32_t u32Fifos;
     1491    uint32_t u32Fifow;
    13561492    switch (src)
    13571493    {
     
    13601496            u8Strm = 4;
    13611497            u32Ctl = SDCTL(pState, 4);
    1362             u64BaseDMA = SDBDPL(pState, 4);
    1363             u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32);
     1498            u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4));
    13641499            pu32Lpib = &SDLPIB(pState, 4);
    13651500            pu32Sts = &SDSTS(pState, 4);
     
    13671502            pBdle = &pState->stOutBdle;
    13681503            pBdle->u32BdleMaxCvi = SDLVI(pState, 4);
     1504            u32Fifos = SDFIFOS(pState, 4);
     1505            u32Fifow = hdaFifoWToSz(pState, 4);
    13691506            break;
    13701507        }
     
    13761513            pu32Sts = &SDSTS(pState, 0);
    13771514            u32Lcbl = SDLCBL(pState, 0);
    1378             u64BaseDMA = SDBDPL(pState, 0);
    1379             u64BaseDMA |= (((uint64_t)SDBDPU(pState, 0)) << 32);
     1515            u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 0), SDBDPU(pState, 0));
    13801516            pBdle = &pState->stInBdle;
    13811517            pBdle->u32BdleMaxCvi = SDLVI(pState, 0);
     1518            u32Fifos = SDFIFOS(pState, 0);
     1519            u32Fifow = hdaFifoWToSz(pState, 0);
    13821520            break;
    13831521        }
     
    13941532    while( avail && !fStop)
    13951533    {
     1534        Assert((avail >= 0 && (u32Lcbl >= (*pu32Lpib)))); /* sanity */
     1535        uint32_t u32CblLimit = u32Lcbl - (*pu32Lpib);
     1536        Log(("hda: CBL=%d, LPIB=%d\n", u32Lcbl, *pu32Lpib));
    13961537        switch (src)
    13971538        {
    13981539            case PO_INDEX:
    1399                 nBytes = hdaWriteAudio(pState, avail, &fStop);
     1540                nBytes = hdaWriteAudio(pState, (uint32_t *)&avail, &fStop, u32CblLimit);
    14001541                break;
    14011542            case PI_INDEX:
    1402                 nBytes = hdaReadAudio(pState, avail, &fStop);
     1543                nBytes = hdaReadAudio(pState, (uint32_t *)&avail, &fStop, u32CblLimit);
    14031544                break;
    14041545            default:
     
    14071548                AssertMsgFailed(("Unsupported"));
    14081549        }
    1409         /* Update the buffer position and handle Cyclic Buffer Length (CBL) wraparound. */
    1410         *pu32Lpib += nBytes;
    1411         avail -= nBytes;
    1412         if (*pu32Lpib >= u32Lcbl)
    1413             *pu32Lpib  -= u32Lcbl;
    1414 
    1415         /* Optionally write back the current DMA position. */
    1416         if (pState->u64DPBase & DPBASE_ENABLED)
    1417             PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState),
     1550        /*
     1551         * if we're under FIFO Watermark it's expected that HDA doesn't fetch anything.
     1552         * (ICH6 datasheet 18.2.38)
     1553         */
     1554        Assert(nBytes <= (u32Fifos + 1));
     1555        if (!pBdle->cbUnderFifoW)
     1556        {
     1557            *pu32Lpib += nBytes;
     1558            /*
     1559             * Update the buffer position and handle Cyclic Buffer Length (CBL) wraparound.
     1560             */
     1561            Assert((*pu32Lpib <= u32Lcbl));
     1562   
     1563            /* Optionally write back the current DMA position. */
     1564            if (pState->u64DPBase & DPBASE_ENABLED)
     1565                PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState),
    14181566                               (pState->u64DPBase & DPBASE_ADDR_MASK) + u8Strm*8, pu32Lpib, sizeof(*pu32Lpib));
    1419 
     1567   
     1568        }
    14201569        /* Process end of buffer condition. */
    1421         if (pBdle->u32BdleCviPos == pBdle->u32BdleCviLen)
     1570        if (   pBdle->u32BdleCviPos == pBdle->u32BdleCviLen
     1571            || *pu32Lpib == u32Lcbl)
    14221572        {
    14231573            if (pBdle->fBdleCviIoc)
     
    14261576                hdaProcessInterrupt(pState);
    14271577            }
    1428             pBdle->u32BdleCviPos = 0;
    1429             pBdle->u32BdleCvi++;
    1430             if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1)
     1578            if (*pu32Lpib == u32Lcbl)
     1579                *pu32Lpib -= u32Lcbl;
     1580
     1581            if (pBdle->u32BdleCviPos == pBdle->u32BdleCviLen)
    14311582            {
    1432                 pBdle->u32BdleCvi = 0;
     1583                pBdle->u32BdleCviPos = 0;
     1584                pBdle->u32BdleCvi++;
     1585                if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1)
     1586                {
     1587                    pBdle->u32BdleCvi = 0;
     1588                }
     1589                fetch_bd(pState, pBdle, u64BaseDMA);
    14331590            }
    1434             fStop = true;   /* Give the guest a chance to refill (or empty) buffers. */
     1591            if (nBytes > (u32Fifow))
     1592                fStop = true;
    14351593        }
    14361594    }
     
    16871845    SDFIFOS(&pThis->hda, 2) = HDA_SDINFIFO_120B;
    16881846    SDFIFOS(&pThis->hda, 3) = HDA_SDINFIFO_120B;
     1847
    16891848    SDFIFOS(&pThis->hda, 4) = HDA_SDONFIFO_192B;
    16901849    SDFIFOS(&pThis->hda, 5) = HDA_SDONFIFO_192B;
    16911850    SDFIFOS(&pThis->hda, 6) = HDA_SDONFIFO_192B;
    16921851    SDFIFOS(&pThis->hda, 7) = HDA_SDONFIFO_192B;
     1852
     1853    SDFIFOW(&pThis->hda, 0) = HDA_SDFIFOW_8B;
     1854    SDFIFOW(&pThis->hda, 4) = HDA_SDFIFOW_32B;
    16931855
    16941856    /* emulateion of codec "wake up" HDA spec (5.5.1 and 6.5)*/
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