Changeset 88139 in vbox
- Timestamp:
- Mar 16, 2021 12:33:30 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r88137 r88139 540 540 SSMFIELD_ENTRY(HDASTREAMPERIOD, u64ElapsedWalClk), 541 541 SSMFIELD_ENTRY(HDASTREAMPERIOD, cFramesTransferred), 542 SSMFIELD_ENTRY (HDASTREAMPERIOD, cIntPending),542 SSMFIELD_ENTRY_OLD(cIntPending, sizeof(uint8_t)), /** @todo Not sure what we should for non-zero values on restore... ignoring it for now. */ 543 543 SSMFIELD_ENTRY_TERM() 544 544 }; … … 568 568 }; 569 569 570 571 #ifdef IN_RING3572 /**573 * Reschedules pending interrupts for all audio streams which have complete574 * audio periods but did not have the chance to issue their (pending) interrupts yet.575 *576 * @param pDevIns The device instance.577 * @param pThis The shared HDA device state.578 * @param pThisCC The ring-3 HDA device state.579 */580 static void hdaR3ReschedulePendingInterrupts(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC)581 {582 bool fInterrupt = false;583 584 for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i)585 {586 PHDASTREAM pStream = &pThis->aStreams[i];587 if ( hdaR3StreamPeriodIsComplete( &pStream->State.Period)588 && hdaR3StreamPeriodNeedsInterrupt(&pStream->State.Period)589 && hdaR3WalClkSet(pThis, pThisCC, hdaR3StreamPeriodGetAbsElapsedWalClk(&pStream->State.Period), false /* fForce */))590 {591 fInterrupt = true;592 break;593 }594 }595 596 LogFunc(("fInterrupt=%RTbool\n", fInterrupt));597 598 HDA_PROCESS_INTERRUPT(pDevIns, pThis);599 }600 #endif /* IN_RING3 */601 570 602 571 /** … … 1483 1452 if (pThisCC->cStreamsActive) 1484 1453 pThisCC->cStreamsActive--; 1485 1486 /* Make sure to (re-)schedule outstanding (delayed) interrupts. */1487 hdaR3ReschedulePendingInterrupts(pDevIns, pThis, pThisCC);1488 1454 1489 1455 /* Reset the period. */ -
trunk/src/VBox/Devices/Audio/HDAStreamPeriod.cpp
r88096 r88139 112 112 pPeriod->cFramesToTransfer = cFramesToTransfer; 113 113 pPeriod->cFramesTransferred = 0; 114 pPeriod->cIntPending = 0;115 114 116 115 Log3Func(("[SD%RU8] %RU64 long, Hz=%RU32, CBL=%RU32, LVI=%RU16 -> %u periods, %RU32 frames each\n", … … 129 128 { 130 129 Log3Func(("[SD%RU8]\n", pPeriod->u8SD)); 131 132 if (pPeriod->cIntPending)133 LogRelMax(50, ("HDA: Warning: %RU8 interrupts for stream #%RU8 still pending -- so a period reset might trigger audio hangs\n",134 pPeriod->cIntPending, pPeriod->u8SD));135 130 136 131 pPeriod->fStatus &= ~HDASTREAMPERIOD_F_ACTIVE; … … 138 133 pPeriod->u64ElapsedWalClk = 0; 139 134 pPeriod->cFramesTransferred = 0; 140 pPeriod->cIntPending = 0;141 135 # ifdef LOG_ENABLED 142 136 pPeriod->Dbg.tsStartNs = 0; … … 159 153 pPeriod->u64ElapsedWalClk = 0; 160 154 pPeriod->cFramesTransferred = 0; 161 pPeriod->cIntPending = 0;162 155 # ifdef LOG_ENABLED 163 156 pPeriod->Dbg.tsStartNs = RTTimeNanoTS(); … … 169 162 170 163 /** 171 * Ends a formerly begun period life span.172 *173 * @param pPeriod Stream period to end life span for.174 */175 void hdaR3StreamPeriodEnd(PHDASTREAMPERIOD pPeriod)176 {177 Log3Func(("[SD%RU8] Took %zuus\n", pPeriod->u8SD, (RTTimeNanoTS() - pPeriod->Dbg.tsStartNs) / 1000));178 179 if (!(pPeriod->fStatus & HDASTREAMPERIOD_F_ACTIVE))180 return;181 182 /* Sanity. */183 AssertMsg(pPeriod->cIntPending == 0,184 ("%RU8 interrupts for stream #%RU8 still pending -- so ending a period might trigger audio hangs\n",185 pPeriod->cIntPending, pPeriod->u8SD));186 Assert(hdaR3StreamPeriodIsComplete(pPeriod));187 188 pPeriod->fStatus &= ~HDASTREAMPERIOD_F_ACTIVE;189 }190 191 /**192 * Pauses a period. All values remain intact.193 *194 * @param pPeriod Stream period to pause.195 */196 void hdaR3StreamPeriodPause(PHDASTREAMPERIOD pPeriod)197 {198 AssertMsg((pPeriod->fStatus & HDASTREAMPERIOD_F_ACTIVE), ("Period %p already in inactive state\n", pPeriod));199 200 pPeriod->fStatus &= ~HDASTREAMPERIOD_F_ACTIVE;201 202 Log3Func(("[SD%RU8]\n", pPeriod->u8SD));203 }204 205 /**206 164 * Resumes a formerly paused period. 207 165 * … … 305 263 306 264 /** 307 * Tells whether a given stream period has some required interrupts pending or not.308 *309 * @return true if period has interrupts pending, false if not.310 * @param pPeriod Stream period to get status for.311 */312 bool hdaR3StreamPeriodNeedsInterrupt(PHDASTREAMPERIOD pPeriod)313 {314 return pPeriod->cIntPending > 0;315 }316 317 /**318 * Acquires (references) an (pending) interrupt for a given stream period.319 *320 * @param pPeriod Stream period to acquire interrupt for.321 *322 * @remark This routine does not do any actual interrupt processing; it only323 * keeps track of the required (pending) interrupts for a stream period.324 */325 void hdaR3StreamPeriodAcquireInterrupt(PHDASTREAMPERIOD pPeriod)326 {327 uint32_t cIntPending = pPeriod->cIntPending;328 if (cIntPending)329 {330 Log3Func(("[SD%RU8] Already pending\n", pPeriod->u8SD));331 return;332 }333 334 pPeriod->cIntPending++;335 336 Log3Func(("[SD%RU8] %RU32\n", pPeriod->u8SD, pPeriod->cIntPending));337 }338 339 /**340 * Releases (dereferences) a pending interrupt.341 *342 * @param pPeriod Stream period to release pending interrupt for.343 */344 void hdaR3StreamPeriodReleaseInterrupt(PHDASTREAMPERIOD pPeriod)345 {346 Assert(pPeriod->cIntPending);347 pPeriod->cIntPending--;348 349 Log3Func(("[SD%RU8] %RU32\n", pPeriod->u8SD, pPeriod->cIntPending));350 }351 352 /**353 265 * Adds an amount of (processed) audio frames to a given stream period. 354 266 * … … 369 281 } 370 282 371 /**372 * Tells whether a given stream period is considered as complete or not.373 *374 * @return true if stream period is complete, false if not.375 * @param pPeriod Stream period to report status for.376 *377 * @remark A stream period is considered complete if it has 1) passed (elapsed) its calculated period time378 * and 2) processed all required audio frames.379 */380 bool hdaR3StreamPeriodIsComplete(PHDASTREAMPERIOD pPeriod)381 {382 const bool fIsComplete = /* Has the period elapsed time-wise? */383 hdaR3StreamPeriodHasElapsed(pPeriod)384 /* All frames transferred? */385 && pPeriod->cFramesTransferred >= pPeriod->cFramesToTransfer;386 # ifdef VBOX_STRICT387 if (fIsComplete)388 {389 Assert(pPeriod->cFramesTransferred == pPeriod->cFramesToTransfer);390 Assert(pPeriod->u64ElapsedWalClk == pPeriod->u64DurationWalClk);391 }392 # endif393 394 Log3Func(("[SD%RU8] Period %s - runtime %RU64 / %RU64 (abs @ %RU64, starts @ %RU64, ends @ %RU64), %RU8 IRQs pending\n",395 pPeriod->u8SD,396 fIsComplete ? "COMPLETE" : "NOT COMPLETE YET",397 pPeriod->u64ElapsedWalClk, pPeriod->u64DurationWalClk,398 hdaR3StreamPeriodGetAbsElapsedWalClk(pPeriod), pPeriod->u64StartWalClk,399 hdaR3StreamPeriodGetAbsEndWalClk(pPeriod), pPeriod->cIntPending));400 401 return fIsComplete;402 }403 404 283 #endif /* IN_RING3 */ 405 284 -
trunk/src/VBox/Devices/Audio/HDAStreamPeriod.h
r88138 r88139 58 58 /** The period's status flags. */ 59 59 uint8_t fStatus; 60 /** Number of pending interrupts required for this period. */ 61 uint8_t cIntPending; 62 uint8_t bPadding0; 60 uint8_t abPadding[2]; 63 61 /** Hertz (Hz) rate this period runs with. */ 64 62 uint32_t u32Hz; … … 92 90 void hdaR3StreamPeriodReset(PHDASTREAMPERIOD pPeriod); 93 91 int hdaR3StreamPeriodBegin(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk); 94 void hdaR3StreamPeriodEnd(PHDASTREAMPERIOD pPeriod);95 void hdaR3StreamPeriodPause(PHDASTREAMPERIOD pPeriod);96 92 void hdaR3StreamPeriodResume(PHDASTREAMPERIOD pPeriod); 97 93 uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t uFrames); … … 101 97 bool hdaR3StreamPeriodHasElapsed(PHDASTREAMPERIOD pPeriod); 102 98 bool hdaR3StreamPeriodHasPassedAbsWalClk(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk); 103 bool hdaR3StreamPeriodNeedsInterrupt(PHDASTREAMPERIOD pPeriod);104 void hdaR3StreamPeriodAcquireInterrupt(PHDASTREAMPERIOD pPeriod);105 void hdaR3StreamPeriodReleaseInterrupt(PHDASTREAMPERIOD pPeriod);106 99 void hdaR3StreamPeriodInc(PHDASTREAMPERIOD pPeriod, uint32_t framesInc); 107 bool hdaR3StreamPeriodIsComplete(PHDASTREAMPERIOD pPeriod);108 100 #endif /* IN_RING3 */ 109 101
Note:
See TracChangeset
for help on using the changeset viewer.