Changeset 81181 in vbox
- Timestamp:
- Oct 9, 2019 12:09:24 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r81031 r81181 402 402 /* Offset 0x88 (SD0) */ \ 403 403 { 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, 0x0000 FFFF, 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" }, \ 406 406 /* Reserved: FIFO Watermark. ** @todo Document this! */ \ 407 407 { offset + 0xE, 0x00002, 0x00000007, 0x00000007, HDA_RD_FLAG_NONE, hdaRegReadU16 , hdaRegWriteSDFIFOW, HDA_REG_IDX_STRM(name, FIFOW), #name " FIFO Watermark" }, \ … … 1368 1368 hdaR3StreamLock(pStream); 1369 1369 1370 int rc2 ;1370 int rc2 = VINF_SUCCESS; 1371 1371 1372 1372 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO … … 1420 1420 } 1421 1421 1422 /* Enable/disable the stream. */ 1423 rc2 = hdaR3StreamEnable(pStream, fRun /* fEnable */); 1424 AssertRC(rc2); 1425 1426 if (fRun) 1422 if (RT_SUCCESS(rc2)) 1427 1423 { 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 */); 1437 1426 AssertRC(rc2); 1438 1427 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 } 1454 1458 } 1455 1459 … … 1597 1601 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1598 1602 1603 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg); 1604 1599 1605 #ifdef HDA_USE_DMA_ACCESS_HANDLER 1600 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);1601 1602 1606 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) 1603 1607 { … … 1613 1617 } 1614 1618 #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)); 1615 1622 1616 1623 int rc2 = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r80692 r81181 26 26 #include <iprt/semaphore.h> 27 27 28 #include <VBox/AssertGuest.h> 28 29 #include <VBox/vmm/pdmdev.h> 29 30 #include <VBox/vmm/pdmaudioifs.h> … … 239 240 AssertRCReturn(rc, rc); 240 241 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 241 246 /* 242 247 * Set the stream's timer Hz rate, based on the stream channel count. … … 344 349 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS)); 345 350 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 350 351 if (RT_SUCCESS(rc)) 351 352 { … … 357 358 /* Figure out how many transfer fragments we're going to use for this stream. */ 358 359 /** @todo Use a more dynamic fragment size? */ 359 Assert(pStream->u16LVI <= UINT8_MAX - 1);360 360 uint8_t cFragments = pStream->u16LVI + 1; 361 361 if (cFragments <= 1) … … 446 446 Assert(pStream->State.cbTransferSize); 447 447 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)); 476 483 477 484 #ifdef LOG_ENABLED 478 hdaR3BDLEDumpAll(pThis, pStream->u64BDLBase, pStream->u16LVI + 1);485 hdaR3BDLEDumpAll(pThis, pStream->u64BDLBase, pStream->u16LVI + 1); 479 486 #endif 487 } 488 } 480 489 } 481 490
Note:
See TracChangeset
for help on using the changeset viewer.