- Timestamp:
- Nov 23, 2010 8:03:20 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r34229 r34271 1342 1342 } 1343 1343 1344 static inline uint32_t hdaCalculate DMABufferLength(PHDABDLEDESC pBdle, uint32_t u32SoundBackendBufferBytesAvail, uint32_t u32Fifos, uint32_t u32CblLimit)1344 static inline uint32_t hdaCalculateTransferBufferLength(PHDABDLEDESC pBdle, uint32_t u32SoundBackendBufferBytesAvail, uint32_t u32Fifos, uint32_t u32CblLimit) 1345 1345 { 1346 1346 uint32_t cb2Copy; … … 1366 1366 } 1367 1367 1368 static inline void hdaBackendWriteTransferReported(PHDABDLEDESC pBdle, uint32_t cbArranged2Copy, uint32_t cbCopied, uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity) 1369 { 1370 Log(("hda:hdaBackendWriteTransferReported: cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 1371 cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 1372 Assert((cbCopied)); 1373 Assert((pu32BackendBufferCapacity && *pu32BackendBufferCapacity)); 1374 /* Assertion!!! It was copied less than cbUnderFifoW 1375 * Probably we need to move the buffer, but it rather hard to imagine situation 1376 * why it may happen. 1377 */ 1378 Assert((cbCopied == pBdle->cbUnderFifoW + cbArranged2Copy)); /* we assume that we write whole buffer including not reported bytes */ 1379 if ( pBdle->cbUnderFifoW 1380 && pBdle->cbUnderFifoW <= cbCopied) 1381 Log(("hda:hdaBackendWriteTransferReported: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1382 1383 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbCopied); 1384 Assert((!pBdle->cbUnderFifoW)); /* Assert!!! Assumption failed */ 1385 1386 /* We always increment position on DMA buffer counter because we're always reading to intermediate buffer */ 1387 pBdle->u32BdleCviPos += cbArranged2Copy; 1388 1389 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32BackendBufferCapacity >= cbCopied)); /* sanity */ 1390 /* We reports all bytes (including unreported previously) */ 1391 *pu32DMACursor += cbCopied; 1392 /* reducing backend counter on amount of bytes we copied to backend */ 1393 *pu32BackendBufferCapacity -= cbCopied; 1394 Log(("hda:hdaBackendWriteTransferReported: CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 1395 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity)); 1396 } 1397 1398 static inline void hdaBackendReadTransferReported(PHDABDLEDESC pBdle, uint32_t cbArranged2Copy, uint32_t cbCopied, uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity) 1399 { 1400 Assert((cbCopied, cbArranged2Copy)); 1401 *pu32BackendBufferCapacity -= cbCopied; 1402 pBdle->u32BdleCviPos += cbCopied; 1403 Log(("hda:hdaBackendReadTransferReported: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1404 *pu32DMACursor += cbCopied + pBdle->cbUnderFifoW; 1405 pBdle->cbUnderFifoW = 0; 1406 Log(("hda:hdaBackendReadTransferReported: CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 1407 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 1408 } 1409 1410 static inline void hdaBackendTransferUnreported(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint8_t u8Strm, uint32_t cbCopied, uint32_t *pu32BackendBufferCapacity) 1411 { 1412 Log(("hda:hdaBackendTransferUnreported: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1413 pBdle->u32BdleCviPos += cbCopied; 1414 pBdle->cbUnderFifoW += cbCopied; 1415 /* In case of read transaction we're always coping from backend buffer */ 1416 if (pu32BackendBufferCapacity) 1417 *pu32BackendBufferCapacity -= cbCopied; 1418 Log(("hda:hdaBackendTransferUnreported: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1419 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, u8Strm))); 1420 } 1421 /* 1422 * hdaReadAudio - copies samples from Qemu Sound back-end to DMA. 1423 * Note: this function writes immediately to DMA buffer, but "reports bytes" when all conditions meet (FIFOW) 1424 */ 1368 1425 static uint32_t hdaReadAudio(INTELHDLinkState *pState, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit) 1369 1426 { … … 1375 1432 Log(("hda:ra: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1376 1433 1377 cb2Copy = hdaCalculate DMABufferLength(pBdle, *pu32Avail, SDFIFOS(pState, 0), u32CblLimit);1434 cb2Copy = hdaCalculateTransferBufferLength(pBdle, *pu32Avail, SDFIFOS(pState, 0), u32CblLimit); 1378 1435 if (!cb2Copy) 1379 1436 { 1437 /* if we enter here we can't report "unreported bits" */ 1380 1438 *fStop = true; 1381 return 0;1439 goto done; 1382 1440 } 1383 1441 1384 1442 1385 1443 /* 1386 * read from backend input line 1444 * read from backend input line to last ureported position or at the begining. 1387 1445 */ 1388 1446 cbBackendCopy = AUD_read (ISD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy); … … 1392 1450 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer, cbBackendCopy); 1393 1451 1452 /* Don't see reasons why cb2Copy could differ from cbBackendCopy */ 1394 1453 Assert((cbBackendCopy == cb2Copy && (*pu32Avail) >= cb2Copy)); /* sanity */ 1395 *pu32Avail -= cb2Copy; 1396 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1454 1397 1455 if (pBdle->cbUnderFifoW + cbBackendCopy > hdaFifoWToSz(pState, 0)) 1398 { 1399 Log(("hda:ra: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1400 cbTransfered += cbBackendCopy + pBdle->cbUnderFifoW; 1401 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1402 Assert(!pBdle->cbUnderFifoW); /* we assume, we've read Under FIFO W fully */ 1403 } 1456 hdaBackendReadTransferReported(pBdle, cb2Copy, cbBackendCopy, &cbTransfered, pu32Avail); 1404 1457 else 1405 1458 { 1406 Log(("hda:ra: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1407 pBdle->cbUnderFifoW += RT_MIN(cbBackendCopy, cb2Copy); 1408 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 0))); 1459 hdaBackendTransferUnreported(pState, pBdle, 0, cbBackendCopy, pu32Avail); 1409 1460 *fStop = true; 1410 goto done;1411 1461 } 1412 1462 done: … … 1425 1475 Log(("hda:wa: CVI(cvi:%d, pos:%d, len:%d)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1426 1476 1427 cb2Copy = hdaCalculate DMABufferLength(pBdle, *pu32Avail, SDFIFOS(pState, 4), u32CblLimit);1477 cb2Copy = hdaCalculateTransferBufferLength(pBdle, *pu32Avail, SDFIFOS(pState, 4), u32CblLimit); 1428 1478 1429 1479 /* 1430 1480 * Copy from DMA to the corresponding hdaBuffer (if there exists some bytes from the previous not reported transfer we write to ''pBdle->cbUnderFifoW'' offset) 1431 1481 */ 1432 if (cb2Copy) 1433 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 1482 if (!cb2Copy) 1483 { 1484 *fStop = true; 1485 goto done; 1486 } 1487 1488 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 1434 1489 /* 1435 1490 * Write to audio backend. we should be sure whether we have enought bytes to copy to Audio backend. … … 1441 1496 */ 1442 1497 cbBackendCopy = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 1443 Assert((cbBackendCopy)); 1444 /* Assertion!!! It was copied less than cbUnderFifoW 1445 * Probably we need to move the buffer, but it rather hard to imagine situation 1446 * why it may happen. 1447 */ 1448 Assert((cbBackendCopy == pBdle->cbUnderFifoW + cb2Copy)); /* we assume that we write whole buffer including not reported bytes */ 1449 if ( pBdle->cbUnderFifoW 1450 && pBdle->cbUnderFifoW <= cbBackendCopy) 1451 Log(("hda:wa: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1452 1453 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1454 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1455 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32Avail >= cbBackendCopy)); /* sanity */ 1456 Assert((!pBdle->cbUnderFifoW)); /* Assert!!! Assumption failed */ 1457 *pu32Avail -= cbBackendCopy; 1458 cbTransfered += cbBackendCopy; 1498 hdaBackendWriteTransferReported(pBdle, cb2Copy, cbBackendCopy, &cbTransfered, pu32Avail); 1459 1499 } 1460 1500 else 1461 1501 { 1462 1502 /* Not enough bytes to be processed and reported, check luck on next enterence */ 1463 Log(("hda:wa: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1464 pBdle->cbUnderFifoW += cb2Copy; 1465 pBdle->u32BdleCviPos += cb2Copy; 1466 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 4))); 1467 goto done; 1503 hdaBackendTransferUnreported(pState, pBdle, 4, cb2Copy, NULL); 1504 *fStop = true; 1468 1505 } 1469 1506 … … 1532 1569 return; 1533 1570 /* Fetch the Buffer Descriptor Entry (BDE). */ 1534 *pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);1535 1571 fetch_bd(pState, pBdle, u64BaseDMA); 1536 1572 while( avail && !fStop) 1537 1573 { 1574 *pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 1538 1575 Assert((avail >= 0 && (u32Cbl >= (*pu32Lpib)))); /* sanity */ 1539 1576 uint32_t u32CblLimit = u32Cbl - (*pu32Lpib); … … 1557 1594 */ 1558 1595 Assert(nBytes <= (u32Fifos + 1)); 1596 *pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 1559 1597 if (!pBdle->cbUnderFifoW) 1560 1598 { … … 1574 1612 || *pu32Lpib == u32Cbl) 1575 1613 { 1576 if ( !pBdle->cbUnderFifoW1577 && pBdle->fBdleCviIoc)1614 if ( !pBdle->cbUnderFifoW 1615 && pBdle->fBdleCviIoc) 1578 1616 { 1579 *pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 1617 /* 1618 * @todo - more carefully investigate BCIS flag. 1619 * Speech synthesis works fine on Mac Guest if this bit isn't set 1620 * but in general sound quality becomes lesser. 1621 */ 1580 1622 *pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 1581 hdaProcessInterrupt(pState); 1623 /* 1624 * we should generate the interrupt if ICE bit of SDCTL register is set. 1625 */ 1626 if (u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)) 1627 hdaProcessInterrupt(pState); 1582 1628 } 1583 1629 if (*pu32Lpib == u32Cbl) … … 1596 1642 } 1597 1643 } 1598 *pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);1599 1644 } 1600 1645
Note:
See TracChangeset
for help on using the changeset viewer.