Changeset 89753 in vbox
- Timestamp:
- Jun 16, 2021 10:54:04 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89752 r89753 1719 1719 pRegs->picb = 0; 1720 1720 pRegs->piv = 0; /* Note! Because this is also zero, we will actually start transferring with BDLE00. */ 1721 pRegs->cr = pRegs->cr &AC97_CR_DONT_CLEAR_MASK;1721 pRegs->cr &= AC97_CR_DONT_CLEAR_MASK; 1722 1722 pRegs->bd_valid = 0; 1723 1723 … … 2702 2702 */ 2703 2703 case AC97_NABM_OFF_CR: 2704 { 2704 2705 #ifdef IN_RING3 2705 2706 DEVAC97_LOCK(pDevIns, pThis); 2706 2707 2707 Log3Func(("[SD%RU8] CR <- %#x (cr %#x)\n", pStream->u8SD, u32, pRegs->cr)); 2708 if (u32 & AC97_CR_RR) /* Busmaster reset. */ 2708 uint32_t const fCrChanged = pRegs->cr ^ u32; 2709 Log3Func(("[SD%RU8] CR <- %#x (was %#x; changed %#x)\n", pStream->u8SD, u32, pRegs->cr, fCrChanged)); 2710 2711 /* 2712 * Busmaster reset. 2713 */ 2714 if (u32 & AC97_CR_RR) 2709 2715 { 2710 Log3Func(("[SD%RU8] Reset\n", pStream->u8SD)); 2711 2712 /* Make sure that Run/Pause Bus Master bit (RPBM) is cleared (0). */ 2713 Assert((pRegs->cr & AC97_CR_RPBM) == 0); 2714 if (pRegs->cr & AC97_CR_RPBM) 2715 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */); 2716 LogFunc(("[SD%RU8] Reset\n", pStream->u8SD)); 2717 2718 /* Make sure that Run/Pause Bus Master bit (RPBM) is cleared (0). 2719 3.2.7 in 302349-003 says RPBM be must be clear when resetting 2720 and that behavior is undefined if it's set. */ 2721 ASSERT_GUEST_STMT((pRegs->cr & AC97_CR_RPBM) == 0, 2722 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, 2723 pStreamCC, false /* fEnable */)); 2716 2724 2717 2725 ichac97R3StreamReset(pThis, pStream, pStreamCC); 2718 2726 2719 2727 ichac97StreamUpdateSR(pDevIns, pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */ 2728 2729 DEVAC97_UNLOCK(pDevIns, pThis); 2730 break; 2731 } 2732 2733 /* 2734 * Write the new value to the register and if RPBM didn't change we're done. 2735 */ 2736 pRegs->cr = u32 & AC97_CR_VALID_MASK; 2737 2738 if (!(fCrChanged & AC97_CR_RPBM)) 2739 DEVAC97_UNLOCK(pDevIns, pThis); /* Probably not so likely, but avoid one extra intentation level. */ 2740 /* 2741 * Pause busmaster. 2742 */ 2743 else if (!(pRegs->cr & AC97_CR_RPBM)) 2744 { 2745 LogFunc(("[SD%RU8] Pause busmaster (disable stream) SR=%#x -> %#x\n", 2746 pStream->u8SD, pRegs->sr, pRegs->sr | AC97_SR_DCH)); 2747 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */); 2748 pRegs->sr |= AC97_SR_DCH; 2720 2749 2721 2750 DEVAC97_UNLOCK(pDevIns, pThis); 2722 2751 } 2752 /* 2753 * Run busmaster. 2754 */ 2723 2755 else 2724 2756 { 2725 pRegs->cr = u32 & AC97_CR_VALID_MASK; 2726 2727 if (!(pRegs->cr & AC97_CR_RPBM)) 2728 { 2729 Log3Func(("[SD%RU8] Disable\n", pStream->u8SD)); 2730 2731 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */); 2732 2733 pRegs->sr |= AC97_SR_DCH; 2734 2735 DEVAC97_UNLOCK(pDevIns, pThis); 2736 } 2737 else 2738 { 2739 /** @todo r=bird: How do we prevent the guest from triggering enable more 2740 * than once? Only take action if the RBMP bit changed. Duh^3 */ 2741 Log3Func(("[SD%RU8] Enable\n", pStream->u8SD)); 2742 2743 pRegs->sr &= ~AC97_SR_DCH; 2744 2745 if (ichac97R3StreamFetchNextBdle(pDevIns, pStream, pStreamCC)) 2746 ichac97StreamUpdateSR(pDevIns, pThis, pStream, pRegs->sr | AC97_SR_BCIS); 2757 LogFunc(("[SD%RU8] Run busmaster (enable stream) SR=%#x -> %#x\n", 2758 pStream->u8SD, pRegs->sr, pRegs->sr & ~AC97_SR_DCH)); 2759 pRegs->sr &= ~AC97_SR_DCH; 2760 2761 if (ichac97R3StreamFetchNextBdle(pDevIns, pStream, pStreamCC)) 2762 ichac97StreamUpdateSR(pDevIns, pThis, pStream, pRegs->sr | AC97_SR_BCIS); 2747 2763 # ifdef LOG_ENABLED 2748 2749 2764 if (LogIsFlowEnabled()) 2765 ichac97R3DbgPrintBdl(pDevIns, pThis, pStream, DBGFR3InfoLogHlp(), "ichac97IoPortNabmWrite: "); 2750 2766 # endif 2751 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fEnable */); 2752 2753 /* 2754 * Arm the DMA timer. Must drop the AC'97 device lock first as it would 2755 * create a lock order violation with the virtual sync time lock otherwise. 2756 */ 2757 /** @todo is ichac97R3StreamTransferUpdate called here? */ 2758 uint64_t const cTicksToDeadline = pStreamCC->State.cTransferTicks; 2759 2760 DEVAC97_UNLOCK(pDevIns, pThis); 2761 2762 /** @todo take down the start time here. */ 2763 int rc2 = PDMDevHlpTimerSetRelative(pDevIns, pStream->hTimer, cTicksToDeadline, NULL /*pu64Now*/); 2764 AssertRC(rc2); 2765 } 2767 ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fEnable */); 2768 2769 /* 2770 * Arm the DMA timer. Must drop the AC'97 device lock first as it would 2771 * create a lock order violation with the virtual sync time lock otherwise. 2772 */ 2773 /** @todo is ichac97R3StreamTransferUpdate called here? */ 2774 uint64_t const cTicksToDeadline = pStreamCC->State.cTransferTicks; 2775 2776 DEVAC97_UNLOCK(pDevIns, pThis); 2777 2778 /** @todo for output streams we could probably service this a little bit 2779 * earlier if we push it, just to reduce the lag... For HDA we do a 2780 * DMA run immediately after the stream is enabled. */ 2781 /** @todo take down the start time here. */ 2782 int rc2 = PDMDevHlpTimerSetRelative(pDevIns, pStream->hTimer, cTicksToDeadline, NULL /*pu64Now*/); 2783 AssertRC(rc2); 2766 2784 } 2767 2785 #else /* !IN_RING3 */ … … 2769 2787 #endif 2770 2788 break; 2789 } 2771 2790 2772 2791 /*
Note:
See TracChangeset
for help on using the changeset viewer.