Changeset 89751 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 16, 2021 8:38:13 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145202
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89750 r89751 2656 2656 case AC97_NABM_OFF_LVI: 2657 2657 DEVAC97_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_IOPORT_WRITE); 2658 if ( (pRegs->cr & AC97_CR_RPBM)2659 && (pRegs->sr & AC97_SR_DCH))2658 if ( !(pRegs->sr & AC97_SR_DCH) 2659 || !(pRegs->cr & AC97_CR_RPBM)) 2660 2660 { 2661 pRegs->lvi = u32 % AC97_MAX_BDLE; 2662 DEVAC97_UNLOCK(pDevIns, pThis); 2663 Log3Func(("[SD%RU8] LVI <- %#x\n", pStream->u8SD, u32)); 2664 } 2665 else 2666 { 2667 #ifdef IN_RING3 2668 /* Recover from underflow situation where CIV caught up with LVI 2669 and the DMA processing stopped. We clear the status condition, 2670 update LVI and then try to load the next BDLE. Unfortunately, 2671 we cannot do this from ring-3 as much of the BDLE state is 2672 ring-3 only. */ 2661 2673 pRegs->sr &= ~(AC97_SR_DCH | AC97_SR_CELV); 2662 pRegs->civ = pRegs->piv; 2663 pRegs->piv = (pRegs->piv + 1) % AC97_MAX_BDLE; 2664 /** @todo r=bird: there used to be a ichac97StreamFetchBDLE here, but it was 2665 * removed in r128222 without any helpful clue in the commit message 2666 * ("Audio/AC97: Added more code for transfer calculation for helping with A/V 2667 * synchronization"). There wasn't and isn't any clue to the logic here in the 2668 * source code either, of course, so at least there is some consistency. :-) 2669 * 2670 * The old code with the fetch was probably correct, though, as we're now 2671 * skipping one BDLE (CIV is incremented here, but since PICB is still zero 2672 * we'll increment CIV again in the DMA transfer loop - the way I read it). 2673 * 2674 * I found no special handling of DCH in the linux code, but that doesn't prove 2675 * anything as they might just expect the device never to get into this underrun 2676 * situation... Ditto windows 8.1 AC'97 sample driver. */ 2674 pRegs->lvi = u32 % AC97_MAX_BDLE; 2675 if (ichac97R3StreamFetchNextBdle(pDevIns, pStream, pStreamCC)) 2676 ichac97StreamUpdateSR(pDevIns, pThis, pStream, pRegs->sr | AC97_SR_BCIS); 2677 2678 /* We now have to re-arm the DMA timer according to the new BDLE length. 2679 This means leaving the device lock to avoid virtual sync lock order issues. */ 2680 ichac97R3StreamTransferUpdate(pDevIns, pStream, pStreamCC); 2681 uint64_t const cTicksToDeadline = pStreamCC->State.cTransferTicks; 2682 2683 /** @todo Stop the DMA timer when we get into the AC97_SR_CELV situation to 2684 * avoid potential race here. */ 2685 DEVAC97_UNLOCK(pDevIns, pThis); 2686 2687 LogFunc(("[SD%RU8] LVI <- %#x; CIV=%#x PIV=%#x SR=%#x cTicksToDeadline=%#RX64 [recovering]\n", 2688 pStream->u8SD, u32, pRegs->civ, pRegs->piv, pRegs->sr, cTicksToDeadline)); 2689 2690 /** @todo take down the start time here. */ 2691 int rc2 = PDMDevHlpTimerSetRelative(pDevIns, pStream->hTimer, cTicksToDeadline, NULL /*pu64Now*/); 2692 AssertRC(rc2); 2693 #else 2694 rc = VINF_IOM_R3_IOPORT_WRITE; 2695 #endif 2677 2696 } 2678 pRegs->lvi = u32 % AC97_MAX_BDLE;2679 DEVAC97_UNLOCK(pDevIns, pThis);2680 Log3Func(("[SD%RU8] LVI <- %#x\n", pStream->u8SD, u32));2681 2697 break; 2682 2698 … … 2721 2737 { 2722 2738 /** @todo r=bird: How do we prevent the guest from triggering enable more 2723 * than once? */2739 * than once? Only take action if the RBMP bit changed. Duh^3 */ 2724 2740 Log3Func(("[SD%RU8] Enable\n", pStream->u8SD)); 2725 2741 … … 2738 2754 * create a lock order violation with the virtual sync time lock otherwise. 2739 2755 */ 2756 /** @todo is ichac97R3StreamTransferUpdate called here? */ 2740 2757 uint64_t const cTicksToDeadline = pStreamCC->State.cTransferTicks; 2741 2758
Note:
See TracChangeset
for help on using the changeset viewer.