Changeset 82450 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Dec 6, 2019 12:39:15 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r82425 r82450 24 24 * Header Files * 25 25 *********************************************************************************************************************************/ 26 #ifdef DEBUG_bird27 # define RT_NO_STRICT /* I'm tried of this crap asserting on save and restore of Maverics guests. */28 #endif29 26 #define LOG_GROUP LOG_GROUP_DEV_HDA 30 27 #include <VBox/log.h> … … 219 216 /** Node for storing this driver in our device driver list of HDASTATE. */ 220 217 RTLISTNODER3 Node; 221 /** Pointer to HDA controller (state). */ 222 R3PTRTYPE(PHDASTATE) pHDAState; 218 /** Pointer to shared HDA device state. */ 219 R3PTRTYPE(PHDASTATE) pHDAStateShared; 220 /** Pointer to the ring-3 HDA device state. */ 221 R3PTRTYPE(PHDASTATER3) pHDAStateR3; 223 222 /** Driver flags. */ 224 223 PDMAUDIODRVFLAGS fFlags; … … 254 253 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 255 254 #ifdef IN_RING3 256 static void hdaR3GCTLReset(P HDASTATE pThis);255 static void hdaR3GCTLReset(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC); 257 256 #endif 258 257 … … 317 316 */ 318 317 #ifdef IN_RING3 319 static int hdaR3AddStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);320 static int hdaR3RemoveStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);318 static int hdaR3AddStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg); 319 static int hdaR3RemoveStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg); 321 320 # ifdef HDA_USE_DMA_ACCESS_HANDLER 322 321 static DECLCALLBACK(VBOXSTRICTRC) hdaR3DmaAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, … … 331 330 */ 332 331 #ifdef IN_RING3 333 static int hdaR3MixerAddDrvStream(P HDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);332 static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv); 334 333 #endif 335 334 /** @} */ … … 564 563 * audio periods but did not have the chance to issue their (pending) interrupts yet. 565 564 * 566 * @param pThis The HDA device state. 567 */ 568 static void hdaR3ReschedulePendingInterrupts(PHDASTATE pThis) 565 * @param pDevIns The device instance. 566 * @param pThis The shared HDA device state. 567 * @param pThisCC The ring-3 HDA device state. 568 */ 569 static void hdaR3ReschedulePendingInterrupts(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC) 569 570 { 570 571 bool fInterrupt = false; … … 572 573 for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i) 573 574 { 574 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, i); 575 if (!pStream) 576 continue; 577 578 if ( hdaR3StreamPeriodIsComplete (&pStream->State.Period) 575 PHDASTREAM pStream = &pThis->aStreams[i]; 576 if ( hdaR3StreamPeriodIsComplete( &pStream->State.Period) 579 577 && hdaR3StreamPeriodNeedsInterrupt(&pStream->State.Period) 580 && hdaR3WalClkSet(pThis, hdaR3StreamPeriodGetAbsElapsedWalClk(&pStream->State.Period), false /* fForce */))578 && hdaR3WalClkSet(pThis, pThisCC, hdaR3StreamPeriodGetAbsElapsedWalClk(&pStream->State.Period), false /* fForce */)) 581 579 { 582 580 fInterrupt = true; … … 587 585 LogFunc(("fInterrupt=%RTbool\n", fInterrupt)); 588 586 589 HDA_PROCESS_INTERRUPT(p This->pDevInsR3, pThis);587 HDA_PROCESS_INTERRUPT(pDevIns, pThis); 590 588 } 591 589 #endif /* IN_RING3 */ … … 703 701 * 704 702 * @returns IPRT status code. 705 * @param pThis HDA state. 703 * 704 * @param pDevIns The device instance. 705 * @param pThis The shared HDA device state. 706 706 * @param fLocal Specify true to synchronize HDA state's CORB buffer with the device state, 707 707 * or false to synchronize the device state's RIRB buffer with the HDA state. … … 709 709 * @todo r=andy Break this up into two functions? 710 710 */ 711 static int hdaR3CmdSync(P HDASTATE pThis, bool fLocal)711 static int hdaR3CmdSync(PPDMDEVINS pDevIns, PHDASTATE pThis, bool fLocal) 712 712 { 713 713 int rc = VINF_SUCCESS; … … 716 716 if (pThis->u64CORBBase) 717 717 { 718 AssertPtr(pThis->pu32CorbBuf);719 718 Assert(pThis->cbCorbBuf); 720 719 … … 722 721 * the CORB and PDMDevHlpPCIPhysWrite with RIRB below. There are 723 722 * similar unexplained inconsistencies in DevHDACommon.cpp. */ 724 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pThis->u64CORBBase, pThis->pu32CorbBuf, pThis->cbCorbBuf); 723 rc = PDMDevHlpPhysRead(pDevIns, pThis->u64CORBBase, pThis->au32CorbBuf, 724 RT_MIN(pThis->cbCorbBuf, sizeof(pThis->au32CorbBuf))); 725 725 Log(("hdaR3CmdSync/CORB: read %RGp LB %#x (%Rrc)\n", pThis->u64CORBBase, pThis->cbCorbBuf, rc)); 726 726 AssertRCReturn(rc, rc); … … 731 731 if (pThis->u64RIRBBase) 732 732 { 733 AssertPtr(pThis->pu64RirbBuf);734 733 Assert(pThis->cbRirbBuf); 735 734 736 rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), pThis->u64RIRBBase, pThis->pu64RirbBuf, pThis->cbRirbBuf); 737 Log(("hdaR3CmdSync/RIRB: phys read %RGp LB %#x (%Rrc)\n", pThis->u64RIRBBase, pThis->pu64RirbBuf, rc)); 735 rc = PDMDevHlpPCIPhysWrite(pDevIns, pThis->u64RIRBBase, pThis->au64RirbBuf, 736 RT_MIN(pThis->cbRirbBuf, sizeof(pThis->au64RirbBuf))); 737 Log(("hdaR3CmdSync/RIRB: phys read %RGp LB %#x (%Rrc)\n", pThis->u64RIRBBase, pThis->cbRirbBuf, rc)); 738 738 AssertRCReturn(rc, rc); 739 739 } … … 789 789 * This will invoke the HDA codec verb dispatcher. 790 790 * 791 * @returns IPRT status code. 792 * @param pThis HDA state. 793 */ 794 static int hdaR3CORBCmdProcess(PHDASTATE pThis) 795 { 796 uint8_t corbRp = HDA_REG(pThis, CORBRP); 797 uint8_t corbWp = HDA_REG(pThis, CORBWP); 798 uint8_t rirbWp = HDA_REG(pThis, RIRBWP); 799 800 Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", corbRp, corbWp, rirbWp)); 791 * @returns VBox status code suitable for MMIO write return. 792 * @param pDevIns The device instance. 793 * @param pThis The shared HDA device state. 794 * @param pThisCC The ring-3 HDA device state. 795 */ 796 static int hdaR3CORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC) 797 { 798 Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP))); 801 799 802 800 if (!(HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA)) … … 808 806 Assert(pThis->cbCorbBuf); 809 807 810 int rc = hdaR3CmdSync(p This, true /* Sync from guest */);808 int rc = hdaR3CmdSync(pDevIns, pThis, true /* Sync from guest */); 811 809 AssertRCReturn(rc, rc); 812 810 811 /* 812 * Prepare local copies of relevant registers. 813 */ 813 814 uint16_t cIntCnt = HDA_REG(pThis, RINTCNT) & 0xff; 814 815 815 if (!cIntCnt) /* 0 means 256 interrupts. */ 816 816 cIntCnt = HDA_MAX_RINTCNT; 817 817 818 Log3Func(("START CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", 819 corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt)); 820 818 uint32_t const cCorbEntries = RT_MIN(RT_MAX(pThis->cbCorbBuf, 1), sizeof(pThis->au32CorbBuf)) / HDA_CORB_ELEMENT_SIZE; 819 uint8_t const corbWp = HDA_REG(pThis, CORBWP) % cCorbEntries; 820 uint8_t corbRp = HDA_REG(pThis, CORBRP); 821 uint8_t rirbWp = HDA_REG(pThis, RIRBWP); 822 823 /* 824 * The loop. 825 */ 826 Log3Func(("START CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt)); 821 827 while (corbRp != corbWp) 822 828 { 823 corbRp = (corbRp + 1) % (pThis->cbCorbBuf / HDA_CORB_ELEMENT_SIZE); /* Advance +1 as the first command(s) are at CORBWP + 1. */ 824 825 uint32_t uCmd = pThis->pu32CorbBuf[corbRp]; 829 /* Fetch the command from the CORB. */ 830 corbRp = (corbRp + 1) /* Advance +1 as the first command(s) are at CORBWP + 1. */ % cCorbEntries; 831 uint32_t const uCmd = pThis->au32CorbBuf[corbRp]; 832 833 /* 834 * Execute the command. 835 */ 826 836 uint64_t uResp = 0; 827 828 rc = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp); 837 rc = pThisCC->pCodec->pfnLookup(pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp); 829 838 if (RT_FAILURE(rc)) 830 839 LogFunc(("Codec lookup failed with rc=%Rrc\n", rc)); 831 832 Log3Func(("Codec verb %08x -> response %016lx\n", uCmd, uResp)); 840 Log3Func(("Codec verb %08x -> response %016RX64\n", uCmd, uResp)); 833 841 834 842 if ( (uResp & CODEC_RESPONSE_UNSOLICITED) … … 837 845 LogFunc(("Unexpected unsolicited response.\n")); 838 846 HDA_REG(pThis, CORBRP) = corbRp; 839 840 /** @todo r=andy No CORB/RIRB syncing to guest required in that case? */ 841 return rc; 842 } 843 847 /** @todo r=andy No RIRB syncing to guest required in that case? */ 848 /** @todo r=bird: Why isn't RIRBWP updated here. The response might come 849 * after already processing several commands, can't it? (When you think 850 * about it, it is bascially the same question as Andy is asking.) */ 851 return VINF_SUCCESS; 852 } 853 854 /* 855 * Store the response in the RIRB. 856 */ 857 AssertCompile(HDA_RIRB_SIZE == RT_ELEMENTS(pThis->au64RirbBuf)); 844 858 rirbWp = (rirbWp + 1) % HDA_RIRB_SIZE; 845 846 pThis->pu64RirbBuf[rirbWp] = uResp; 847 859 pThis->au64RirbBuf[rirbWp] = uResp; 860 861 /* 862 * Send interrupt if needed. 863 */ 864 bool fSendInterrupt = false; 848 865 pThis->u16RespIntCnt++; 849 850 bool fSendInterrupt = false; 851 852 if (pThis->u16RespIntCnt == cIntCnt) /* Response interrupt count reached? */ 866 if (pThis->u16RespIntCnt >= cIntCnt) /* Response interrupt count reached? */ 853 867 { 854 868 pThis->u16RespIntCnt = 0; /* Reset internal interrupt response counter. */ … … 856 870 Log3Func(("Response interrupt count reached (%RU16)\n", pThis->u16RespIntCnt)); 857 871 fSendInterrupt = true; 858 859 872 } 860 873 else if (corbRp == corbWp) /* Did we reach the end of the current command buffer? */ … … 863 876 fSendInterrupt = true; 864 877 } 865 866 878 if (fSendInterrupt) 867 879 { … … 869 881 { 870 882 HDA_REG(pThis, RIRBSTS) |= HDA_RIRBSTS_RINTFL; 871 872 rc = HDA_PROCESS_INTERRUPT(pThis->pDevInsR3, pThis); 883 HDA_PROCESS_INTERRUPT(pDevIns, pThis); 873 884 } 874 885 } 875 886 } 876 887 877 Log3Func(("END CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", 878 corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt)); 879 888 /* 889 * Put register locals back. 890 */ 891 Log3Func(("END CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt)); 880 892 HDA_REG(pThis, CORBRP) = corbRp; 881 893 HDA_REG(pThis, RIRBWP) = rirbWp; 882 894 883 rc = hdaR3CmdSync(pThis, false /* Sync to guest */);884 AssertRCReturn(rc, rc);885 886 if (RT_FAILURE(rc))887 AssertRCReturn(rc,rc);895 /* 896 * Write out the response. 897 */ 898 rc = hdaR3CmdSync(pDevIns, pThis, false /* Sync to guest */); 899 AssertRC(rc); 888 900 889 901 return rc; … … 989 1001 HDA_REG(pThis, GCTL) &= ~HDA_GCTL_CRST; 990 1002 991 hdaR3GCTLReset(p This);1003 hdaR3GCTLReset(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3)); 992 1004 #else 993 1005 return VINF_IOM_R3_MMIO_WRITE; … … 1032 1044 /** 1033 1045 * Returns the current maximum value the wall clock counter can be set to. 1046 * 1034 1047 * This maximum value depends on all currently handled HDA streams and their own current timing. 1035 1048 * 1036 1049 * @return Current maximum value the wall clock counter can be set to. 1037 * @param pThis HDA state. 1050 * @param pThis The shared HDA device state. 1051 * @param pThisCC The ring-3 HDA device state. 1038 1052 * 1039 1053 * @remark Does not actually set the wall clock counter. 1040 */ 1041 static uint64_t hdaR3WalClkGetMax(PHDASTATE pThis) 1054 * 1055 * @todo r=bird: This function is in the wrong file. 1056 */ 1057 static uint64_t hdaR3WalClkGetMax(PHDASTATE pThis, PHDASTATER3 pThisCC) 1042 1058 { 1043 1059 const uint64_t u64WalClkCur = ASMAtomicReadU64(&pThis->u64WalClk); 1044 const uint64_t u64FrontAbsWalClk = pThis ->SinkFront.pStream1045 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThis ->SinkFront.pStream->State.Period): 0;1060 const uint64_t u64FrontAbsWalClk = pThisCC->SinkFront.pStreamShared 1061 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkFront.pStreamShared->State.Period) : 0; 1046 1062 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 1047 1063 # error "Implement me!" 1048 1064 # endif 1049 const uint64_t u64LineInAbsWalClk = pThis ->SinkLineIn.pStream1050 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThis ->SinkLineIn.pStream->State.Period) : 0;1065 const uint64_t u64LineInAbsWalClk = pThisCC->SinkLineIn.pStreamShared 1066 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkLineIn.pStreamShared->State.Period) : 0; 1051 1067 # ifdef VBOX_WITH_HDA_MIC_IN 1052 const uint64_t u64MicInAbsWalClk = pThis ->SinkMicIn.pStream1053 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThis ->SinkMicIn.pStream->State.Period): 0;1068 const uint64_t u64MicInAbsWalClk = pThisCC->SinkMicIn.pStreamShared 1069 ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkMicIn.pStreamShared->State.Period) : 0; 1054 1070 # endif 1055 1071 … … 1078 1094 *pu32Value = RT_LO_U32(u64WalClkCur); 1079 1095 1080 Log3Func(("%RU32 (max @ %RU64)\n", *pu32Value, hdaR3WalClkGetMax(pThis )));1096 Log3Func(("%RU32 (max @ %RU64)\n", *pu32Value, hdaR3WalClkGetMax(pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3)))); 1081 1097 return VINF_SUCCESS; 1082 1098 #else … … 1094 1110 if (pThis->cbCorbBuf) 1095 1111 { 1096 #ifdef IN_RING3 1097 AssertPtr(pThis->pu32CorbBuf); 1098 RT_BZERO(pThis->pu32CorbBuf, pThis->cbCorbBuf); 1099 #else 1112 RT_ZERO(pThis->au32CorbBuf); 1100 1113 return VINF_IOM_R3_MMIO_WRITE; 1101 #endif1102 1114 } 1103 1115 … … 1119 1131 1120 1132 if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Start DMA engine. */ 1121 rc = hdaR3CORBCmdProcess(p This);1133 rc = hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3)); 1122 1134 else 1123 1135 LogFunc(("CORB DMA not running, skipping\n")); … … 1132 1144 static VBOXSTRICTRC hdaRegWriteCORBSIZE(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1133 1145 { 1134 #ifdef IN_RING31135 1146 RT_NOREF(pDevIns, iReg); 1136 1147 … … 1159 1170 1160 1171 uint32_t cbCorbBuf = cEntries * HDA_CORB_ELEMENT_SIZE; 1161 Assert(cbCorbBuf <= HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Paranoia.*/1172 Assert(cbCorbBuf <= sizeof(pThis->au32CorbBuf)); /* paranoia */ 1162 1173 1163 1174 if (cbCorbBuf != pThis->cbCorbBuf) 1164 1175 { 1165 RT_ BZERO(pThis->pu32CorbBuf, HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Clear CORB when setting a new size. */1176 RT_ZERO(pThis->au32CorbBuf); /* Clear CORB when setting a new size. */ 1166 1177 pThis->cbCorbBuf = cbCorbBuf; 1167 1178 } … … 1174 1185 LogFunc(("CORB DMA is (still) running, skipping\n")); 1175 1186 return VINF_SUCCESS; 1187 } 1188 1189 static VBOXSTRICTRC hdaRegWriteCORBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1190 { 1191 RT_NOREF(pDevIns, iReg); 1192 1193 uint32_t v = HDA_REG(pThis, CORBSTS); 1194 HDA_REG(pThis, CORBSTS) &= ~(v & u32Value); 1195 1196 return VINF_SUCCESS; 1197 } 1198 1199 static VBOXSTRICTRC hdaRegWriteCORBWP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1200 { 1201 #ifdef IN_RING3 1202 VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1203 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 1204 1205 return hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3)); 1176 1206 #else 1177 1207 RT_NOREF(pDevIns, pThis, iReg, u32Value); … … 1180 1210 } 1181 1211 1182 static VBOXSTRICTRC hdaRegWriteCORBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1183 { 1184 RT_NOREF(pDevIns, iReg); 1185 1186 uint32_t v = HDA_REG(pThis, CORBSTS); 1187 HDA_REG(pThis, CORBSTS) &= ~(v & u32Value); 1188 1189 return VINF_SUCCESS; 1190 } 1191 1192 static VBOXSTRICTRC hdaRegWriteCORBWP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1212 static VBOXSTRICTRC hdaRegWriteSDCBL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1213 { 1214 return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 1215 } 1216 1217 static VBOXSTRICTRC hdaRegWriteSDCTL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1193 1218 { 1194 1219 #ifdef IN_RING3 1195 VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1196 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 1197 1198 return hdaR3CORBCmdProcess(pThis); 1199 #else 1200 RT_NOREF(pDevIns, pThis, iReg, u32Value); 1201 return VINF_IOM_R3_MMIO_WRITE; 1202 #endif 1203 } 1204 1205 static VBOXSTRICTRC hdaRegWriteSDCBL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1206 { 1207 return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 1208 } 1209 1210 static VBOXSTRICTRC hdaRegWriteSDCTL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1211 { 1212 #ifdef IN_RING3 1213 /* Get the stream descriptor. */ 1220 /* Get the stream descriptor number. */ 1214 1221 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg); 1222 AssertReturn(uSD < RT_ELEMENTS(pThis->aStreams), VERR_INTERNAL_ERROR_3); /* paranoia^2: Bad g_aHdaRegMap. */ 1215 1223 1216 1224 /* … … 1221 1229 * So depending on the guest OS, SD3 can use stream tag 4, for example. 1222 1230 */ 1223 uint8_t uTag = (u32Value >> HDA_SDCTL_NUM_SHIFT) & HDA_SDCTL_NUM_MASK; 1224 ASSERT_GUEST_MSG_RETURN(uTag < RT_ELEMENTS(pThis->aTags), 1231 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 1232 uint8_t uTag = (u32Value >> HDA_SDCTL_NUM_SHIFT) & HDA_SDCTL_NUM_MASK; 1233 ASSERT_GUEST_MSG_RETURN(uTag < RT_ELEMENTS(pThisCC->aTags), 1225 1234 ("SD%RU8: Invalid stream tag %RU8 (u32Value=%#x)!\n", uSD, uTag, u32Value), 1226 1235 VINF_SUCCESS /* Always return success to the MMIO handler. */); 1227 1236 1228 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 1229 ASSERT_GUEST_LOGREL_MSG_RETURN(pStream, ("Guest tried writing SDCTL (0x%x) to unhandled stream #%RU8\n", u32Value, uSD), 1230 VINF_SUCCESS /* Always return success to the MMIO handler. */); 1237 PHDASTREAM const pStreamShared = &pThis->aStreams[uSD]; 1238 PHDASTREAMR3 const pStreamR3 = &pThisCC->aStreams[uSD]; 1231 1239 1232 1240 const bool fRun = RT_BOOL(u32Value & HDA_SDCTL_RUN); … … 1242 1250 { 1243 1251 DEVHDA_UNLOCK(pDevIns, pThis); 1244 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream , VINF_IOM_R3_MMIO_WRITE);1252 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStreamShared, VINF_IOM_R3_MMIO_WRITE); 1245 1253 } 1246 1254 … … 1256 1264 1257 1265 /* Exit reset state. */ 1258 ASMAtomicXchgBool(&pStream ->State.fInReset, false);1266 ASMAtomicXchgBool(&pStreamShared->State.fInReset, false); 1259 1267 1260 1268 /* Report that we're done resetting this stream by clearing SRST. */ … … 1270 1278 LogFunc(("[SD%RU8] Reset enter\n", uSD)); 1271 1279 1272 hdaR3StreamLock(pStream );1280 hdaR3StreamLock(pStreamR3); 1273 1281 1274 1282 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1275 hdaR3StreamAsyncIOLock(pStream );1283 hdaR3StreamAsyncIOLock(pStreamR3); 1276 1284 # endif 1277 1285 /* Make sure to remove the run bit before doing the actual stream reset. */ 1278 1286 HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_SDCTL_RUN; 1279 1287 1280 hdaR3StreamReset(pThis, p Stream, pStream->u8SD);1288 hdaR3StreamReset(pThis, pThisCC, pStreamShared, pStreamR3, uSD); 1281 1289 1282 1290 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1283 hdaR3StreamAsyncIOUnlock(pStream );1291 hdaR3StreamAsyncIOUnlock(pStreamR3); 1284 1292 # endif 1285 hdaR3StreamUnlock(pStream );1293 hdaR3StreamUnlock(pStreamR3); 1286 1294 } 1287 1295 else … … 1295 1303 LogFunc(("[SD%RU8] State changed (fRun=%RTbool)\n", uSD, fRun)); 1296 1304 1297 hdaR3StreamLock(pStream );1305 hdaR3StreamLock(pStreamR3); 1298 1306 1299 1307 int rc2 = VINF_SUCCESS; … … 1301 1309 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1302 1310 if (fRun) 1303 rc2 = hdaR3StreamAsyncIOCreate(pStream );1304 1305 hdaR3StreamAsyncIOLock(pStream );1311 rc2 = hdaR3StreamAsyncIOCreate(pStreamR3); 1312 1313 hdaR3StreamAsyncIOLock(pStreamR3); 1306 1314 # endif 1307 1315 if (fRun) … … 1316 1324 } 1317 1325 1318 PHDATAG pTag = &pThis->aTags[uTag]; 1319 AssertPtr(pTag); 1320 1326 /* Assign new values. */ 1321 1327 LogFunc(("[SD%RU8] Using stream tag=%RU8\n", uSD, uTag)); 1322 1323 /* Assign new values. */ 1324 pTag->uTag = uTag; 1325 pTag->pStream = hdaGetStreamFromSD(pThis, uSD); 1328 PHDATAG pTag = &pThisCC->aTags[uTag]; 1329 pTag->uTag = uTag; 1330 pTag->pStreamR3 = &pThisCC->aStreams[uSD]; 1326 1331 1327 1332 # ifdef LOG_ENABLED 1328 1333 PDMAUDIOPCMPROPS Props; 1329 rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, pStream->u8SD), &Props);1334 rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props); 1330 1335 AssertRC(rc2); 1331 1336 LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n", 1332 pStream->u8SD, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels));1337 uSD, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels)); 1333 1338 # endif 1334 1339 /* (Re-)initialize the stream with current values. */ 1335 rc2 = hdaR3Stream Init(pDevIns, pStream, pStream->u8SD);1340 rc2 = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, pStreamR3, uSD); 1336 1341 if ( RT_SUCCESS(rc2) 1337 1342 /* Any vital stream change occurred so that we need to (re-)add the stream to our setup? … … 1340 1345 { 1341 1346 /* Remove the old stream from the device setup. */ 1342 rc2 = hdaR3RemoveStream(pThis , &pStream->State.Cfg);1347 rc2 = hdaR3RemoveStream(pThisCC, &pStreamShared->State.Cfg); 1343 1348 AssertRC(rc2); 1344 1349 1345 1350 /* Add the stream to the device setup. */ 1346 rc2 = hdaR3AddStream(pThis , &pStream->State.Cfg);1351 rc2 = hdaR3AddStream(pThisCC, &pStreamShared->State.Cfg); 1347 1352 AssertRC(rc2); 1348 1353 } … … 1352 1357 { 1353 1358 /* Enable/disable the stream. */ 1354 rc2 = hdaR3StreamEnable(pStream , fRun /* fEnable */);1359 rc2 = hdaR3StreamEnable(pStreamShared, pStreamR3, fRun /* fEnable */); 1355 1360 AssertRC(rc2); 1356 1361 … … 1358 1363 { 1359 1364 /* Keep track of running streams. */ 1360 pThis ->cStreamsActive++;1365 pThisCC->cStreamsActive++; 1361 1366 1362 1367 /* (Re-)init the stream's period. */ 1363 hdaR3StreamPeriodInit(&pStream ->State.Period,1364 pStream ->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.Cfg);1368 hdaR3StreamPeriodInit(&pStreamShared->State.Period, uSD, pStreamShared->u16LVI, 1369 pStreamShared->u32CBL, &pStreamShared->State.Cfg); 1365 1370 1366 1371 /* Begin a new period for this stream. */ 1367 rc2 = hdaR3StreamPeriodBegin(&pStream->State.Period, hdaWalClkGetCurrent(pThis)/* Use current wall clock time */); 1372 rc2 = hdaR3StreamPeriodBegin(&pStreamShared->State.Period, 1373 hdaWalClkGetCurrent(pThis) /* Use current wall clock time */); 1368 1374 AssertRC(rc2); 1369 1375 1370 uint64_t const tsNow = PDMDevHlpTimerGet(pDevIns, pStream ->hTimer);1371 rc2 = hdaR3TimerSet(pDevIns, pStream , tsNow + pStream->State.cTransferTicks, false /* fForce */, tsNow);1376 uint64_t const tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); 1377 rc2 = hdaR3TimerSet(pDevIns, pStreamShared, tsNow + pStreamShared->State.cTransferTicks, false /* fForce */, tsNow); 1372 1378 AssertRC(rc2); 1373 1379 } … … 1375 1381 { 1376 1382 /* Keep track of running streams. */ 1377 Assert(pThis ->cStreamsActive);1378 if (pThis ->cStreamsActive)1379 pThis ->cStreamsActive--;1383 Assert(pThisCC->cStreamsActive); 1384 if (pThisCC->cStreamsActive) 1385 pThisCC->cStreamsActive--; 1380 1386 1381 1387 /* Make sure to (re-)schedule outstanding (delayed) interrupts. */ 1382 hdaR3ReschedulePendingInterrupts(p This);1388 hdaR3ReschedulePendingInterrupts(pDevIns, pThis, pThisCC); 1383 1389 1384 1390 /* Reset the period. */ 1385 hdaR3StreamPeriodReset(&pStream ->State.Period);1391 hdaR3StreamPeriodReset(&pStreamShared->State.Period); 1386 1392 } 1387 1393 } 1388 1394 1389 1395 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1390 hdaR3StreamAsyncIOUnlock(pStream );1396 hdaR3StreamAsyncIOUnlock(pStreamR3); 1391 1397 # endif 1392 1398 /* Make sure to leave the lock before (eventually) starting the timer. */ 1393 hdaR3StreamUnlock(pStream );1399 hdaR3StreamUnlock(pStreamR3); 1394 1400 } 1395 1401 } 1396 1402 1397 1403 if (fNeedVirtualSyncClockLock) 1398 PDMDevHlpTimerUnlockClock(pDevIns, pStream ->hTimer); /* Caller will unlock pThis->CritSect. */1404 PDMDevHlpTimerUnlockClock(pDevIns, pStreamShared->hTimer); /* Caller will unlock pThis->CritSect. */ 1399 1405 1400 1406 return hdaRegWriteU24(pDevIns, pThis, iReg, u32Value); … … 1409 1415 #ifdef IN_RING3 1410 1416 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, STS, iReg); 1411 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 1412 ASSERT_GUEST_LOGREL_MSG_RETURN(pStream, ("Guest tried writing SDSTS (0x%x) to unhandled stream #%RU8\n", u32Value, uSD), 1413 VINF_SUCCESS); 1417 AssertReturn(uSD < RT_ELEMENTS(pThis->aStreams), VERR_INTERNAL_ERROR_3); /* paranoia^2: Bad g_aHdaRegMap. */ 1418 PHDASTATER3 const pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 1419 PHDASTREAMR3 const pStreamR3 = &pThisCC->aStreams[uSD]; 1420 PHDASTREAM const pStreamShared = &pThis->aStreams[uSD]; 1414 1421 1415 1422 /* We only need to take the virtual-sync lock if we want to call 1416 1423 PDMDevHlpTimerGet or hdaR3TimerSet later. Only precondition for that 1417 1424 is that we've got a non-zero ticks-per-transfer value. */ 1418 uint64_t const cTransferTicks = pStream ->State.cTransferTicks;1425 uint64_t const cTransferTicks = pStreamShared->State.cTransferTicks; 1419 1426 if (cTransferTicks) 1420 1427 { 1421 1428 DEVHDA_UNLOCK(pDevIns, pThis); 1422 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream , VINF_IOM_R3_MMIO_WRITE);1423 } 1424 1425 hdaR3StreamLock(pStream );1429 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStreamShared, VINF_IOM_R3_MMIO_WRITE); 1430 } 1431 1432 hdaR3StreamLock(pStreamR3); 1426 1433 1427 1434 uint32_t v = HDA_REG_IND(pThis, iReg); … … 1438 1445 /* Some guests tend to write SDnSTS even if the stream is not running. 1439 1446 * So make sure to check if the RUN bit is set first. */ 1440 const bool fRunning = pStream ->State.fRunning;1441 1442 Log3Func(("[SD%RU8] fRunning=%RTbool %R[sdsts]\n", pStream->u8SD, fRunning, v));1443 1444 PHDASTREAMPERIOD pPeriod = &pStream ->State.Period;1447 const bool fRunning = pStreamShared->State.fRunning; 1448 1449 Log3Func(("[SD%RU8] fRunning=%RTbool %R[sdsts]\n", uSD, fRunning, v)); 1450 1451 PHDASTREAMPERIOD pPeriod = &pStreamShared->State.Period; 1445 1452 hdaR3StreamPeriodLock(pPeriod); 1446 1453 if (hdaR3StreamPeriodNeedsInterrupt(pPeriod)) … … 1450 1457 /* Make sure to try to update the WALCLK register if a period is complete. 1451 1458 * Use the maximum WALCLK value all (active) streams agree to. */ 1452 const uint64_t uWalClkMax = hdaR3WalClkGetMax(pThis );1459 const uint64_t uWalClkMax = hdaR3WalClkGetMax(pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3)); 1453 1460 if (uWalClkMax > hdaWalClkGetCurrent(pThis)) 1454 hdaR3WalClkSet(pThis, uWalClkMax, false /* fForce */);1461 hdaR3WalClkSet(pThis, pThisCC, uWalClkMax, false /* fForce */); 1455 1462 1456 1463 hdaR3StreamPeriodEnd(pPeriod); … … 1466 1473 * ... 1467 1474 */ 1468 uint64_t cTicksToNext = pStream ->State.cTransferTicks;1475 uint64_t cTicksToNext = pStreamShared->State.cTransferTicks; 1469 1476 Assert(cTicksToNext == cTicksToNext); 1470 1477 if (cTicksToNext) /* Only do any calculations if the stream currently is set up for transfers. */ 1471 1478 { 1472 const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream ->hTimer);1473 Assert(tsNow >= pStream ->State.tsTransferLast);1474 1475 const uint64_t cTicksElapsed = tsNow - pStream ->State.tsTransferLast;1479 const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); 1480 Assert(tsNow >= pStreamShared->State.tsTransferLast); 1481 1482 const uint64_t cTicksElapsed = tsNow - pStreamShared->State.tsTransferLast; 1476 1483 # ifdef LOG_ENABLED 1477 const uint64_t cTicksTransferred = pStream ->State.cbTransferProcessed * pStream->State.cTicksPerByte;1484 const uint64_t cTicksTransferred = pStreamShared->State.cbTransferProcessed * pStreamShared->State.cTicksPerByte; 1478 1485 # endif 1479 1486 1480 1487 Log3Func(("[SD%RU8] cTicksElapsed=%RU64, cTicksTransferred=%RU64, cTicksToNext=%RU64\n", 1481 pStream->u8SD, cTicksElapsed, cTicksTransferred, cTicksToNext));1482 1483 Log3Func(("[SD%RU8] cbTransferProcessed=%RU32, cbTransferChunk=%RU32, cbTransferSize=%RU32\n", 1484 pStream ->u8SD, pStream->State.cbTransferProcessed, pStream->State.cbTransferChunk, pStream->State.cbTransferSize));1488 uSD, cTicksElapsed, cTicksTransferred, cTicksToNext)); 1489 1490 Log3Func(("[SD%RU8] cbTransferProcessed=%RU32, cbTransferChunk=%RU32, cbTransferSize=%RU32\n", uSD, 1491 pStreamShared->State.cbTransferProcessed, pStreamShared->State.cbTransferChunk, pStreamShared->State.cbTransferSize)); 1485 1492 1486 1493 if (cTicksElapsed <= cTicksToNext) … … 1489 1496 { 1490 1497 Log3Func(("[SD%RU8] Warning: Lagging behind (%RU64 ticks elapsed, maximum allowed is %RU64)\n", 1491 pStream->u8SD, cTicksElapsed, cTicksToNext)); 1492 1493 LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n", 1494 pStream->u8SD, 1495 (PDMDevHlpTimerGetFreq(pDevIns, pStream->hTimer) / pThis->uTimerHz) / 1000, 1496 (tsNow - pStream->State.tsTransferLast) / 1000)); 1498 uSD, cTicksElapsed, cTicksToNext)); 1499 1500 LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n", uSD, 1501 (PDMDevHlpTimerGetFreq(pDevIns, pStreamShared->hTimer) / pThis->uTimerHz) / 1000, 1502 (tsNow - pStreamShared->State.tsTransferLast) / 1000)); 1497 1503 1498 1504 cTicksToNext = 0; 1499 1505 } 1500 1506 1501 Log3Func(("[SD%RU8] -> cTicksToNext=%RU64\n", pStream->u8SD, cTicksToNext));1507 Log3Func(("[SD%RU8] -> cTicksToNext=%RU64\n", uSD, cTicksToNext)); 1502 1508 1503 1509 /* Reset processed data counter. */ 1504 pStream ->State.cbTransferProcessed = 0;1505 pStream ->State.tsTransferNext = tsNow + cTicksToNext;1510 pStreamShared->State.cbTransferProcessed = 0; 1511 pStreamShared->State.tsTransferNext = tsNow + cTicksToNext; 1506 1512 1507 1513 /* Only re-arm the timer if there were pending transfer interrupts left 1508 1514 * -- it could happen that we land in here if a guest writes to SDnSTS 1509 1515 * unconditionally. */ 1510 if (pStream ->State.cTransferPendingInterrupts)1511 { 1512 pStream ->State.cTransferPendingInterrupts--;1516 if (pStreamShared->State.cTransferPendingInterrupts) 1517 { 1518 pStreamShared->State.cTransferPendingInterrupts--; 1513 1519 1514 1520 /* Re-arm the timer. */ 1515 LogFunc(("Timer set SD%RU8\n", pStream->u8SD)); 1516 hdaR3TimerSet(pDevIns, pStream, tsNow + cTicksToNext, true /* fForce - we just set tsTransferNext*/, 0 /*tsNow*/); 1521 LogFunc(("Timer set SD%RU8\n", uSD)); 1522 hdaR3TimerSet(pDevIns, pStreamShared, tsNow + cTicksToNext, 1523 true /* fForce - we just set tsTransferNext*/, 0 /*tsNow*/); 1517 1524 } 1518 1525 } 1519 1526 1520 1527 if (cTransferTicks) 1521 PDMDevHlpTimerUnlockClock(pDevIns, pStream ->hTimer); /* Caller will unlock pThis->CritSect. */1522 hdaR3StreamUnlock(pStream );1528 PDMDevHlpTimerUnlockClock(pDevIns, pStreamShared->hTimer); /* Caller will unlock pThis->CritSect. */ 1529 hdaR3StreamUnlock(pStreamR3); 1523 1530 return VINF_SUCCESS; 1524 1531 #else /* !IN_RING3 */ … … 1530 1537 static VBOXSTRICTRC hdaRegWriteSDLVI(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1531 1538 { 1532 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg); 1539 const size_t idxStream = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg); 1540 AssertReturn(idxStream < RT_ELEMENTS(pThis->aStreams), VERR_INTERNAL_ERROR_3); /* paranoia^2: Bad g_aHdaRegMap. */ 1533 1541 1534 1542 #ifdef HDA_USE_DMA_ACCESS_HANDLER … … 1537 1545 /* Try registering the DMA handlers. 1538 1546 * As we can't be sure in which order LVI + BDL base are set, try registering in both routines. */ 1539 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);1547 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, idxStream); 1540 1548 if ( pStream 1541 1549 && hdaR3StreamRegisterDMAHandlers(pThis, pStream)) … … 1545 1553 1546 1554 ASSERT_GUEST_LOGREL_MSG(u32Value <= UINT8_MAX, /* Should be covered by the register write mask, but just to make sure. */ 1547 ("LVI for stream #% RU8 must not be bigger than %RU8\n", uSD, UINT8_MAX - 1));1555 ("LVI for stream #%zu must not be bigger than %RU8\n", idxStream, UINT8_MAX - 1)); 1548 1556 return hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1549 1557 } … … 1551 1559 static VBOXSTRICTRC hdaRegWriteSDFIFOW(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1552 1560 { 1553 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg); 1554 1555 if (RT_LIKELY(hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN)) /* FIFOW for input streams only. */ 1561 size_t const idxStream = HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg); 1562 AssertReturn(idxStream < RT_ELEMENTS(pThis->aStreams), VERR_INTERNAL_ERROR_3); /* paranoia^2: Bad g_aHdaRegMap. */ 1563 1564 if (RT_LIKELY(hdaGetDirFromSD((uint8_t)idxStream) == PDMAUDIODIR_IN)) /* FIFOW for input streams only. */ 1556 1565 { /* likely */ } 1557 1566 else 1558 1567 { 1559 1568 #ifndef IN_RING0 1560 LogRel(("HDA: Warning: Guest tried to write read-only FIFOW to output stream #%RU8, ignoring\n", uSD));1569 LogRel(("HDA: Warning: Guest tried to write read-only FIFOW to output stream #%RU8, ignoring\n", idxStream)); 1561 1570 return VINF_SUCCESS; 1562 1571 #else … … 1565 1574 } 1566 1575 1567 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg)); 1568 if (pStream) 1569 { 1570 uint32_t u32FIFOW = 0; 1571 switch (u32Value) 1572 { 1573 case HDA_SDFIFOW_8B: 1574 case HDA_SDFIFOW_16B: 1575 case HDA_SDFIFOW_32B: 1576 u32FIFOW = u32Value; 1577 break; 1578 default: 1579 ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing unsupported FIFOW (0x%x) to stream #%RU8, defaulting to 32 bytes\n", 1580 u32Value, uSD)); 1581 u32FIFOW = HDA_SDFIFOW_32B; 1582 break; 1583 } 1584 1585 if (u32FIFOW) /** @todo r=bird: Logic error. it will never be zero, so why this check? */ 1586 { 1587 pStream->u16FIFOW = hdaSDFIFOWToBytes(u32FIFOW); 1588 LogFunc(("[SD%RU8] Updating FIFOW to %RU32 bytes\n", uSD, pStream->u16FIFOW)); 1589 return hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOW); 1590 } 1576 uint32_t u32FIFOW = 0; 1577 switch (u32Value) 1578 { 1579 case HDA_SDFIFOW_8B: 1580 case HDA_SDFIFOW_16B: 1581 case HDA_SDFIFOW_32B: 1582 u32FIFOW = u32Value; 1583 break; 1584 default: 1585 ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing unsupported FIFOW (0x%zx) to stream #%RU8, defaulting to 32 bytes\n", 1586 u32Value, idxStream)); 1587 u32FIFOW = HDA_SDFIFOW_32B; 1588 break; 1589 } 1590 1591 if (u32FIFOW) /** @todo r=bird: Logic error. it will never be zero, so why this check? */ 1592 { 1593 pThis->aStreams[idxStream].u16FIFOW = hdaSDFIFOWToBytes(u32FIFOW); 1594 LogFunc(("[SD%zu] Updating FIFOW to %u bytes\n", idxStream, pThis->aStreams[idxStream].u16FIFOW)); 1595 return hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOW); 1591 1596 } 1592 1597 return VINF_SUCCESS; … … 1632 1637 * 1633 1638 * @returns IPRT status code. 1634 * @param pThis Device state.1639 * @param pThisCC The ring-3 HDA device state. 1635 1640 * @param pCfg Stream configuration to use for adding a stream. 1636 1641 */ 1637 static int hdaR3AddStreamOut(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 1638 { 1639 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1642 static int hdaR3AddStreamOut(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg) 1643 { 1640 1644 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1641 1645 … … 1718 1722 pCfg->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels); 1719 1723 1720 rc = hdaCodecAddStream(pThis ->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg);1724 rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg); 1721 1725 } 1722 1726 … … 1733 1737 pCfg->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels); 1734 1738 1735 rc = hdaCodecAddStream(pThis ->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);1739 rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg); 1736 1740 } 1737 1741 … … 1747 1751 pCfg->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels); 1748 1752 1749 rc = hdaCodecAddStream(pThis ->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);1753 rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg); 1750 1754 } 1751 1755 # endif /* VBOX_WITH_AUDIO_HDA_51_SURROUND */ … … 1761 1765 * 1762 1766 * @returns IPRT status code. 1763 * @param pThis Device state.1767 * @param pThisCC The ring-3 HDA device state. 1764 1768 * @param pCfg Stream configuration to use for adding a stream. 1765 1769 */ 1766 static int hdaR3AddStreamIn(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 1767 { 1768 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1770 static int hdaR3AddStreamIn(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg) 1771 { 1769 1772 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1770 1773 … … 1774 1777 1775 1778 int rc; 1776 1777 1779 switch (pCfg->u.enmSrc) 1778 1780 { 1779 1781 case PDMAUDIORECSRC_LINE: 1780 { 1781 rc = hdaCodecAddStream(pThis->pCodec, PDMAUDIOMIXERCTL_LINE_IN, pCfg); 1782 rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_LINE_IN, pCfg); 1782 1783 break; 1783 }1784 1784 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 1785 1785 case PDMAUDIORECSRC_MIC: 1786 { 1787 rc = hdaCodecAddStream(pThis->pCodec, PDMAUDIOMIXERCTL_MIC_IN, pCfg); 1786 rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_MIC_IN, pCfg); 1788 1787 break; 1789 }1790 1788 # endif 1791 1789 default: … … 1802 1800 * 1803 1801 * @returns IPRT status code. 1804 * @param pThis Device state.1802 * @param pThisCC The ring-3 HDA device state. 1805 1803 * @param pCfg Stream configuration to use for adding a stream. 1806 1804 */ 1807 static int hdaR3AddStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 1808 { 1809 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1805 static int hdaR3AddStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg) 1806 { 1810 1807 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1811 1808 1809 LogFlowFuncEnter(); 1810 1812 1811 int rc; 1813 1814 LogFlowFuncEnter();1815 1816 1812 switch (pCfg->enmDir) 1817 1813 { 1818 1814 case PDMAUDIODIR_OUT: 1819 rc = hdaR3AddStreamOut(pThis , pCfg);1815 rc = hdaR3AddStreamOut(pThisCC, pCfg); 1820 1816 break; 1821 1817 1822 1818 case PDMAUDIODIR_IN: 1823 rc = hdaR3AddStreamIn(pThis , pCfg);1819 rc = hdaR3AddStreamIn(pThisCC, pCfg); 1824 1820 break; 1825 1821 … … 1839 1835 * 1840 1836 * @returns IPRT status code. 1841 * @param pThis Device state.1837 * @param pThisCC The ring-3 HDA device state. 1842 1838 * @param pCfg Stream configuration to use for removing a stream. 1843 1839 */ 1844 static int hdaR3RemoveStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 1845 { 1846 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1840 static int hdaR3RemoveStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg) 1841 { 1847 1842 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1848 1843 … … 1898 1893 && enmMixerCtl != PDMAUDIOMIXERCTL_UNKNOWN) 1899 1894 { 1900 rc = hdaCodecRemoveStream(pThis ->pCodec, enmMixerCtl);1895 rc = hdaCodecRemoveStream(pThisCC->pCodec, enmMixerCtl); 1901 1896 } 1902 1897 … … 1993 1988 HDA_REG(pThis, IRS) = HDA_IRS_ICB; /* busy */ 1994 1989 1995 uint64_t uResp = 0; 1996 int rc2 = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp); 1990 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 1991 uint64_t uResp = 0; 1992 int rc2 = pThisCC->pCodec->pfnLookup(pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp); 1997 1993 if (RT_FAILURE(rc2)) 1998 1994 LogFunc(("Codec lookup failed with rc2=%Rrc\n", rc2)); … … 2028 2024 /* Do a RIRB reset. */ 2029 2025 if (pThis->cbRirbBuf) 2030 { 2031 #ifdef IN_RING3 2032 Assert(pThis->pu64RirbBuf); 2033 RT_BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf); 2034 #else 2035 return VINF_IOM_R3_MMIO_WRITE; 2036 #endif 2037 } 2026 RT_ZERO(pThis->au64RirbBuf); 2038 2027 2039 2028 LogRel2(("HDA: RIRB reset\n")); … … 2057 2046 VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 2058 2047 AssertRC(VBOXSTRICTRC_VAL(rc)); 2048 2049 /** @todo r=bird: Shouldn't we make sure the HDASTATE::u16RespIntCnt is below 2050 * the new RINTCNT value? Or alterantively, make the DMA look take 2051 * this into account instead... I'll do the later for now. */ 2059 2052 2060 2053 LogFunc(("Response interrupt count is now %RU8\n", HDA_REG(pThis, RINTCNT) & 0xFF)); … … 2116 2109 HDA_REG(pThis, RIRBSTS) &= ~(v & u32Value); 2117 2110 2118 return HDA_PROCESS_INTERRUPT(pDevIns, pThis); 2111 HDA_PROCESS_INTERRUPT(pDevIns, pThis); 2112 return VINF_SUCCESS; 2119 2113 } 2120 2114 … … 2123 2117 /** 2124 2118 * Retrieves a corresponding sink for a given mixer control. 2125 * Returns NULL if no sink is found.2126 2119 * 2127 * @return P HDAMIXERSINK2128 * @param pThis HDAstate.2120 * @return Pointer to the sink, NULL if no sink is found. 2121 * @param pThisCC The ring-3 HDA device state. 2129 2122 * @param enmMixerCtl Mixer control to get the corresponding sink for. 2130 2123 */ 2131 static PHDAMIXERSINK hdaR3MixerControlToSink(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)2124 static PHDAMIXERSINK hdaR3MixerControlToSink(PHDASTATER3 pThisCC, PDMAUDIOMIXERCTL enmMixerCtl) 2132 2125 { 2133 2126 PHDAMIXERSINK pSink; … … 2138 2131 /* Fall through is intentional. */ 2139 2132 case PDMAUDIOMIXERCTL_FRONT: 2140 pSink = &pThis ->SinkFront;2133 pSink = &pThisCC->SinkFront; 2141 2134 break; 2142 2135 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2143 2136 case PDMAUDIOMIXERCTL_CENTER_LFE: 2144 pSink = &pThis ->SinkCenterLFE;2137 pSink = &pThisCC->SinkCenterLFE; 2145 2138 break; 2146 2139 case PDMAUDIOMIXERCTL_REAR: 2147 pSink = &pThis ->SinkRear;2140 pSink = &pThisCC->SinkRear; 2148 2141 break; 2149 2142 # endif 2150 2143 case PDMAUDIOMIXERCTL_LINE_IN: 2151 pSink = &pThis ->SinkLineIn;2144 pSink = &pThisCC->SinkLineIn; 2152 2145 break; 2153 2146 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2154 2147 case PDMAUDIOMIXERCTL_MIC_IN: 2155 pSink = &pThis ->SinkMicIn;2148 pSink = &pThisCC->SinkMicIn; 2156 2149 break; 2157 2150 # endif 2158 2151 default: 2152 AssertMsgFailed(("Unhandled mixer control\n")); 2159 2153 pSink = NULL; 2160 AssertMsgFailed(("Unhandled mixer control\n"));2161 2154 break; 2162 2155 } … … 2169 2162 * 2170 2163 * @return IPRT status code. 2171 * @param pThis HDAstate.2164 * @param pThisCC The ring-3 HDA device state. 2172 2165 * @param pDrv HDA driver to add. 2173 2166 */ 2174 static int hdaR3MixerAddDrv(PHDASTATE pThis, PHDADRIVER pDrv)2167 static int hdaR3MixerAddDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv) 2175 2168 { 2176 2169 int rc = VINF_SUCCESS; 2177 2170 2178 PHDASTREAM pStream = hdaR3GetS treamFromSink(pThis, &pThis->SinkLineIn);2171 PHDASTREAM pStream = hdaR3GetSharedStreamFromSink(&pThisCC->SinkLineIn); 2179 2172 if ( pStream 2180 2173 && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg)) 2181 2174 { 2182 int rc2 = hdaR3MixerAddDrvStream(pThis , pThis->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);2175 int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv); 2183 2176 if (RT_SUCCESS(rc)) 2184 2177 rc = rc2; … … 2186 2179 2187 2180 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2188 pStream = hdaR3GetS treamFromSink(pThis, &pThis->SinkMicIn);2181 pStream = hdaR3GetSharedStreamFromSink(&pThisCC->SinkMicIn); 2189 2182 if ( pStream 2190 2183 && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg)) 2191 2184 { 2192 int rc2 = hdaR3MixerAddDrvStream(pThis , pThis->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);2185 int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv); 2193 2186 if (RT_SUCCESS(rc)) 2194 2187 rc = rc2; … … 2196 2189 # endif 2197 2190 2198 pStream = hdaR3GetS treamFromSink(pThis, &pThis->SinkFront);2191 pStream = hdaR3GetSharedStreamFromSink(&pThisCC->SinkFront); 2199 2192 if ( pStream 2200 2193 && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg)) 2201 2194 { 2202 int rc2 = hdaR3MixerAddDrvStream(pThis , pThis->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);2195 int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkFront.pMixSink, &pStream->State.Cfg, pDrv); 2203 2196 if (RT_SUCCESS(rc)) 2204 2197 rc = rc2; … … 2206 2199 2207 2200 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2208 pStream = hdaR3GetS treamFromSink(pThis, &pThis->SinkCenterLFE);2201 pStream = hdaR3GetSharedStreamFromSink(&pThisCC->SinkCenterLFE); 2209 2202 if ( pStream 2210 2203 && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg)) 2211 2204 { 2212 int rc2 = hdaR3MixerAddDrvStream(pThis , pThis->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);2205 int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv); 2213 2206 if (RT_SUCCESS(rc)) 2214 2207 rc = rc2; 2215 2208 } 2216 2209 2217 pStream = hdaR3GetS treamFromSink(pThis, &pThis->SinkRear);2210 pStream = hdaR3GetSharedStreamFromSink(&pThisCC->SinkRear); 2218 2211 if ( pStream 2219 2212 && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg)) 2220 2213 { 2221 int rc2 = hdaR3MixerAddDrvStream(pThis , pThis->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);2214 int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkRear.pMixSink, &pStream->State.Cfg, pDrv); 2222 2215 if (RT_SUCCESS(rc)) 2223 2216 rc = rc2; … … 2232 2225 * associated streams. 2233 2226 * 2234 * @param pThis HDA state. 2235 * @param pDrv HDA driver to remove. 2236 */ 2237 static void hdaR3MixerRemoveDrv(PHDASTATE pThis, PHDADRIVER pDrv) 2238 { 2239 AssertPtrReturnVoid(pThis); 2227 * @param pThisCC The ring-3 HDA device state. 2228 * @param pDrv HDA driver to remove. 2229 */ 2230 static void hdaR3MixerRemoveDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv) 2231 { 2240 2232 AssertPtrReturnVoid(pDrv); 2241 2233 2242 2234 if (pDrv->LineIn.pMixStrm) 2243 2235 { 2244 if (AudioMixerSinkGetRecordingSource(pThis ->SinkLineIn.pMixSink) == pDrv->LineIn.pMixStrm)2245 AudioMixerSinkSetRecordingSource(pThis ->SinkLineIn.pMixSink, NULL);2246 2247 AudioMixerSinkRemoveStream(pThis ->SinkLineIn.pMixSink, pDrv->LineIn.pMixStrm);2236 if (AudioMixerSinkGetRecordingSource(pThisCC->SinkLineIn.pMixSink) == pDrv->LineIn.pMixStrm) 2237 AudioMixerSinkSetRecordingSource(pThisCC->SinkLineIn.pMixSink, NULL); 2238 2239 AudioMixerSinkRemoveStream(pThisCC->SinkLineIn.pMixSink, pDrv->LineIn.pMixStrm); 2248 2240 AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm); 2249 2241 pDrv->LineIn.pMixStrm = NULL; … … 2253 2245 if (pDrv->MicIn.pMixStrm) 2254 2246 { 2255 if (AudioMixerSinkGetRecordingSource(pThis ->SinkMicIn.pMixSink) == pDrv->MicIn.pMixStrm)2256 AudioMixerSinkSetRecordingSource(&pThis ->SinkMicIn.pMixSink, NULL);2257 2258 AudioMixerSinkRemoveStream(pThis ->SinkMicIn.pMixSink, pDrv->MicIn.pMixStrm);2247 if (AudioMixerSinkGetRecordingSource(pThisCC->SinkMicIn.pMixSink) == pDrv->MicIn.pMixStrm) 2248 AudioMixerSinkSetRecordingSource(&pThisCC->SinkMicIn.pMixSink, NULL); 2249 2250 AudioMixerSinkRemoveStream(pThisCC->SinkMicIn.pMixSink, pDrv->MicIn.pMixStrm); 2259 2251 AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm); 2260 2252 pDrv->MicIn.pMixStrm = NULL; … … 2264 2256 if (pDrv->Front.pMixStrm) 2265 2257 { 2266 AudioMixerSinkRemoveStream(pThis ->SinkFront.pMixSink, pDrv->Front.pMixStrm);2258 AudioMixerSinkRemoveStream(pThisCC->SinkFront.pMixSink, pDrv->Front.pMixStrm); 2267 2259 AudioMixerStreamDestroy(pDrv->Front.pMixStrm); 2268 2260 pDrv->Front.pMixStrm = NULL; … … 2272 2264 if (pDrv->CenterLFE.pMixStrm) 2273 2265 { 2274 AudioMixerSinkRemoveStream(pThis ->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);2266 AudioMixerSinkRemoveStream(pThisCC->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm); 2275 2267 AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm); 2276 2268 pDrv->CenterLFE.pMixStrm = NULL; … … 2279 2271 if (pDrv->Rear.pMixStrm) 2280 2272 { 2281 AudioMixerSinkRemoveStream(pThis ->SinkRear.pMixSink, pDrv->Rear.pMixStrm);2273 AudioMixerSinkRemoveStream(pThisCC->SinkRear.pMixSink, pDrv->Rear.pMixStrm); 2282 2274 AudioMixerStreamDestroy(pDrv->Rear.pMixStrm); 2283 2275 pDrv->Rear.pMixStrm = NULL; … … 2292 2284 * 2293 2285 * @returns IPRT status code (ignored by caller). 2294 * @param pThis HDA state.2295 2286 * @param pMixSink Audio mixer sink to add audio streams to. 2296 2287 * @param pCfg Audio stream configuration to use for the audio streams to add. 2297 2288 * @param pDrv Driver stream to add. 2298 2289 */ 2299 static int hdaR3MixerAddDrvStream(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv) 2300 { 2301 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2290 static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv) 2291 { 2302 2292 AssertPtrReturn(pMixSink, VERR_INVALID_POINTER); 2303 2293 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); … … 2417 2407 * 2418 2408 * @returns IPRT status code. 2419 * @param pThis HDAstate.2409 * @param pThisCC The ring-3 HDA device state. 2420 2410 * @param pMixSink Audio mixer sink to add stream to. 2421 2411 * @param pCfg Audio stream configuration to use for the audio streams to add. 2422 2412 */ 2423 static int hdaR3MixerAddDrvStreams(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg) 2424 { 2425 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2413 static int hdaR3MixerAddDrvStreams(PHDASTATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg) 2414 { 2426 2415 AssertPtrReturn(pMixSink, VERR_INVALID_POINTER); 2427 2416 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); … … 2437 2426 2438 2427 PHDADRIVER pDrv; 2439 RTListForEach(&pThis ->lstDrv, pDrv, HDADRIVER, Node)2440 { 2441 int rc2 = hdaR3MixerAddDrvStream(p This, pMixSink, pCfg, pDrv);2428 RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node) 2429 { 2430 int rc2 = hdaR3MixerAddDrvStream(pMixSink, pCfg, pDrv); 2442 2431 if (RT_FAILURE(rc2)) 2443 2432 LogFunc(("Attaching stream failed with %Rrc\n", rc2)); … … 2452 2441 /** 2453 2442 * @interface_method_impl{HDACODEC,pfnCbMixerAddStream} 2454 * 2455 * Adds a new audio stream to a specific mixer control. 2456 * 2457 * Depending on the mixer control the stream then gets assigned to one of the internal 2458 * mixer sinks, which in turn then handle the mixing of all connected streams to that sink. 2459 * 2460 * @return IPRT status code. 2461 * @param pThis HDA state. 2462 * @param enmMixerCtl Mixer control to assign new stream to. 2463 * @param pCfg Stream configuration for the new stream. 2464 */ 2465 static DECLCALLBACK(int) hdaR3MixerAddStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg) 2466 { 2467 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2443 */ 2444 static DECLCALLBACK(int) hdaR3MixerAddStream(PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg) 2445 { 2446 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 2468 2447 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 2469 2470 2448 int rc; 2471 2449 2472 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThis , enmMixerCtl);2450 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThisCC, enmMixerCtl); 2473 2451 if (pSink) 2474 2452 { 2475 rc = hdaR3MixerAddDrvStreams(pThis , pSink->pMixSink, pCfg);2453 rc = hdaR3MixerAddDrvStreams(pThisCC, pSink->pMixSink, pCfg); 2476 2454 2477 2455 AssertPtr(pSink->pMixSink); … … 2487 2465 /** 2488 2466 * @interface_method_impl{HDACODEC,pfnCbMixerRemoveStream} 2489 * 2490 * Removes a specified mixer control from the HDA's mixer. 2491 * 2492 * @return IPRT status code. 2493 * @param pThis HDA state. 2494 * @param enmMixerCtl Mixer control to remove. 2495 * 2496 * @remarks Can be called as a callback by the HDA codec. 2497 */ 2498 static DECLCALLBACK(int) hdaR3MixerRemoveStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl) 2499 { 2500 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2501 2502 int rc; 2503 2504 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThis, enmMixerCtl); 2467 */ 2468 static DECLCALLBACK(int) hdaR3MixerRemoveStream(PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl) 2469 { 2470 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 2471 int rc; 2472 2473 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThisCC, enmMixerCtl); 2505 2474 if (pSink) 2506 2475 { 2507 2476 PHDADRIVER pDrv; 2508 RTListForEach(&pThis ->lstDrv, pDrv, HDADRIVER, Node)2477 RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node) 2509 2478 { 2510 2479 PAUDMIXSTREAM pMixStream = NULL; … … 2568 2537 * @interface_method_impl{HDACODEC,pfnCbMixerControl} 2569 2538 * 2570 * Controls an input / output converter widget, that is, which converter is connected 2571 * to which stream (and channel). 2572 * 2573 * @returns IPRT status code. 2574 * @param pThis HDA State. 2575 * @param enmMixerCtl Mixer control to set SD stream number and channel for. 2576 * @param uSD SD stream number (number + 1) to set. Set to 0 for unassign. 2577 * @param uChannel Channel to set. Only valid if a valid SD stream number is specified. 2578 * 2579 * @remarks Can be called as a callback by the HDA codec. 2580 */ 2581 static DECLCALLBACK(int) hdaR3MixerControl(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel) 2582 { 2539 * @note Is also called directly by the DevHDA code. 2540 */ 2541 static DECLCALLBACK(int) hdaR3MixerControl(PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel) 2542 { 2543 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 2544 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 2583 2545 LogFunc(("enmMixerCtl=%s, uSD=%RU8, uChannel=%RU8\n", DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), uSD, uChannel)); 2584 2546 … … 2606 2568 int rc = VINF_SUCCESS; 2607 2569 2608 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThis , enmMixerCtl);2570 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThisCC, enmMixerCtl); 2609 2571 if (pSink) 2610 2572 { … … 2612 2574 2613 2575 /* If this an output stream, determine the correct SD#. */ 2614 if ( (uSD < HDA_MAX_SDI)2576 if ( uSD < HDA_MAX_SDI 2615 2577 && AudioMixerSinkGetDir(pSink->pMixSink) == AUDMIXSINKDIR_OUTPUT) 2616 {2617 2578 uSD += HDA_MAX_SDI; 2618 } 2579 2580 /* Make 100% sure we got a good stream number before continuing. */ 2581 AssertLogRelReturn(uSD < RT_ELEMENTS(pThisCC->aStreams), VERR_NOT_IMPLEMENTED); 2619 2582 2620 2583 /* Detach the existing stream from the sink. */ 2621 if ( pSink->pStream 2622 && ( pSink->pStream->u8SD != uSD 2623 || pSink->pStream->u8Channel != uChannel) 2584 if ( pSink->pStreamShared 2585 && pSink->pStreamR3 2586 && ( pSink->pStreamShared->u8SD != uSD 2587 || pSink->pStreamShared->u8Channel != uChannel) 2624 2588 ) 2625 2589 { 2626 2590 LogFunc(("Sink '%s' was assigned to stream #%RU8 (channel %RU8) before\n", 2627 pSink->pMixSink->pszName, pSink->pStream ->u8SD, pSink->pStream->u8Channel));2628 2629 hdaR3StreamLock(pSink->pStream );2591 pSink->pMixSink->pszName, pSink->pStreamShared->u8SD, pSink->pStreamShared->u8Channel)); 2592 2593 hdaR3StreamLock(pSink->pStreamR3); 2630 2594 2631 2595 /* Only disable the stream if the stream descriptor # has changed. */ 2632 if (pSink->pStream->u8SD != uSD) 2633 hdaR3StreamEnable(pSink->pStream, false); 2634 2635 pSink->pStream->pMixSink = NULL; 2636 2637 hdaR3StreamUnlock(pSink->pStream); 2638 2639 pSink->pStream = NULL; 2640 } 2641 2642 Assert(uSD < HDA_MAX_STREAMS); 2596 if (pSink->pStreamShared->u8SD != uSD) 2597 hdaR3StreamEnable(pSink->pStreamShared, pSink->pStreamR3, false /*fEnable*/); 2598 2599 pSink->pStreamR3->pMixSink = NULL; 2600 2601 hdaR3StreamUnlock(pSink->pStreamR3); 2602 2603 pSink->pStreamShared = NULL; 2604 pSink->pStreamR3 = NULL; 2605 } 2643 2606 2644 2607 /* Attach the new stream to the sink. 2645 2608 * Enabling the stream will be done by the gust via a separate SDnCTL call then. */ 2646 if (pSink->pStream == NULL)2609 if (pSink->pStreamShared == NULL) 2647 2610 { 2648 2611 LogRel2(("HDA: Setting sink '%s' to stream #%RU8 (channel %RU8), mixer control=%s\n", 2649 2612 pSink->pMixSink->pszName, uSD, uChannel, DrvAudioHlpAudMixerCtlToStr(enmMixerCtl))); 2650 2613 2651 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 2652 if (pStream) 2653 { 2654 hdaR3StreamLock(pStream); 2655 2656 pSink->pStream = pStream; 2657 2658 pStream->u8Channel = uChannel; 2659 pStream->pMixSink = pSink; 2660 2661 hdaR3StreamUnlock(pStream); 2662 2663 rc = VINF_SUCCESS; 2664 } 2665 else 2666 rc = VERR_NOT_IMPLEMENTED; 2614 PHDASTREAMR3 pStreamR3 = &pThisCC->aStreams[uSD]; 2615 PHDASTREAM pStreamShared = &pThis->aStreams[uSD]; 2616 hdaR3StreamLock(pStreamR3); 2617 2618 pSink->pStreamR3 = pStreamR3; 2619 pSink->pStreamShared = pStreamShared; 2620 2621 pStreamShared->u8Channel = uChannel; 2622 pStreamR3->pMixSink = pSink; 2623 2624 hdaR3StreamUnlock(pStreamR3); 2625 rc = VINF_SUCCESS; 2667 2626 } 2668 2627 } … … 2680 2639 /** 2681 2640 * @interface_method_impl{HDACODEC,pfnCbMixerSetVolume} 2682 * 2683 * Sets the volume of a specified mixer control. 2684 * 2685 * @return IPRT status code. 2686 * @param pThis HDA State. 2687 * @param enmMixerCtl Mixer control to set volume for. 2688 * @param pVol Pointer to volume data to set. 2689 * 2690 * @remarks Can be called as a callback by the HDA codec. 2691 */ 2692 static DECLCALLBACK(int) hdaR3MixerSetVolume(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol) 2693 { 2694 int rc; 2695 2696 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThis, enmMixerCtl); 2641 */ 2642 static DECLCALLBACK(int) hdaR3MixerSetVolume(PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol) 2643 { 2644 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 2645 int rc; 2646 2647 PHDAMIXERSINK pSink = hdaR3MixerControlToSink(pThisCC, enmMixerCtl); 2697 2648 if ( pSink 2698 2649 && pSink->pMixSink) … … 2717 2668 static DECLCALLBACK(void) hdaR3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 2718 2669 { 2719 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 2720 PHDASTREAM pStream = (PHDASTREAM)pvUser; 2721 TMTIMERHANDLE hTimer = pStream->hTimer; 2670 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 2671 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 2672 uintptr_t idxStream = (uintptr_t)pvUser; 2673 AssertReturnVoid(idxStream < RT_ELEMENTS(pThis->aStreams)); 2674 PHDASTREAM pStreamShared = &pThis->aStreams[idxStream]; 2675 PHDASTREAMR3 pStreamR3 = &pThisCC->aStreams[idxStream]; 2676 TMTIMERHANDLE hTimer = pStreamShared->hTimer; 2722 2677 RT_NOREF(pTimer); 2723 2678 2724 AssertPtr(pStream);2725 2679 Assert(PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect)); 2726 2680 Assert(PDMDevHlpTimerIsLockOwner(pDevIns, hTimer)); 2727 2681 2728 hdaR3StreamUpdate(pDevIns, p Stream, true /* fInTimer */);2682 hdaR3StreamUpdate(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, true /* fInTimer */); 2729 2683 2730 2684 /* Flag indicating whether to kick the timer again for a new data processing round. */ 2731 2685 bool fSinkActive = false; 2732 if (pStream ->pMixSink)2733 fSinkActive = AudioMixerSinkIsActive(pStream ->pMixSink->pMixSink);2686 if (pStreamR3->pMixSink) 2687 fSinkActive = AudioMixerSinkIsActive(pStreamR3->pMixSink->pMixSink); 2734 2688 2735 2689 if (fSinkActive) 2736 2690 { 2737 2691 uint64_t const tsNow = PDMDevHlpTimerGet(pDevIns, hTimer); /* (For virtual sync this remains the same for the whole callout IIRC) */ 2738 const bool fTimerScheduled = hdaR3StreamTransferIsScheduled(pStream , tsNow);2692 const bool fTimerScheduled = hdaR3StreamTransferIsScheduled(pStreamShared, tsNow); 2739 2693 Log3Func(("fSinksActive=%RTbool, fTimerScheduled=%RTbool\n", fSinkActive, fTimerScheduled)); 2740 2694 if (!fTimerScheduled) 2741 hdaR3TimerSet(pDevIns, pStream , tsNow + PDMDevHlpTimerGetFreq(pDevIns, hTimer) / pThis->uTimerHz,2695 hdaR3TimerSet(pDevIns, pStreamShared, tsNow + PDMDevHlpTimerGetFreq(pDevIns, hTimer) / pThis->uTimerHz, 2742 2696 true /*fForce*/, tsNow /*fixed*/ ); 2743 2697 } … … 2882 2836 * Soft reset of the device triggered via GCTL. 2883 2837 * 2884 * @param pThis HDA state. 2885 * 2886 */ 2887 static void hdaR3GCTLReset(PHDASTATE pThis) 2838 * @param pDevIns The device instance. 2839 * @param pThis The shared HDA device state. 2840 * @param pThisCC The ring-3 HDA device state. 2841 */ 2842 static void hdaR3GCTLReset(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC) 2888 2843 { 2889 2844 LogFlowFuncEnter(); 2890 2845 2891 pThis ->cStreamsActive = 0;2846 pThisCC->cStreamsActive = 0; 2892 2847 2893 2848 HDA_REG(pThis, GCAP) = HDA_MAKE_GCAP(HDA_MAX_SDO, HDA_MAX_SDI, 0, 0, 1); /* see 6.2.1 */ … … 2908 2863 * Stop any audio currently playing and/or recording. 2909 2864 */ 2910 pThis->SinkFront.pStream = NULL; 2911 if (pThis->SinkFront.pMixSink) 2912 AudioMixerSinkReset(pThis->SinkFront.pMixSink); 2865 pThisCC->SinkFront.pStreamShared = NULL; 2866 pThisCC->SinkFront.pStreamR3 = NULL; 2867 if (pThisCC->SinkFront.pMixSink) 2868 AudioMixerSinkReset(pThisCC->SinkFront.pMixSink); 2913 2869 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2914 pThis->SinkMicIn.pStream = NULL; 2915 if (pThis->SinkMicIn.pMixSink) 2916 AudioMixerSinkReset(pThis->SinkMicIn.pMixSink); 2870 pThisCC->SinkMicIn.pStreamShared = NULL; 2871 pThisCC->SinkMicIn.pStreamR3 = NULL; 2872 if (pThisCC->SinkMicIn.pMixSink) 2873 AudioMixerSinkReset(pThisCC->SinkMicIn.pMixSink); 2917 2874 # endif 2918 pThis->SinkLineIn.pStream = NULL; 2919 if (pThis->SinkLineIn.pMixSink) 2920 AudioMixerSinkReset(pThis->SinkLineIn.pMixSink); 2875 pThisCC->SinkLineIn.pStreamShared = NULL; 2876 pThisCC->SinkLineIn.pStreamR3 = NULL; 2877 if (pThisCC->SinkLineIn.pMixSink) 2878 AudioMixerSinkReset(pThisCC->SinkLineIn.pMixSink); 2921 2879 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2922 pThis->SinkCenterLFE = NULL; 2923 if (pThis->SinkCenterLFE.pMixSink) 2924 AudioMixerSinkReset(pThis->SinkCenterLFE.pMixSink); 2925 pThis->SinkRear.pStream = NULL; 2926 if (pThis->SinkRear.pMixSink) 2927 AudioMixerSinkReset(pThis->SinkRear.pMixSink); 2880 pThisCC->SinkCenterLFE = NULL; 2881 if (pThisCC->SinkCenterLFE.pMixSink) 2882 AudioMixerSinkReset(pThisCC->SinkCenterLFE.pMixSink); 2883 pThisCC->SinkRear.pStreamShared = NULL; 2884 pThisCC->SinkRear.pStreamR3 = NULL; 2885 if (pThisCC->SinkRear.pMixSink) 2886 AudioMixerSinkReset(pThisCC->SinkRear.pMixSink); 2928 2887 # endif 2929 2888 … … 2931 2890 * Reset the codec. 2932 2891 */ 2933 if ( pThis ->pCodec2934 && pThis ->pCodec->pfnReset)2935 { 2936 pThis ->pCodec->pfnReset(pThis->pCodec);2892 if ( pThisCC->pCodec 2893 && pThisCC->pCodec->pfnReset) 2894 { 2895 pThisCC->pCodec->pfnReset(pThisCC->pCodec); 2937 2896 } 2938 2897 … … 2944 2903 * These stream numbers can be changed by the guest dynamically lateron. 2945 2904 */ 2905 ASMCompilerBarrier(); /* paranoia */ 2946 2906 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2947 hdaR3MixerControl(p This, PDMAUDIOMIXERCTL_MIC_IN , 1 /* SD0 */, 0 /* Channel */);2907 hdaR3MixerControl(pDevIns, PDMAUDIOMIXERCTL_MIC_IN , 1 /* SD0 */, 0 /* Channel */); 2948 2908 # endif 2949 hdaR3MixerControl(p This, PDMAUDIOMIXERCTL_LINE_IN , 1 /* SD0 */, 0 /* Channel */);2950 2951 hdaR3MixerControl(p This, PDMAUDIOMIXERCTL_FRONT , 5 /* SD4 */, 0 /* Channel */);2909 hdaR3MixerControl(pDevIns, PDMAUDIOMIXERCTL_LINE_IN , 1 /* SD0 */, 0 /* Channel */); 2910 2911 hdaR3MixerControl(pDevIns, PDMAUDIOMIXERCTL_FRONT , 5 /* SD4 */, 0 /* Channel */); 2952 2912 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2953 hdaR3MixerControl(p This, PDMAUDIOMIXERCTL_CENTER_LFE, 5 /* SD4 */, 0 /* Channel */);2954 hdaR3MixerControl(p This, PDMAUDIOMIXERCTL_REAR , 5 /* SD4 */, 0 /* Channel */);2913 hdaR3MixerControl(pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, 5 /* SD4 */, 0 /* Channel */); 2914 hdaR3MixerControl(pDevIns, PDMAUDIOMIXERCTL_REAR , 5 /* SD4 */, 0 /* Channel */); 2955 2915 # endif 2916 ASMCompilerBarrier(); /* paranoia */ 2956 2917 2957 2918 /* Reset CORB. */ 2958 2919 pThis->cbCorbBuf = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE; 2959 RT_ BZERO(pThis->pu32CorbBuf, pThis->cbCorbBuf);2920 RT_ZERO(pThis->au32CorbBuf); 2960 2921 2961 2922 /* Reset RIRB. */ 2962 2923 pThis->cbRirbBuf = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE; 2963 RT_ BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf);2924 RT_ZERO(pThis->au64RirbBuf); 2964 2925 2965 2926 /* Clear our internal response interrupt counter. */ 2966 2927 pThis->u16RespIntCnt = 0; 2967 2928 2968 for ( uint8_t uSD = 0; uSD < HDA_MAX_STREAMS; ++uSD)2969 { 2970 int rc2 = hdaR3StreamEnable(&pThis->aStreams[ uSD], false /* fEnable */);2929 for (size_t idxStream = 0; idxStream < RT_ELEMENTS(pThis->aStreams); idxStream++) 2930 { 2931 int rc2 = hdaR3StreamEnable(&pThis->aStreams[idxStream], &pThisCC->aStreams[idxStream], false /* fEnable */); 2971 2932 if (RT_SUCCESS(rc2)) 2972 2933 { 2973 2934 /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */ 2974 HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_SDCTL_RUN;2975 hdaR3StreamReset(pThis, &pThis->aStreams[uSD], uSD);2935 HDA_STREAM_REG(pThis, CTL, idxStream) &= ~HDA_SDCTL_RUN; 2936 hdaR3StreamReset(pThis, pThisCC, &pThis->aStreams[idxStream], &pThisCC->aStreams[idxStream], (uint8_t)idxStream); 2976 2937 } 2977 2938 } 2978 2939 2979 2940 /* Clear stream tags <-> objects mapping table. */ 2980 RT_ZERO(pThis ->aTags);2941 RT_ZERO(pThisCC->aTags); 2981 2942 2982 2943 /* Emulation of codec "wake up" (HDA spec 5.5.1 and 6.5). */ … … 3426 3387 3427 3388 3428 static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStream )3389 static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3) 3429 3390 { 3430 3391 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; … … 3433 3394 # endif 3434 3395 3435 Log2Func(("[SD%RU8]\n", pStream ->u8SD));3396 Log2Func(("[SD%RU8]\n", pStreamShared->u8SD)); 3436 3397 3437 3398 /* Save stream ID. */ 3438 int rc = pHlp->pfnSSMPutU8(pSSM, pStream->u8SD); 3399 Assert(pStreamShared->u8SD < HDA_MAX_STREAMS); 3400 int rc = pHlp->pfnSSMPutU8(pSSM, pStreamShared->u8SD); 3439 3401 AssertRCReturn(rc, rc); 3440 Assert(pStream->u8SD < HDA_MAX_STREAMS); 3441 3442 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStream->State, sizeof(HDASTREAMSTATE),0 /*fFlags*/, g_aSSMStreamStateFields7, NULL);3402 3403 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStreamShared->State, sizeof(pStreamShared->State), 3404 0 /*fFlags*/, g_aSSMStreamStateFields7, NULL); 3443 3405 AssertRCReturn(rc, rc); 3444 3406 3445 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStream->State.BDLE.Desc, sizeof(HDABDLEDESC), 0 /*fFlags*/, g_aSSMBDLEDescFields7, NULL); 3407 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStreamShared->State.BDLE.Desc, sizeof(pStreamShared->State.BDLE.Desc), 3408 0 /*fFlags*/, g_aSSMBDLEDescFields7, NULL); 3446 3409 AssertRCReturn(rc, rc); 3447 3410 3448 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStream->State.BDLE.State, sizeof(HDABDLESTATE), 0 /*fFlags*/, g_aSSMBDLEStateFields7, NULL); 3411 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStreamShared->State.BDLE.State, sizeof(pStreamShared->State.BDLE.State), 3412 0 /*fFlags*/, g_aSSMBDLEStateFields7, NULL); 3449 3413 AssertRCReturn(rc, rc); 3450 3414 3451 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStream->State.Period, sizeof(HDASTREAMPERIOD), 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL); 3415 rc = pHlp->pfnSSMPutStructEx(pSSM, &pStreamShared->State.Period, sizeof(pStreamShared->State.Period), 3416 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL); 3452 3417 AssertRCReturn(rc, rc); 3453 3418 … … 3455 3420 uint32_t cbCircBufUsed = 0; 3456 3421 3457 if (pStream ->State.pCircBuf)3458 { 3459 cbCircBufSize = (uint32_t)RTCircBufSize(pStream ->State.pCircBuf);3460 cbCircBufUsed = (uint32_t)RTCircBufUsed(pStream ->State.pCircBuf);3422 if (pStreamR3->State.pCircBuf) 3423 { 3424 cbCircBufSize = (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf); 3425 cbCircBufUsed = (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf); 3461 3426 } 3462 3427 … … 3476 3441 * So get the current read offset and serialize the buffer data manually based on that. 3477 3442 */ 3478 size_t const offBuf = RTCircBufOffsetRead(pStream ->State.pCircBuf);3443 size_t const offBuf = RTCircBufOffsetRead(pStreamR3->State.pCircBuf); 3479 3444 void *pvBuf; 3480 3445 size_t cbBuf; 3481 RTCircBufAcquireReadBlock(pStream ->State.pCircBuf, cbCircBufUsed, &pvBuf, &cbBuf);3446 RTCircBufAcquireReadBlock(pStreamR3->State.pCircBuf, cbCircBufUsed, &pvBuf, &cbBuf); 3482 3447 Assert(cbBuf); 3483 3448 if (cbBuf) … … 3491 3456 } 3492 3457 } 3493 RTCircBufReleaseReadBlock(pStream->State.pCircBuf, 0 /* Don't advance read pointer -- see comment above */); 3494 } 3495 3496 Log2Func(("[SD%RU8] LPIB=%RU32, CBL=%RU32, LVI=%RU32\n", 3497 pStream->u8SD, 3498 HDA_STREAM_REG(pThis, LPIB, pStream->u8SD), HDA_STREAM_REG(pThis, CBL, pStream->u8SD), HDA_STREAM_REG(pThis, LVI, pStream->u8SD))); 3458 RTCircBufReleaseReadBlock(pStreamR3->State.pCircBuf, 0 /* Don't advance read pointer -- see comment above */); 3459 } 3460 3461 Log2Func(("[SD%RU8] LPIB=%RU32, CBL=%RU32, LVI=%RU32\n", pStreamR3->u8SD, HDA_STREAM_REG(pThis, LPIB, pStreamShared->u8SD), 3462 HDA_STREAM_REG(pThis, CBL, pStreamShared->u8SD), HDA_STREAM_REG(pThis, LVI, pStreamShared->u8SD))); 3499 3463 3500 3464 #ifdef LOG_ENABLED 3501 hdaR3BDLEDumpAll(p This, pStream->u64BDLBase, pStream->u16LVI + 1);3465 hdaR3BDLEDumpAll(pDevIns, pThis, pStreamShared->u64BDLBase, pStreamShared->u16LVI + 1); 3502 3466 #endif 3503 3467 … … 3510 3474 static DECLCALLBACK(int) hdaR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 3511 3475 { 3512 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3513 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 3476 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3477 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 3478 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 3514 3479 3515 3480 /* Save Codec nodes states. */ 3516 hdaCodecSaveState(pDevIns, pThis ->pCodec, pSSM);3481 hdaCodecSaveState(pDevIns, pThisCC->pCodec, pSSM); 3517 3482 3518 3483 /* Save MMIO registers. */ … … 3530 3495 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 3531 3496 { 3532 int rc = hdaR3SaveStream(pDevIns, pSSM, &pThis->aStreams[i] );3497 int rc = hdaR3SaveStream(pDevIns, pSSM, &pThis->aStreams[i], &pThisCC->aStreams[i]); 3533 3498 AssertRCReturn(rc, rc); 3534 3499 } … … 3541 3506 * 3542 3507 * @param pDevIns The device instance. 3543 * @param pThis Pointer to HDA state. 3544 */ 3545 static int hdaR3LoadExecPost(PPDMDEVINS pDevIns, PHDASTATE pThis) 3546 { 3547 int rc = VINF_SUCCESS; 3508 * @param pThis Pointer to the shared HDA state. 3509 * @param pThisCC Pointer to the ring-3 HDA state. 3510 */ 3511 static int hdaR3LoadExecPost(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC) 3512 { 3513 int rc = VINF_SUCCESS; /** @todo r=bird: Really, what's the point of this? */ 3548 3514 3549 3515 /* 3550 3516 * Enable all previously active streams. 3551 3517 */ 3552 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 3553 { 3554 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, i); 3555 if (pStream) 3556 { 3518 for (size_t i = 0; i < HDA_MAX_STREAMS; i++) 3519 { 3520 PHDASTREAM pStreamShared = &pThis->aStreams[i]; 3521 3522 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_SDCTL_RUN); 3523 if (fActive) 3524 { 3525 PHDASTREAMR3 pStreamR3 = &pThisCC->aStreams[i]; 3526 3557 3527 int rc2; 3558 3559 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_SDCTL_RUN);3560 if (fActive)3561 {3562 3528 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 3563 3564 rc2 = hdaR3StreamAsyncIOCreate(pStream);3565 3566 3567 3568 hdaR3StreamAsyncIOEnable(pStream, true /* fEnable */);3529 /* Make sure to also create the async I/O thread before actually enabling the stream. */ 3530 rc2 = hdaR3StreamAsyncIOCreate(pStreamR3); 3531 AssertRC(rc2); 3532 3533 /* ... and enabling it. */ 3534 hdaR3StreamAsyncIOEnable(pStreamR3, true /* fEnable */); 3569 3535 #endif 3570 3571 hdaR3StreamPeriodResume(&pStream->State.Period);3572 3573 3574 rc2 = hdaR3StreamEnable(pStream, true /* fEnable */);3575 3576 3577 3578 rc2 = hdaR3AddStream(pThis, &pStream->State.Cfg);3579 3536 /* Resume the stream's period. */ 3537 hdaR3StreamPeriodResume(&pStreamShared->State.Period); 3538 3539 /* (Re-)enable the stream. */ 3540 rc2 = hdaR3StreamEnable(pStreamShared, pStreamR3, true /* fEnable */); 3541 AssertRC(rc2); 3542 3543 /* Add the stream to the device setup. */ 3544 rc2 = hdaR3AddStream(pThisCC, &pStreamShared->State.Cfg); 3545 AssertRC(rc2); 3580 3546 3581 3547 #ifdef HDA_USE_DMA_ACCESS_HANDLER 3582 3583 hdaR3StreamRegisterDMAHandlers(pThis, pStream);3548 /* (Re-)install the DMA handler. */ 3549 hdaR3StreamRegisterDMAHandlers(pThis, pStreamShared); 3584 3550 #endif 3585 if (hdaR3StreamTransferIsScheduled(pStream, PDMDevHlpTimerGet(pDevIns, pStream->hTimer))) 3586 hdaR3TimerSet(pDevIns, pStream, hdaR3StreamTransferGetNext(pStream), true /*fForce*/, 0 /*tsNow*/); 3587 3588 /* Also keep track of the currently active streams. */ 3589 pThis->cStreamsActive++; 3590 } 3551 if (hdaR3StreamTransferIsScheduled(pStreamShared, PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer))) 3552 hdaR3TimerSet(pDevIns, pStreamShared, hdaR3StreamTransferGetNext(pStreamShared), true /*fForce*/, 0 /*tsNow*/); 3553 3554 /* Also keep track of the currently active streams. */ 3555 pThisCC->cStreamsActive++; 3591 3556 } 3592 3557 } … … 3601 3566 * 3602 3567 * @param pDevIns The device instance. 3603 * @param pThis Pointer to HDA state. 3568 * @param pThis Pointer to the shared HDA state. 3569 * @param pThisCC Pointer to the ring-3 HDA state. 3604 3570 * @param pSSM Pointer to SSM handle. 3605 3571 * @param uVersion Saved state version to load. 3606 3572 */ 3607 static int hdaR3LoadExecLegacy(PPDMDEVINS pDevIns, PHDASTATE pThis, P SSMHANDLE pSSM, uint32_t uVersion)3573 static int hdaR3LoadExecLegacy(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, PSSMHANDLE pSSM, uint32_t uVersion) 3608 3574 { 3609 3575 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; … … 3694 3660 3695 3661 /* Output */ 3696 PHDASTREAM pStream = &pThis->aStreams[4];3697 rc = hdaR3Stream Init(pDevIns, pStream, 4 /* Stream descriptor, hardcoded */);3662 PHDASTREAM pStreamShared = &pThis->aStreams[4]; 3663 rc = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, &pThisCC->aStreams[4], 4 /* Stream descriptor, hardcoded */); 3698 3664 AssertRCReturn(rc, rc); 3699 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE, sizeof(pStream->State.BDLE),3665 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE, sizeof(pStreamShared->State.BDLE), 3700 3666 0 /* fFlags */, g_aSSMStreamBdleFields1234, pDevIns); 3701 3667 AssertRCReturn(rc, rc); 3702 pStream ->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;3668 pStreamShared->State.uCurBDLE = pStreamShared->State.BDLE.State.u32BDLIndex; 3703 3669 3704 3670 /* Microphone-In */ 3705 pStream = &pThis->aStreams[2];3706 rc = hdaR3Stream Init(pDevIns, pStream, 2 /* Stream descriptor, hardcoded */);3671 pStreamShared = &pThis->aStreams[2]; 3672 rc = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, &pThisCC->aStreams[2], 2 /* Stream descriptor, hardcoded */); 3707 3673 AssertRCReturn(rc, rc); 3708 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE, sizeof(pStream->State.BDLE),3674 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE, sizeof(pStreamShared->State.BDLE), 3709 3675 0 /* fFlags */, g_aSSMStreamBdleFields1234, pDevIns); 3710 3676 AssertRCReturn(rc, rc); 3711 pStream ->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;3677 pStreamShared->State.uCurBDLE = pStreamShared->State.BDLE.State.u32BDLIndex; 3712 3678 3713 3679 /* Line-In */ 3714 pStream = &pThis->aStreams[0];3715 rc = hdaR3Stream Init(pDevIns, pStream, 0 /* Stream descriptor, hardcoded */);3680 pStreamShared = &pThis->aStreams[0]; 3681 rc = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, &pThisCC->aStreams[0], 0 /* Stream descriptor, hardcoded */); 3716 3682 AssertRCReturn(rc, rc); 3717 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE, sizeof(pStream->State.BDLE),3683 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE, sizeof(pStreamShared->State.BDLE), 3718 3684 0 /* fFlags */, g_aSSMStreamBdleFields1234, pDevIns); 3719 3685 AssertRCReturn(rc, rc); 3720 pStream ->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;3686 pStreamShared->State.uCurBDLE = pStreamShared->State.BDLE.State.u32BDLIndex; 3721 3687 break; 3722 3688 } … … 3743 3709 AssertRCReturn(rc, rc); 3744 3710 3745 HDASTREAM StreamDummy;3746 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, idStream);3747 if (!pStream)3748 {3749 pStream = &StreamDummy;3750 LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping loading it ...\n", idStream));3751 }3752 3753 rc = hdaR3Stream Init(pDevIns, pStream, idStream);3711 HDASTREAM StreamDummyShared; 3712 HDASTREAMR3 StreamDummyR3; 3713 PHDASTREAM pStreamShared = idStream < RT_ELEMENTS(pThis->aStreams) ? &pThis->aStreams[idStream] : &StreamDummyShared; 3714 PHDASTREAMR3 pStreamR3 = idStream < RT_ELEMENTS(pThisCC->aStreams) ? &pThisCC->aStreams[idStream] : &StreamDummyR3; 3715 AssertLogRelMsgStmt(idStream < RT_ELEMENTS(pThisCC->aStreams), 3716 ("HDA stream ID=%RU8 not supported, skipping loadingit ...\n", idStream), 3717 RT_ZERO(StreamDummyShared); RT_ZERO(StreamDummyR3)); 3718 3719 rc = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, pStreamR3, idStream); 3754 3720 if (RT_FAILURE(rc)) 3755 3721 { 3756 LogRel(("HDA: Stream #%RU32: Initializationof stream %RU8 failed, rc=%Rrc\n", i, idStream, rc));3722 LogRel(("HDA: Stream #%RU32: Setting up of stream %RU8 failed, rc=%Rrc\n", i, idStream, rc)); 3757 3723 break; 3758 3724 } … … 3779 3745 rc = pHlp->pfnSSMGetStructEx(pSSM, &Tmp, sizeof(Tmp), 0 /* fFlags */, g_aV5State1Fields, NULL); 3780 3746 AssertRCReturn(rc, rc); 3781 pStream ->State.uCurBDLE = Tmp.uCurBDLE;3747 pStreamShared->State.uCurBDLE = Tmp.uCurBDLE; 3782 3748 3783 3749 for (uint16_t a = 0; a < Tmp.cBLDEs; a++) … … 3792 3758 rc = pHlp->pfnSSMGetStructEx(pSSM, &Tmp, sizeof(Tmp), 0 /* fFlags */, g_aV5State2Fields, NULL); 3793 3759 AssertRCReturn(rc, rc); 3794 if (Tmp.u32BDLEIndex == pStream ->State.uCurBDLE)3760 if (Tmp.u32BDLEIndex == pStreamShared->State.uCurBDLE) 3795 3761 { 3796 pStream ->State.BDLE.State.cbBelowFIFOW = Tmp.cbBelowFIFOW;3797 pStream ->State.BDLE.State.u32BufOff = Tmp.u32BufOff;3762 pStreamShared->State.BDLE.State.cbBelowFIFOW = Tmp.cbBelowFIFOW; 3763 pStreamShared->State.BDLE.State.u32BufOff = Tmp.u32BufOff; 3798 3764 } 3799 3765 } … … 3801 3767 else 3802 3768 { 3803 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State, sizeof(HDASTREAMSTATE),3769 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State, sizeof(HDASTREAMSTATE), 3804 3770 0 /* fFlags */, g_aSSMStreamStateFields6, NULL); 3805 3771 AssertRCReturn(rc, rc); 3806 3772 3807 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE.Desc, sizeof(pStream->State.BDLE.Desc),3773 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE.Desc, sizeof(pStreamShared->State.BDLE.Desc), 3808 3774 0 /* fFlags */, g_aSSMBDLEDescFields6, pDevIns); 3809 3775 AssertRCReturn(rc, rc); 3810 3776 3811 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE.State, sizeof(HDABDLESTATE),3777 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE.State, sizeof(HDABDLESTATE), 3812 3778 0 /* fFlags */, g_aSSMBDLEStateFields6, NULL); 3813 3779 AssertRCReturn(rc, rc); … … 3816 3782 HDA_STREAM_REG(pThis, CBL, idStream), HDA_STREAM_REG(pThis, LVI, idStream))); 3817 3783 #ifdef LOG_ENABLED 3818 hdaR3BDLEDumpAll(p This, pStream->u64BDLBase, pStream->u16LVI + 1);3784 hdaR3BDLEDumpAll(pDevIns, pThis, pStreamShared->u64BDLBase, pStreamShared->u16LVI + 1); 3819 3785 #endif 3820 3786 } … … 3833 3799 static DECLCALLBACK(int) hdaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 3834 3800 { 3835 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3836 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 3801 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3802 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 3803 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 3837 3804 3838 3805 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass); … … 3843 3810 * Load Codec nodes states. 3844 3811 */ 3845 int rc = hdaCodecLoadState(pDevIns, pThis ->pCodec, pSSM, uVersion);3812 int rc = hdaCodecLoadState(pDevIns, pThisCC->pCodec, pSSM, uVersion); 3846 3813 if (RT_FAILURE(rc)) 3847 3814 { … … 3852 3819 if (uVersion <= HDA_SAVED_STATE_VERSION_6) /* Handle older saved states? */ 3853 3820 { 3854 rc = hdaR3LoadExecLegacy(pDevIns, pThis, p SSM, uVersion);3821 rc = hdaR3LoadExecLegacy(pDevIns, pThis, pThisCC, pSSM, uVersion); 3855 3822 if (RT_SUCCESS(rc)) 3856 rc = hdaR3LoadExecPost(pDevIns, pThis );3823 rc = hdaR3LoadExecPost(pDevIns, pThis, pThisCC); 3857 3824 return rc; 3858 3825 } … … 3918 3885 AssertRCReturn(rc, rc); 3919 3886 3920 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, idStream); 3921 HDASTREAM StreamDummy; 3922 3923 if (!pStream) 3924 { 3925 RT_ZERO(StreamDummy); 3926 pStream = &StreamDummy; 3927 LogRel2(("HDA: Warning: Loading of stream #%RU8 not supported, skipping to load ...\n", idStream)); 3928 } 3929 3930 rc = hdaR3StreamInit(pDevIns, pStream, idStream); 3887 HDASTREAM StreamDummyShared; 3888 HDASTREAMR3 StreamDummyR3; 3889 PHDASTREAM pStreamShared = idStream < RT_ELEMENTS(pThis->aStreams) ? &pThis->aStreams[idStream] : &StreamDummyShared; 3890 PHDASTREAMR3 pStreamR3 = idStream < RT_ELEMENTS(pThisCC->aStreams) ? &pThisCC->aStreams[idStream] : &StreamDummyR3; 3891 AssertLogRelMsgStmt(idStream < RT_ELEMENTS(pThisCC->aStreams), 3892 ("HDA stream ID=%RU8 not supported, skipping loadingit ...\n", idStream), 3893 RT_ZERO(StreamDummyShared); RT_ZERO(StreamDummyR3)); 3894 3895 rc = hdaR3StreamSetUp(pDevIns, pThis, pStreamShared, pStreamR3, idStream); 3931 3896 if (RT_FAILURE(rc)) 3932 3897 { 3933 LogRel(("HDA: Stream #%RU8: Loading initializationfailed, rc=%Rrc\n", idStream, rc));3898 LogRel(("HDA: Stream #%RU8: Setting up failed, rc=%Rrc\n", idStream, rc)); 3934 3899 /* Continue. */ 3935 3900 } 3936 3901 3937 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State, sizeof(HDASTREAMSTATE),3902 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State, sizeof(HDASTREAMSTATE), 3938 3903 0 /* fFlags */, g_aSSMStreamStateFields7, NULL); 3939 3904 AssertRCReturn(rc, rc); … … 3942 3907 * Load BDLEs (Buffer Descriptor List Entries) and DMA counters. 3943 3908 */ 3944 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE.Desc, sizeof(HDABDLEDESC),3909 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE.Desc, sizeof(HDABDLEDESC), 3945 3910 0 /* fFlags */, g_aSSMBDLEDescFields7, NULL); 3946 3911 AssertRCReturn(rc, rc); 3947 3912 3948 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream ->State.BDLE.State, sizeof(HDABDLESTATE),3913 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.BDLE.State, sizeof(HDABDLESTATE), 3949 3914 0 /* fFlags */, g_aSSMBDLEStateFields7, NULL); 3950 3915 AssertRCReturn(rc, rc); 3951 3916 3952 Log2Func(("[SD%RU8] %R[bdle]\n", pStream ->u8SD, &pStream->State.BDLE));3917 Log2Func(("[SD%RU8] %R[bdle]\n", pStreamShared->u8SD, &pStreamShared->State.BDLE)); 3953 3918 3954 3919 /* 3955 3920 * Load period state. 3956 3921 */ 3957 hdaR3StreamPeriodInit(&pStream->State.Period, pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.Cfg); 3958 3959 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream->State.Period, sizeof(HDASTREAMPERIOD), 3922 hdaR3StreamPeriodInit(&pStreamShared->State.Period, pStreamShared->u8SD, pStreamShared->u16LVI, 3923 pStreamShared->u32CBL, &pStreamShared->State.Cfg); 3924 3925 rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.Period, sizeof(pStreamShared->State.Period), 3960 3926 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL); 3961 3927 AssertRCReturn(rc, rc); … … 3983 3949 3984 3950 /* Do we need to cre-create the circular buffer do fit the data size? */ 3985 if ( pStream ->State.pCircBuf3986 && cbCircBufSize != (uint32_t)RTCircBufSize(pStream ->State.pCircBuf))3951 if ( pStreamR3->State.pCircBuf 3952 && cbCircBufSize != (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf)) 3987 3953 { 3988 RTCircBufDestroy(pStream ->State.pCircBuf);3989 pStream ->State.pCircBuf = NULL;3954 RTCircBufDestroy(pStreamR3->State.pCircBuf); 3955 pStreamR3->State.pCircBuf = NULL; 3990 3956 } 3991 3957 3992 rc = RTCircBufCreate(&pStream ->State.pCircBuf, cbCircBufSize);3958 rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBufSize); 3993 3959 AssertRCReturn(rc, rc); 3994 3960 … … 3997 3963 void *pvBuf; 3998 3964 size_t cbBuf; 3999 RTCircBufAcquireWriteBlock(pStream ->State.pCircBuf, cbCircBufUsed, &pvBuf, &cbBuf);3965 RTCircBufAcquireWriteBlock(pStreamR3->State.pCircBuf, cbCircBufUsed, &pvBuf, &cbBuf); 4000 3966 4001 3967 AssertLogRelMsgReturn(cbBuf == cbCircBufUsed, ("cbBuf=%zu cbCircBufUsed=%zu\n", cbBuf, cbCircBufUsed), … … 4004 3970 AssertRCReturn(rc, rc); 4005 3971 4006 RTCircBufReleaseWriteBlock(pStream ->State.pCircBuf, cbBuf);3972 RTCircBufReleaseWriteBlock(pStreamR3->State.pCircBuf, cbBuf); 4007 3973 4008 3974 Assert(cbBuf == cbCircBufUsed); … … 4013 3979 HDA_STREAM_REG(pThis, CBL, idStream), HDA_STREAM_REG(pThis, LVI, idStream))); 4014 3980 #ifdef LOG_ENABLED 4015 hdaR3BDLEDumpAll(p This, pStream->u64BDLBase, pStream->u16LVI + 1);3981 hdaR3BDLEDumpAll(pDevIns, pThis, pStreamShared->u64BDLBase, pStreamShared->u16LVI + 1); 4016 3982 #endif 4017 3983 /** @todo (Re-)initialize active periods? */ … … 4019 3985 } /* for cStreams */ 4020 3986 4021 rc = hdaR3LoadExecPost(pDevIns, pThis );3987 rc = hdaR3LoadExecPost(pDevIns, pThis, pThisCC); 4022 3988 AssertRC(rc); 4023 3989 … … 4170 4136 } 4171 4137 4172 static void hdaR3DbgPrintBDLE(P HDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx)4138 static void hdaR3DbgPrintBDLE(PPDMDEVINS pDevIns, PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx) 4173 4139 { 4174 4140 Assert( pThis … … 4197 4163 { 4198 4164 HDABDLEDESC bd; 4199 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), u64BaseDMA + i * sizeof(HDABDLEDESC), &bd, sizeof(bd));4165 PDMDevHlpPhysRead(pDevIns, u64BaseDMA + i * sizeof(HDABDLEDESC), &bd, sizeof(bd)); 4200 4166 4201 4167 pHlp->pfnPrintf(pHlp, "\t\t%s #%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n", … … 4220 4186 { 4221 4187 uint32_t uDMACnt; 4222 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)),4188 PDMDevHlpPhysRead(pDevIns, (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)), 4223 4189 &uDMACnt, sizeof(uDMACnt)); 4224 4190 … … 4256 4222 int iHdaStreamdex = hdaR3DbgLookupStrmIdx(pThis, pszArgs); 4257 4223 if (iHdaStreamdex != -1) 4258 hdaR3DbgPrintBDLE(p This, pHlp, iHdaStreamdex);4224 hdaR3DbgPrintBDLE(pDevIns, pThis, pHlp, iHdaStreamdex); 4259 4225 else 4260 4226 for (iHdaStreamdex = 0; iHdaStreamdex < HDA_MAX_STREAMS; ++iHdaStreamdex) 4261 hdaR3DbgPrintBDLE(p This, pHlp, iHdaStreamdex);4227 hdaR3DbgPrintBDLE(pDevIns, pThis, pHlp, iHdaStreamdex); 4262 4228 } 4263 4229 … … 4267 4233 static DECLCALLBACK(void) hdaR3DbgInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4268 4234 { 4269 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);4270 4271 if (pThis ->pCodec->pfnDbgListNodes)4272 pThis ->pCodec->pfnDbgListNodes(pThis->pCodec, pHlp, pszArgs);4235 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4236 4237 if (pThisCC->pCodec->pfnDbgListNodes) 4238 pThisCC->pCodec->pfnDbgListNodes(pThisCC->pCodec, pHlp, pszArgs); 4273 4239 else 4274 4240 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n"); … … 4280 4246 static DECLCALLBACK(void) hdaR3DbgInfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4281 4247 { 4282 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);4283 4284 if (pThis ->pCodec->pfnDbgSelector)4285 pThis ->pCodec->pfnDbgSelector(pThis->pCodec, pHlp, pszArgs);4248 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4249 4250 if (pThisCC->pCodec->pfnDbgSelector) 4251 pThisCC->pCodec->pfnDbgSelector(pThisCC->pCodec, pHlp, pszArgs); 4286 4252 else 4287 4253 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n"); … … 4293 4259 static DECLCALLBACK(void) hdaR3DbgInfoMixer(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4294 4260 { 4295 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);4296 4297 if (pThis ->pMixer)4298 AudioMixerDebug(pThis ->pMixer, pHlp, pszArgs);4261 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4262 4263 if (pThisCC->pMixer) 4264 AudioMixerDebug(pThisCC->pMixer, pHlp, pszArgs); 4299 4265 else 4300 4266 pHlp->pfnPrintf(pHlp, "Mixer not available\n"); … … 4311 4277 static DECLCALLBACK(void *) hdaR3QueryInterface(struct PDMIBASE *pInterface, const char *pszIID) 4312 4278 { 4313 PHDASTATE pThis = RT_FROM_MEMBER(pInterface, HDASTATE, IBase); 4314 Assert(&pThis->IBase == pInterface); 4315 4316 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase); 4279 PHDASTATER3 pThisCC = RT_FROM_MEMBER(pInterface, HDASTATER3, IBase); 4280 4281 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase); 4317 4282 return NULL; 4318 4283 } … … 4331 4296 * 4332 4297 * @returns VBox status code. 4333 * @param pThis HDA state. 4298 * @param pDevIns The device instance. 4299 * @param pThis The shared HDA device state. 4300 * @param pThisR3 The ring-3 HDA device state. 4334 4301 * @param uLUN The logical unit which is being detached. 4335 4302 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 4336 4303 * @param ppDrv Attached driver instance on success. Optional. 4337 4304 */ 4338 static int hdaR3AttachInternal(P HDASTATE pThis, unsigned uLUN, uint32_t fFlags, PHDADRIVER *ppDrv)4305 static int hdaR3AttachInternal(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, unsigned uLUN, uint32_t fFlags, PHDADRIVER *ppDrv) 4339 4306 { 4340 4307 RT_NOREF(fFlags); … … 4348 4315 4349 4316 PPDMIBASE pDrvBase; 4350 int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN, 4351 &pThis->IBase, &pDrvBase, pszDesc); 4317 int rc = PDMDevHlpDriverAttach(pDevIns, uLUN, &pThisCC->IBase, &pDrvBase, pszDesc); 4352 4318 if (RT_SUCCESS(rc)) 4353 4319 { … … 4355 4321 if (pDrv) 4356 4322 { 4357 pDrv->pDrvBase = pDrvBase; 4358 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR); 4323 pDrv->pDrvBase = pDrvBase; 4324 pDrv->pHDAStateShared = pThis; 4325 pDrv->pHDAStateR3 = pThisCC; 4326 pDrv->uLUN = uLUN; 4327 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR); 4359 4328 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc)); 4360 pDrv->pHDAState = pThis;4361 pDrv->uLUN = uLUN;4362 4329 4363 4330 /* … … 4373 4340 if (!pDrv->fAttached) 4374 4341 { 4375 RTListAppend(&pThis ->lstDrv, &pDrv->Node);4342 RTListAppend(&pThisCC->lstDrv, &pDrv->Node); 4376 4343 pDrv->fAttached = true; 4377 4344 } … … 4404 4371 * 4405 4372 * @returns VBox status code. 4406 * @param pThis HDAstate.4373 * @param pThisR3 The ring-3 HDA device state. 4407 4374 * @param pDrv Driver to detach from device. 4408 4375 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 4409 4376 */ 4410 static int hdaR3DetachInternal(PHDASTATE pThis, PHDADRIVER pDrv, uint32_t fFlags)4377 static int hdaR3DetachInternal(PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags) 4411 4378 { 4412 4379 RT_NOREF(fFlags); … … 4414 4381 /* First, remove the driver from our list and destory it's associated streams. 4415 4382 * This also will un-set the driver as a recording source (if associated). */ 4416 hdaR3MixerRemoveDrv(pThis , pDrv);4383 hdaR3MixerRemoveDrv(pThisCC, pDrv); 4417 4384 4418 4385 /* Next, search backwards for a capable (attached) driver which now will be the 4419 4386 * new recording source. */ 4420 4387 PHDADRIVER pDrvCur; 4421 RTListForEachReverse(&pThis ->lstDrv, pDrvCur, HDADRIVER, Node)4388 RTListForEachReverse(&pThisCC->lstDrv, pDrvCur, HDADRIVER, Node) 4422 4389 { 4423 4390 if (!pDrvCur->pConnector) … … 4435 4402 && pDrvStrm->pMixStrm) 4436 4403 { 4437 rc2 = AudioMixerSinkSetRecordingSource(pThis ->SinkMicIn.pMixSink, pDrvStrm->pMixStrm);4404 rc2 = AudioMixerSinkSetRecordingSource(pThisCC->SinkMicIn.pMixSink, pDrvStrm->pMixStrm); 4438 4405 if (RT_SUCCESS(rc2)) 4439 4406 LogRel2(("HDA: Set new recording source for 'Mic In' to '%s'\n", Cfg.szName)); … … 4444 4411 && pDrvStrm->pMixStrm) 4445 4412 { 4446 rc2 = AudioMixerSinkSetRecordingSource(pThis ->SinkLineIn.pMixSink, pDrvStrm->pMixStrm);4413 rc2 = AudioMixerSinkSetRecordingSource(pThisCC->SinkLineIn.pMixSink, pDrvStrm->pMixStrm); 4447 4414 if (RT_SUCCESS(rc2)) 4448 4415 LogRel2(("HDA: Set new recording source for 'Line In' to '%s'\n", Cfg.szName)); … … 4459 4426 static DECLCALLBACK(int) hdaR3Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 4460 4427 { 4461 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4428 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4429 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4462 4430 4463 4431 DEVHDA_LOCK_RETURN(pDevIns, pThis, VERR_IGNORED); … … 4466 4434 4467 4435 PHDADRIVER pDrv; 4468 int rc2 = hdaR3AttachInternal(p This, uLUN, fFlags, &pDrv);4436 int rc2 = hdaR3AttachInternal(pDevIns, pThis, pThisCC, uLUN, fFlags, &pDrv); 4469 4437 if (RT_SUCCESS(rc2)) 4470 rc2 = hdaR3MixerAddDrv(pThis , pDrv);4438 rc2 = hdaR3MixerAddDrv(pThisCC, pDrv); 4471 4439 4472 4440 if (RT_FAILURE(rc2)) … … 4483 4451 static DECLCALLBACK(void) hdaR3Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 4484 4452 { 4485 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4453 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4454 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4486 4455 4487 4456 DEVHDA_LOCK(pDevIns, pThis); … … 4490 4459 4491 4460 PHDADRIVER pDrv, pDrvNext; 4492 RTListForEachSafe(&pThis ->lstDrv, pDrv, pDrvNext, HDADRIVER, Node)4461 RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, HDADRIVER, Node) 4493 4462 { 4494 4463 if (pDrv->uLUN == uLUN) 4495 4464 { 4496 int rc2 = hdaR3DetachInternal(pThis , pDrv, fFlags);4465 int rc2 = hdaR3DetachInternal(pThisCC, pDrv, fFlags); 4497 4466 if (RT_SUCCESS(rc2)) 4498 4467 { … … 4515 4484 static DECLCALLBACK(void) hdaR3PowerOff(PPDMDEVINS pDevIns) 4516 4485 { 4517 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4486 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4487 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4518 4488 4519 4489 DEVHDA_LOCK_RETURN_VOID(pDevIns, pThis); … … 4522 4492 4523 4493 /* Ditto goes for the codec, which in turn uses the mixer. */ 4524 hdaCodecPowerOff(pThis ->pCodec);4494 hdaCodecPowerOff(pThisCC->pCodec); 4525 4495 4526 4496 /* … … 4529 4499 * PDM audio streams it maintains. 4530 4500 */ 4531 if (pThis ->pMixer)4532 { 4533 AudioMixerDestroy(pThis ->pMixer);4534 pThis ->pMixer = NULL;4501 if (pThisCC->pMixer) 4502 { 4503 AudioMixerDestroy(pThisCC->pMixer); 4504 pThisCC->pMixer = NULL; 4535 4505 } 4536 4506 … … 4542 4512 * 4543 4513 * @returns VBox status code. 4514 * @param pDevIns The device instance. 4515 * @param pThis The shared HDA device state. 4516 * @param pThisCC The ring-3 HDA device state. 4544 4517 * @param pThis Device instance. 4545 4518 * @param iLun The logical unit which is being replaced. 4546 4519 */ 4547 static int hdaR3ReconfigLunWithNullAudio(P HDASTATE pThis, unsigned iLun)4548 { 4549 int rc = PDMDevHlpDriverReconfigure2(p This->pDevInsR3, iLun, "AUDIO", "NullAudio");4520 static int hdaR3ReconfigLunWithNullAudio(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, unsigned iLun) 4521 { 4522 int rc = PDMDevHlpDriverReconfigure2(pDevIns, iLun, "AUDIO", "NullAudio"); 4550 4523 if (RT_SUCCESS(rc)) 4551 rc = hdaR3AttachInternal(p This, iLun, 0 /* fFlags */, NULL /* ppDrv */);4524 rc = hdaR3AttachInternal(pDevIns, pThis, pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4552 4525 LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc)); 4553 4526 return rc; … … 4560 4533 static DECLCALLBACK(void) hdaR3Reset(PPDMDEVINS pDevIns) 4561 4534 { 4562 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4535 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4536 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4563 4537 4564 4538 LogFlowFuncEnter(); … … 4572 4546 HDA_REG(pThis, WAKEEN) = 0x0; 4573 4547 4574 hdaR3GCTLReset(p This);4548 hdaR3GCTLReset(pDevIns, pThis, pThisCC); 4575 4549 4576 4550 /* Indicate that HDA is not in reset. The firmware is supposed to (un)reset HDA, … … 4589 4563 { 4590 4564 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); /* this shall come first */ 4591 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4565 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4566 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4592 4567 DEVHDA_LOCK(pDevIns, pThis); /** @todo r=bird: this will fail on early constructor failure. */ 4593 4568 4594 4569 PHDADRIVER pDrv; 4595 while (!RTListIsEmpty(&pThis ->lstDrv))4596 { 4597 pDrv = RTListGetFirst(&pThis ->lstDrv, HDADRIVER, Node);4570 while (!RTListIsEmpty(&pThisCC->lstDrv)) 4571 { 4572 pDrv = RTListGetFirst(&pThisCC->lstDrv, HDADRIVER, Node); 4598 4573 4599 4574 RTListNodeRemove(&pDrv->Node); … … 4601 4576 } 4602 4577 4603 if (pThis->pCodec) 4604 { 4605 hdaCodecDestruct(pThis->pCodec); 4606 4607 RTMemFree(pThis->pCodec); 4608 pThis->pCodec = NULL; 4609 } 4610 4611 RTMemFree(pThis->pu32CorbBuf); 4612 pThis->pu32CorbBuf = NULL; 4613 4614 RTMemFree(pThis->pu64RirbBuf); 4615 pThis->pu64RirbBuf = NULL; 4578 if (pThisCC->pCodec) 4579 { 4580 hdaCodecDestruct(pThisCC->pCodec); 4581 4582 RTMemFree(pThisCC->pCodec); 4583 pThisCC->pCodec = NULL; 4584 } 4616 4585 4617 4586 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 4618 hdaR3StreamDestroy(&pThis->aStreams[i] );4587 hdaR3StreamDestroy(&pThis->aStreams[i], &pThisCC->aStreams[i]); 4619 4588 4620 4589 DEVHDA_UNLOCK(pDevIns, pThis); … … 4630 4599 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */ 4631 4600 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 4601 PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3); 4632 4602 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 4633 4603 Assert(iInstance == 0); RT_NOREF(iInstance); … … 4637 4607 */ 4638 4608 pThis->uAlignmentCheckMagic = HDASTATE_ALIGNMENT_CHECK_MAGIC; 4639 RTListInit(&pThis->lstDrv); 4609 RTListInit(&pThisCC->lstDrv); 4610 pThis->cbCorbBuf = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE; 4611 pThis->cbRirbBuf = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE; 4612 4640 4613 /** @todo r=bird: There are probably other things which should be 4641 4614 * initialized here before we start failing. */ … … 4670 4643 LogRel(("HDA: Using custom position adjustment (%RU16 audio frames)\n", pThis->cPosAdjustFrames)); 4671 4644 4672 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThis ->Dbg.fEnabled, false);4645 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThisCC->Dbg.fEnabled, false); 4673 4646 if (RT_FAILURE(rc)) 4674 4647 return PDMDEV_SET_ERROR(pDevIns, rc, 4675 4648 N_("HDA configuration error: failed to read debugging enabled flag as boolean")); 4676 4649 4677 rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThis ->Dbg.szOutPath, sizeof(pThis->Dbg.szOutPath),4650 rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThisCC->Dbg.szOutPath, sizeof(pThisCC->Dbg.szOutPath), 4678 4651 VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH); 4679 4652 if (RT_FAILURE(rc)) … … 4681 4654 N_("HDA configuration error: failed to read debugging output path flag as string")); 4682 4655 4683 if (pThis ->Dbg.fEnabled)4684 LogRel2(("HDA: Debug output will be saved to '%s'\n", pThis ->Dbg.szOutPath));4656 if (pThisCC->Dbg.fEnabled) 4657 LogRel2(("HDA: Debug output will be saved to '%s'\n", pThisCC->Dbg.szOutPath)); 4685 4658 4686 4659 /* … … 4698 4671 * Initialize data (most of it anyway). 4699 4672 */ 4700 pThis ->pDevInsR3= pDevIns;4673 pThisCC->pDevIns = pDevIns; 4701 4674 /* IBase */ 4702 pThis ->IBase.pfnQueryInterface = hdaR3QueryInterface;4675 pThisCC->IBase.pfnQueryInterface = hdaR3QueryInterface; 4703 4676 4704 4677 /* PCI Device */ … … 4827 4800 AssertBreak(iLun < UINT8_MAX); 4828 4801 LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun)); 4829 rc = hdaR3AttachInternal(p This, iLun, 0 /* fFlags */, NULL /* ppDrv */);4802 rc = hdaR3AttachInternal(pDevIns, pThis, pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4830 4803 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4831 4804 { … … 4835 4808 if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 4836 4809 { 4837 hdaR3ReconfigLunWithNullAudio(p This, iLun); /* Pretend attaching to the NULL audio backend will never fail. */4810 hdaR3ReconfigLunWithNullAudio(pDevIns, pThis, pThisCC, iLun); /* Pretend attaching to the NULL audio backend will never fail. */ 4838 4811 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4839 4812 N_("Host audio backend initialization has failed. Selecting the NULL audio backend with the consequence that no sound is audible")); … … 4846 4819 * Create the mixer. 4847 4820 */ 4848 rc = AudioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThis ->pMixer);4821 rc = AudioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThisCC->pMixer); 4849 4822 AssertRCReturn(rc, rc); 4850 4823 … … 4853 4826 */ 4854 4827 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 4855 rc = AudioMixerCreateSink(pThis ->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);4828 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink); 4856 4829 AssertRCReturn(rc, rc); 4857 rc = AudioMixerCreateSink(pThis ->pMixer, "[Playback] Center / Subwoofer", AUDMIXSINKDIR_OUTPUT, &pThis->SinkCenterLFE.pMixSink);4830 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Center / Subwoofer", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkCenterLFE.pMixSink); 4858 4831 AssertRCReturn(rc, rc); 4859 rc = AudioMixerCreateSink(pThis ->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThis->SinkRear.pMixSink);4832 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkRear.pMixSink); 4860 4833 AssertRCReturn(rc, rc); 4861 4834 #else 4862 rc = AudioMixerCreateSink(pThis ->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);4835 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink); 4863 4836 AssertRCReturn(rc, rc); 4864 4837 #endif … … 4867 4840 * Add mixer input sinks. 4868 4841 */ 4869 rc = AudioMixerCreateSink(pThis ->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->SinkLineIn.pMixSink);4842 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkLineIn.pMixSink); 4870 4843 AssertRCReturn(rc, rc); 4871 4844 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 4872 rc = AudioMixerCreateSink(pThis ->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->SinkMicIn.pMixSink);4845 rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkMicIn.pMixSink); 4873 4846 AssertRCReturn(rc, rc); 4874 4847 #endif … … 4876 4849 /* There is no master volume control. Set the master to max. */ 4877 4850 PDMAUDIOVOLUME vol = { false, 255, 255 }; 4878 rc = AudioMixerSetMasterVolume(pThis ->pMixer, &vol);4851 rc = AudioMixerSetMasterVolume(pThisCC->pMixer, &vol); 4879 4852 AssertRCReturn(rc, rc); 4880 4853 4881 /* Allocate CORB buffer. */4882 pThis->cbCorbBuf = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE;4883 pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);4884 AssertReturn(pThis->pu32CorbBuf, VERR_NO_MEMORY);4885 4886 /* Allocate RIRB buffer. */4887 pThis->cbRirbBuf = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE;4888 pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);4889 AssertReturn(pThis->pu64RirbBuf, VERR_NO_MEMORY);4890 4891 4854 /* Allocate codec. */ 4892 pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 4893 AssertReturn(pThis->pCodec, VERR_NO_MEMORY); 4855 PHDACODEC pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 4856 pThisCC->pCodec = pCodec; 4857 AssertReturn(pCodec, VERR_NO_MEMORY); 4894 4858 4895 4859 /* Set codec callbacks to this controller. */ 4896 pThis->pCodec->pfnCbMixerAddStream = hdaR3MixerAddStream; 4897 pThis->pCodec->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream; 4898 pThis->pCodec->pfnCbMixerControl = hdaR3MixerControl; 4899 pThis->pCodec->pfnCbMixerSetVolume = hdaR3MixerSetVolume; 4900 4901 pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */ 4860 pCodec->pDevIns = pDevIns; 4861 pCodec->pfnCbMixerAddStream = hdaR3MixerAddStream; 4862 pCodec->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream; 4863 pCodec->pfnCbMixerControl = hdaR3MixerControl; 4864 pCodec->pfnCbMixerSetVolume = hdaR3MixerSetVolume; 4902 4865 4903 4866 /* Construct the codec. */ 4904 rc = hdaCodecConstruct(pDevIns, p This->pCodec, 0 /* Codec index */, pCfg);4867 rc = hdaCodecConstruct(pDevIns, pCodec, 0 /* Codec index */, pCfg); 4905 4868 AssertRCReturn(rc, rc); 4906 4869 4907 4870 /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for 4908 4871 verb F20 should provide device/codec recognition. */ 4909 Assert(p This->pCodec->u16VendorId);4910 Assert(p This->pCodec->u16DeviceId);4911 PDMPciDevSetSubSystemVendorId(pPciDev, p This->pCodec->u16VendorId); /* 2c ro - intel.) */4912 PDMPciDevSetSubSystemId( pPciDev, p This->pCodec->u16DeviceId); /* 2e ro. */4872 Assert(pCodec->u16VendorId); 4873 Assert(pCodec->u16DeviceId); 4874 PDMPciDevSetSubSystemVendorId(pPciDev, pCodec->u16VendorId); /* 2c ro - intel.) */ 4875 PDMPciDevSetSubSystemId( pPciDev, pCodec->u16DeviceId); /* 2e ro. */ 4913 4876 4914 4877 /* … … 4930 4893 for (size_t i = 0; i < HDA_MAX_STREAMS; i++) 4931 4894 { 4932 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],4895 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, (void *)(uintptr_t)i, 4933 4896 TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->aStreams[i].hTimer); 4934 4897 AssertRCReturn(rc, rc); … … 4943 4906 for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i) 4944 4907 { 4945 rc = hdaR3StreamC reate(&pThis->aStreams[i], pThis, i /* u8SD */);4908 rc = hdaR3StreamConstruct(&pThis->aStreams[i], &pThisCC->aStreams[i], pThis, pThisCC, i /* u8SD */); 4946 4909 AssertRCReturn(rc, rc); 4947 4910 } … … 4952 4915 */ 4953 4916 PHDADRIVER pDrv; 4954 RTListForEach(&pThis ->lstDrv, pDrv, HDADRIVER, Node)4917 RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node) 4955 4918 { 4956 4919 /* … … 5132 5095 * Register statistics. 5133 5096 */ 5134 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "Timer", STAMUNIT_TICKS_PER_CALL, "Profiling hdaR3Timer.");5135 5097 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn, STAMTYPE_PROFILE, "Input", STAMUNIT_TICKS_PER_CALL, "Profiling input."); 5136 5098 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut, STAMTYPE_PROFILE, "Output", STAMUNIT_TICKS_PER_CALL, "Profiling output."); … … 5203 5165 /* .uSharedVersion = */ 42, 5204 5166 /* .cbInstanceShared = */ sizeof(HDASTATE), 5205 /* .cbInstanceCC = */ 0,5167 /* .cbInstanceCC = */ CTX_EXPR(sizeof(HDASTATER3), 0, 0), 5206 5168 /* .cbInstanceRC = */ 0, 5207 5169 /* .cMaxPciDevices = */ 1, -
trunk/src/VBox/Devices/Audio/DevHDA.h
r82421 r82450 36 36 37 37 /** 38 * Structure defining an HDA mixer sink. 39 * Its purpose is to know which audio mixer sink is bound to 40 * which SDn (SDI/SDO) device stream. 41 * 42 * This is needed in order to handle interleaved streams 43 * (that is, multiple channels in one stream) or non-interleaved 44 * streams (each channel has a dedicated stream). 38 * HDA mixer sink definition (ring-3). 39 * 40 * Its purpose is to know which audio mixer sink is bound to which SDn 41 * (SDI/SDO) device stream. 42 * 43 * This is needed in order to handle interleaved streams (that is, multiple 44 * channels in one stream) or non-interleaved streams (each channel has a 45 * dedicated stream). 45 46 * 46 47 * This is only known to the actual device emulation level. … … 48 49 typedef struct HDAMIXERSINK 49 50 { 50 R3PTRTYPE(PHDASTREAM) pStream; 51 R3PTRTYPE(PHDASTREAM) pStreamShared; 52 R3PTRTYPE(PHDASTREAMR3) pStreamR3; 51 53 /** Pointer to the actual audio mixer sink. */ 52 54 R3PTRTYPE(PAUDMIXSINK) pMixSink; 53 } HDAMIXERSINK, *PHDAMIXERSINK; 54 55 /** 56 * Mapping a stream tag to an HDA stream. 55 } HDAMIXERSINK; 56 /** Pointer to an HDA mixer sink definition (ring-3). */ 57 typedef HDAMIXERSINK *PHDAMIXERSINK; 58 59 /** 60 * Mapping a stream tag to an HDA stream (ring-3). 57 61 */ 58 62 typedef struct HDATAG … … 62 66 uint8_t Padding[7]; 63 67 /** Pointer to associated stream. */ 64 R3PTRTYPE(PHDASTREAM ) pStream;68 R3PTRTYPE(PHDASTREAMR3) pStreamR3; 65 69 } HDATAG; 66 70 /** Pointer to a HDA stream tag mapping. */ 67 71 typedef HDATAG *PHDATAG; 68 72 69 /** @todo Make STAM values out of this? */70 typedef struct HDASTATEDEBUG71 {72 #ifdef DEBUG73 /** Timestamp (in ns) of the last timer callback (hdaTimer).74 * Used to calculate the time actually elapsed between two timer callbacks. */75 uint64_t tsTimerLastCalledNs;76 /** IRQ debugging information. */77 struct78 {79 /** Timestamp (in ns) of last processed (asserted / deasserted) IRQ. */80 uint64_t tsProcessedLastNs;81 /** Timestamp (in ns) of last asserted IRQ. */82 uint64_t tsAssertedNs;83 /** How many IRQs have been asserted already. */84 uint64_t cAsserted;85 /** Accumulated elapsed time (in ns) of all IRQ being asserted. */86 uint64_t tsAssertedTotalNs;87 /** Timestamp (in ns) of last deasserted IRQ. */88 uint64_t tsDeassertedNs;89 /** How many IRQs have been deasserted already. */90 uint64_t cDeasserted;91 /** Accumulated elapsed time (in ns) of all IRQ being deasserted. */92 uint64_t tsDeassertedTotalNs;93 } IRQ;94 #endif95 /** Whether debugging is enabled or not. */96 bool fEnabled;97 /** Path where to dump the debug output to.98 * Defaults to VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH. */99 char szOutPath[RTPATH_MAX + 1];100 } HDASTATEDEBUG;101 102 73 /** 103 74 * Shared ICH Intel HD audio controller state. … … 107 78 /** Critical section protecting the HDA state. */ 108 79 PDMCRITSECT CritSect; 109 /** R3 Pointer to the device instance. */110 PPDMDEVINSR3 pDevInsR3;111 /** The base interface for LUN\#0. */112 PDMIBASE IBase;113 80 /** The HDA's register set. */ 114 81 uint32_t au32Regs[HDA_NUM_REGS]; 115 82 /** Internal stream states. */ 116 83 HDASTREAM aStreams[HDA_MAX_STREAMS]; 117 /** Mapping table between stream tags and stream states. */118 HDATAG aTags[HDA_MAX_TAGS];119 84 /** CORB buffer base address. */ 120 85 uint64_t u64CORBBase; … … 124 89 * Made out of DPLBASE + DPUBASE (3.3.32 + 3.3.33). */ 125 90 uint64_t u64DPBase; 126 /** Pointer to CORB buffer. */ 127 R3PTRTYPE(uint32_t *) pu32CorbBuf; 128 /** Size in bytes of CORB buffer. */ 91 /** Size in bytes of CORB buffer (#au32CorbBuf). */ 129 92 uint32_t cbCorbBuf; 130 /** Padding for alignment. */ 131 uint32_t u32Padding1; 132 /** Pointer to RIRB buffer. */ 133 R3PTRTYPE(uint64_t *) pu64RirbBuf; 134 /** Size in bytes of RIRB buffer. */ 93 /** Size in bytes of RIRB buffer (#au64RirbBuf). */ 135 94 uint32_t cbRirbBuf; 136 /** DMA position buffer enable bit. */137 bool fDMAPosition;138 /** Reserved. */139 bool afPadding1b[2];140 /** Number of active (running) SDn streams. */141 uint8_t cStreamsActive;142 /** Pointer to HDA codec to use. */143 R3PTRTYPE(PHDACODEC) pCodec;144 /** List of associated LUN drivers (HDADRIVER). */145 RTLISTANCHORR3 lstDrv;146 /** The device' software mixer. */147 R3PTRTYPE(PAUDIOMIXER) pMixer;148 /** HDA sink for (front) output. */149 HDAMIXERSINK SinkFront;150 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND151 /** HDA sink for center / LFE output. */152 HDAMIXERSINK SinkCenterLFE;153 /** HDA sink for rear output. */154 HDAMIXERSINK SinkRear;155 #endif156 /** HDA mixer sink for line input. */157 HDAMIXERSINK SinkLineIn;158 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN159 /** Audio mixer sink for microphone input. */160 HDAMIXERSINK SinkMicIn;161 #endif162 /** Last updated wall clock (WALCLK) counter. */163 uint64_t u64WalClk;164 95 /** Response Interrupt Count (RINTCNT). */ 165 96 uint16_t u16RespIntCnt; … … 177 108 /** Whether the position adjustment is enabled or not. */ 178 109 bool fPosAdjustEnabled; 110 /** DMA position buffer enable bit. */ 111 bool fDMAPosition; 112 /** Current IRQ level. */ 113 uint8_t u8IRQL; 179 114 #ifdef VBOX_STRICT 180 115 /** Wall clock (WALCLK) stale count. … … 182 117 * move the counter forward (stale). */ 183 118 uint8_t u8WalClkStaleCnt; 184 uint8_t Padding1[2];185 119 #else 186 uint8_t Padding1[3]; 187 #endif 188 /** Current IRQ level. */ 189 uint8_t u8IRQL; 120 uint8_t bPadding1; 121 #endif 190 122 /** The device timer Hz rate. Defaults to HDA_TIMER_HZ_DEFAULT. */ 191 123 uint16_t uTimerHz; 192 124 /** Padding for alignment. */ 193 uint8_t au8Padding3[3]; 194 /** Debug stuff. */ 195 HDASTATEDEBUG Dbg; 125 uint16_t au16Padding3[3]; 126 /** Last updated wall clock (WALCLK) counter. */ 127 uint64_t u64WalClk; 128 /** The CORB buffer. */ 129 uint32_t au32CorbBuf[HDA_CORB_SIZE]; 130 /** Pointer to RIRB buffer. */ 131 uint64_t au64RirbBuf[HDA_RIRB_SIZE]; 196 132 197 133 /** PCI Region \#0: 16KB of MMIO stuff. */ … … 199 135 200 136 #ifdef VBOX_WITH_STATISTICS 201 STAMPROFILE StatTimer;202 137 STAMPROFILE StatIn; 203 138 STAMPROFILE StatOut; … … 224 159 /** @} */ 225 160 #endif 161 162 #ifdef DEBUG 163 /** Debug stuff. 164 * @todo Make STAM values out some of this? */ 165 struct 166 { 167 # if 0 /* unused */ 168 /** Timestamp (in ns) of the last timer callback (hdaTimer). 169 * Used to calculate the time actually elapsed between two timer callbacks. */ 170 uint64_t tsTimerLastCalledNs; 171 # endif 172 /** IRQ debugging information. */ 173 struct 174 { 175 /** Timestamp (in ns) of last processed (asserted / deasserted) IRQ. */ 176 uint64_t tsProcessedLastNs; 177 /** Timestamp (in ns) of last asserted IRQ. */ 178 uint64_t tsAssertedNs; 179 # if 0 /* unused */ 180 /** How many IRQs have been asserted already. */ 181 uint64_t cAsserted; 182 /** Accumulated elapsed time (in ns) of all IRQ being asserted. */ 183 uint64_t tsAssertedTotalNs; 184 /** Timestamp (in ns) of last deasserted IRQ. */ 185 uint64_t tsDeassertedNs; 186 /** How many IRQs have been deasserted already. */ 187 uint64_t cDeasserted; 188 /** Accumulated elapsed time (in ns) of all IRQ being deasserted. */ 189 uint64_t tsDeassertedTotalNs; 190 # endif 191 } IRQ; 192 } Dbg; 193 #endif 226 194 /** This is for checking that the build was correctly configured in all contexts. 227 195 * This is set to HDASTATE_ALIGNMENT_CHECK_MAGIC. */ … … 234 202 #define HDASTATE_ALIGNMENT_CHECK_MAGIC UINT64_C(0x1298afb75893e059) 235 203 204 205 /** 206 * Ring-3 ICH Intel HD audio controller state. 207 */ 208 typedef struct HDASTATER3 209 { 210 /** Internal stream states. */ 211 HDASTREAMR3 aStreams[HDA_MAX_STREAMS]; 212 /** Mapping table between stream tags and stream states. */ 213 HDATAG aTags[HDA_MAX_TAGS]; 214 /** Number of active (running) SDn streams. */ 215 uint8_t cStreamsActive; 216 uint8_t abPadding0[7]; 217 /** R3 Pointer to the device instance. */ 218 PPDMDEVINSR3 pDevIns; 219 /** The base interface for LUN\#0. */ 220 PDMIBASE IBase; 221 /** Pointer to HDA codec to use. */ 222 R3PTRTYPE(PHDACODEC) pCodec; 223 /** List of associated LUN drivers (HDADRIVER). */ 224 RTLISTANCHORR3 lstDrv; 225 /** The device' software mixer. */ 226 R3PTRTYPE(PAUDIOMIXER) pMixer; 227 /** HDA sink for (front) output. */ 228 HDAMIXERSINK SinkFront; 229 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 230 /** HDA sink for center / LFE output. */ 231 HDAMIXERSINK SinkCenterLFE; 232 /** HDA sink for rear output. */ 233 HDAMIXERSINK SinkRear; 234 #endif 235 /** HDA mixer sink for line input. */ 236 HDAMIXERSINK SinkLineIn; 237 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 238 /** Audio mixer sink for microphone input. */ 239 HDAMIXERSINK SinkMicIn; 240 #endif 241 /** Debug stuff. */ 242 struct 243 { 244 /** Whether debugging is enabled or not. */ 245 bool fEnabled; 246 /** Path where to dump the debug output to. 247 * Defaults to VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH. */ 248 char szOutPath[RTPATH_MAX]; 249 } Dbg; 250 } HDASTATER3; 251 /** Pointer to a ring-3 HDA device state. */ 252 typedef HDASTATER3 *PHDASTATER3; 253 254 236 255 #endif /* !VBOX_INCLUDED_SRC_Audio_DevHDA_h */ 237 256 -
trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
r82406 r82450 41 41 * Processes (de/asserts) the interrupt according to the HDA's current state. 42 42 * 43 * @returns IPRT status code.44 43 * @param pDevIns The device instance. 45 * @param pThis HDAstate.44 * @param pThis The shared HDA device state. 46 45 * @param pszSource Caller information. 47 46 */ 48 47 #if defined(LOG_ENABLED) || defined(DOXYGEN_RUNNING) 49 inthdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis, const char *pszSource)48 void hdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis, const char *pszSource) 50 49 #else 51 inthdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis)50 void hdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis) 52 51 #endif 53 52 { … … 80 79 pThis->u8IRQL = 0; 81 80 } 82 83 return VINF_SUCCESS;84 81 } 85 82 … … 89 86 * @return IPRT status code. 90 87 * @return Currently set wall clock value. 91 * @param pThis HDAstate.88 * @param pThis The shared HDA device state. 92 89 * 93 90 * @remark Operation is atomic. … … 99 96 100 97 #ifdef IN_RING3 98 99 /** 100 * Helper for hdaR3WalClkSet. 101 */ 102 DECLINLINE(PHDASTREAMPERIOD) hdaR3SinkToStreamPeriod(PHDAMIXERSINK pSink) 103 { 104 PHDASTREAM pStream = hdaR3GetSharedStreamFromSink(pSink); 105 if (pStream) 106 return &pStream->State.Period; 107 return NULL; 108 } 101 109 102 110 /** … … 107 115 * 108 116 * @return true if the WALCLK register has been updated, false if not. 109 * @param pThis HDA state. 117 * @param pThis The shared HDA device state. 118 * @param pThisCC The ring-3 HDA device state. 110 119 * @param u64WalClk Wall clock value to set WALCLK register to. 111 120 * @param fForce Whether to force setting the wall clock value or not. 112 121 */ 113 bool hdaR3WalClkSet(PHDASTATE pThis, uint64_t u64WalClk, bool fForce) 114 { 115 const bool fFrontPassed = hdaR3StreamPeriodHasPassedAbsWalClk (&hdaR3GetStreamFromSink(pThis, &pThis->SinkFront)->State.Period, 116 u64WalClk); 117 const uint64_t u64FrontAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk(&hdaR3GetStreamFromSink(pThis, &pThis->SinkFront)->State.Period); 122 bool hdaR3WalClkSet(PHDASTATE pThis, PHDASTATER3 pThisCC, uint64_t u64WalClk, bool fForce) 123 { 124 const bool fFrontPassed = hdaR3StreamPeriodHasPassedAbsWalClk( hdaR3SinkToStreamPeriod(&pThisCC->SinkFront), u64WalClk); 125 const uint64_t u64FrontAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkFront)); 118 126 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 119 127 # error "Implement me!" 120 128 # endif 121 129 122 const bool fLineInPassed = hdaR3StreamPeriodHasPassedAbsWalClk ( &hdaR3GetStreamFromSink(pThis, &pThis->SinkLineIn)->State.Period, u64WalClk);123 const uint64_t u64LineInAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk( &hdaR3GetStreamFromSink(pThis, &pThis->SinkLineIn)->State.Period);130 const bool fLineInPassed = hdaR3StreamPeriodHasPassedAbsWalClk (hdaR3SinkToStreamPeriod(&pThisCC->SinkLineIn), u64WalClk); 131 const uint64_t u64LineInAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkLineIn)); 124 132 # ifdef VBOX_WITH_HDA_MIC_IN 125 const bool fMicInPassed = hdaR3StreamPeriodHasPassedAbsWalClk ( &hdaR3GetStreamFromSink(pThis, &pThis->SinkMicIn)->State.Period, u64WalClk);126 const uint64_t u64MicInAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk( &hdaR3GetStreamFromSink(pThis, &pThis->SinkMicIn)->State.Period);133 const bool fMicInPassed = hdaR3StreamPeriodHasPassedAbsWalClk (hdaR3SinkToStreamPeriod(&pThisCC->SinkMicIn), u64WalClk); 134 const uint64_t u64MicInAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkMicIn)); 127 135 # endif 128 136 … … 190 198 * 191 199 * @return PHDAMIXERSINK 192 * @param pThis HDAstate.200 * @param pThisCC The ring-3 HDA device state. 193 201 * @param uSD SD# to return mixer sink for. 194 202 * NULL if not found / handled. 195 203 */ 196 PHDAMIXERSINK hdaR3GetDefaultSink(PHDASTATE pThis, uint8_t uSD)204 PHDAMIXERSINK hdaR3GetDefaultSink(PHDASTATER3 pThisCC, uint8_t uSD) 197 205 { 198 206 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) … … 201 209 202 210 if (uSD == uFirstSDI) /* First SDI. */ 203 return &pThis ->SinkLineIn;211 return &pThisCC->SinkLineIn; 204 212 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 205 213 if (uSD == uFirstSDI + 1) 206 return &pThis ->SinkMicIn;214 return &pThisCC->SinkMicIn; 207 215 # else 208 216 /* If we don't have a dedicated Mic-In sink, use the always present Line-In sink. */ 209 return &pThis ->SinkLineIn;217 return &pThisCC->SinkLineIn; 210 218 # endif 211 219 } … … 215 223 216 224 if (uSD == uFirstSDO) 217 return &pThis ->SinkFront;225 return &pThisCC->SinkFront; 218 226 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 219 227 if (uSD == uFirstSDO + 1) 220 return &pThis ->SinkCenterLFE;228 return &pThisCC->SinkCenterLFE; 221 229 if (uSD == uFirstSDO + 2) 222 return &pThis ->SinkRear;230 return &pThisCC->SinkRear; 223 231 # endif 224 232 } … … 270 278 * @return Pointer to HDA stream, or NULL if none found. 271 279 */ 272 PHDASTREAM hdaR3GetStreamFromSink(PHDASTATE pThis, PHDAMIXERSINK pSink) 273 { 274 AssertPtrReturn(pThis, NULL); 280 PHDASTREAMR3 hdaR3GetR3StreamFromSink(PHDAMIXERSINK pSink) 281 { 275 282 AssertPtrReturn(pSink, NULL); 276 283 277 284 /** @todo Do something with the channel mapping here? */ 278 return pSink->pStream; 279 } 280 281 /** 285 return pSink->pStreamR3; 286 } 287 288 289 /** 290 * Returns the HDA stream of specified HDA sink. 291 * 292 * @return Pointer to HDA stream, or NULL if none found. 293 */ 294 PHDASTREAM hdaR3GetSharedStreamFromSink(PHDAMIXERSINK pSink) 295 { 296 AssertPtrReturn(pSink, NULL); 297 298 /** @todo Do something with the channel mapping here? */ 299 return pSink->pStreamShared; 300 } 301 302 /* 282 303 * Reads DMA data from a given HDA output stream. 283 304 * 284 305 * @return IPRT status code. 285 * @param pThis HDA state. 286 * @param pStream HDA output stream to read DMA data from. 306 * @param pDevIns The device instance. 307 * @param pThis The shared HDA device state (for stats). 308 * @param pStreamShared HDA output stream to read DMA data from - shared bits. 309 * @param pStreamR3 HDA output stream to read DMA data from - shared ring-3. 287 310 * @param pvBuf Where to store the read data. 288 311 * @param cbBuf How much to read in bytes. 289 312 * @param pcbRead Returns read bytes from DMA. Optional. 290 313 */ 291 int hdaR3DMARead(PHDASTATE pThis, PHDASTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 292 { 293 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 294 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 295 /* pcbRead is optional. */ 296 297 PHDABDLE pBDLE = &pStream->State.BDLE; 314 int hdaR3DMARead(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, 315 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 316 { 317 RT_NOREF(pThis); 318 PHDABDLE pBDLE = &pStreamShared->State.BDLE; 298 319 299 320 int rc = VINF_SUCCESS; … … 305 326 uint64_t csSilence = 0; 306 327 307 pStream ->Dbg.cSilenceThreshold = 100;308 pStream ->Dbg.cbSilenceReadMin = _1M;309 # endif 310 311 RTGCPHYS addrChunk = pBDLE->Desc.u64BufAddr + pBDLE->State.u32BufOff;328 pStreamCC->Dbg.cSilenceThreshold = 100; 329 pStreamCC->Dbg.cbSilenceReadMin = _1M; 330 # endif 331 332 RTGCPHYS GCPhysChunk = pBDLE->Desc.u64BufAddr + pBDLE->State.u32BufOff; 312 333 313 334 while (cbLeft) 314 335 { 315 uint32_t cbChunk = RT_MIN(cbLeft, pStream->u16FIFOS); 316 317 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), addrChunk, (uint8_t *)pvBuf + cbReadTotal, cbChunk); 318 if (RT_FAILURE(rc)) 319 break; 336 uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS); 337 338 rc = PDMDevHlpPhysRead(pDevIns, GCPhysChunk, (uint8_t *)pvBuf + cbReadTotal, cbChunk); 339 AssertRCBreak(rc); 320 340 321 341 # ifdef HDA_DEBUG_SILENCE … … 330 350 } 331 351 # endif 332 if (pStream->Dbg.Runtime.fEnabled) 333 DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbReadTotal, cbChunk, 0 /* fFlags */); 352 if (RT_LIKELY(!pStreamR3->Dbg.Runtime.fEnabled)) 353 { /* likely */ } 354 else 355 DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbReadTotal, cbChunk, 0 /* fFlags */); 334 356 335 357 STAM_COUNTER_ADD(&pThis->StatBytesRead, cbChunk); 336 addrChunk = (addrChunk + cbChunk) % pBDLE->Desc.u32BufSize; 337 358 359 /* advance */ 338 360 Assert(cbLeft >= cbChunk); 361 GCPhysChunk = (GCPhysChunk + cbChunk) % pBDLE->Desc.u32BufSize; 362 cbReadTotal += cbChunk; 339 363 cbLeft -= cbChunk; 340 341 cbReadTotal += cbChunk;342 364 } 343 365 344 366 # ifdef HDA_DEBUG_SILENCE 345 367 if (csSilence) 346 pStream ->Dbg.csSilence += csSilence;368 pStreamR3->Dbg.csSilence += csSilence; 347 369 348 370 if ( csSilence == 0 349 && pStream ->Dbg.csSilence > pStream->Dbg.cSilenceThreshold350 && pStream ->Dbg.cbReadTotal >= pStream->Dbg.cbSilenceReadMin)351 { 352 LogFunc(("Silent block detected: %RU64 audio samples\n", pStream ->Dbg.csSilence));353 pStream ->Dbg.csSilence = 0;371 && pStreamR3->Dbg.csSilence > pStreamR3->Dbg.cSilenceThreshold 372 && pStreamR3->Dbg.cbReadTotal >= pStreamR3->Dbg.cbSilenceReadMin) 373 { 374 LogFunc(("Silent block detected: %RU64 audio samples\n", pStreamR3->Dbg.csSilence)); 375 pStreamR3->Dbg.csSilence = 0; 354 376 } 355 377 # endif … … 368 390 * 369 391 * @return IPRT status code. 370 * @param pThis HDA state. 371 * @param pStream HDA input stream to write audio data to. 392 * @param pDevIns The device instance. 393 * @param pThis The shared HDA device state (for stats). 394 * @param pStreamShared HDA input stream to write audio data to - shared. 395 * @param pStreamR3 HDA input stream to write audio data to - ring-3. 372 396 * @param pvBuf Data to write. 373 397 * @param cbBuf How much (in bytes) to write. 374 398 * @param pcbWritten Returns written bytes on success. Optional. 375 399 */ 376 int hdaR3DMAWrite(PHDASTATE pThis, PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 377 { 378 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 379 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 380 /* pcbWritten is optional. */ 381 382 PHDABDLE pBDLE = &pStream->State.BDLE; 383 384 int rc = VINF_SUCCESS; 385 386 uint32_t cbWrittenTotal = 0; 387 uint32_t cbLeft = RT_MIN(cbBuf, pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 388 389 RTGCPHYS addrChunk = pBDLE->Desc.u64BufAddr + pBDLE->State.u32BufOff; 390 400 int hdaR3DMAWrite(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, 401 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 402 { 403 RT_NOREF(pThis); 404 PHDABDLE pBDLE = &pStreamShared->State.BDLE; 405 int rc = VINF_SUCCESS; 406 uint32_t cbWrittenTotal = 0; 407 uint32_t cbLeft = RT_MIN(cbBuf, pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 408 RTGCPHYS GCPhysChunk = pBDLE->Desc.u64BufAddr + pBDLE->State.u32BufOff; 391 409 while (cbLeft) 392 410 { 393 uint32_t cbChunk = RT_MIN(cbLeft, pStream ->u16FIFOS);411 uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS); 394 412 395 413 /* Sanity checks. */ 396 414 Assert(cbChunk <= pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 397 415 398 if ( pStream->Dbg.Runtime.fEnabled)399 DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk, 0 /* fFlags */);400 401 rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),402 addrChunk, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk); 403 if (RT_FAILURE(rc))404 break;416 if (RT_LIKELY(!pStreamR3->Dbg.Runtime.fEnabled)) 417 { /* likely */ } 418 else 419 DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk, 0 /* fFlags */); 420 421 rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysChunk, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk); 422 AssertRCReturn(rc, rc); 405 423 406 424 STAM_COUNTER_ADD(&pThis->StatBytesWritten, cbChunk); 407 addrChunk = (addrChunk + cbChunk) % pBDLE->Desc.u32BufSize; 408 425 426 /* advance */ 409 427 Assert(cbLeft >= cbChunk); 410 cbLeft -= (uint32_t)cbChunk;411 412 428 cbWrittenTotal += (uint32_t)cbChunk; 429 GCPhysChunk = (GCPhysChunk + cbChunk) % pBDLE->Desc.u32BufSize; 430 cbLeft -= (uint32_t)cbChunk; 413 431 } 414 432 … … 430 448 * 431 449 * @returns Determined INTSTS register value. 432 * @param pThis HDAstate.450 * @param pThis The shared HDA device state. 433 451 * 434 452 * @remark This function does *not* set INTSTS! … … 554 572 555 573 # ifdef LOG_ENABLED 556 void hdaR3BDLEDumpAll(P HDASTATE pThis, uint64_t u64BDLBase, uint16_t cBDLE)574 void hdaR3BDLEDumpAll(PPDMDEVINS pDevIns, PHDASTATE pThis, uint64_t u64BDLBase, uint16_t cBDLE) 557 575 { 558 576 LogFlowFunc(("BDLEs @ 0x%x (%RU16):\n", u64BDLBase, cBDLE)); … … 564 582 { 565 583 HDABDLEDESC bd; 566 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), u64BDLBase + i * sizeof(HDABDLEDESC), &bd, sizeof(bd));584 PDMDevHlpPhysRead(pDevIns, u64BDLBase + i * sizeof(HDABDLEDESC), &bd, sizeof(bd)); 567 585 568 586 LogFunc(("\t#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n", … … 582 600 { 583 601 uint32_t uDMACnt; 584 PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)),602 PDMDevHlpPhysRead(pDevIns, (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)), 585 603 &uDMACnt, sizeof(uDMACnt)); 586 604 … … 593 611 * Fetches a Bundle Descriptor List Entry (BDLE) from the DMA engine. 594 612 * 595 * @param pThis Pointer to HDA state. 596 * @param pBDLE Where to store the fetched result. 597 * @param u64BaseDMA Address base of DMA engine to use. 598 * @param u16Entry BDLE entry to fetch. 599 */ 600 int hdaR3BDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry) 601 { 602 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 613 * @param pDevIns The device instance. 614 * @param pBDLE Where to store the fetched result. 615 * @param u64BaseDMA Address base of DMA engine to use. 616 * @param u16Entry BDLE entry to fetch. 617 */ 618 int hdaR3BDLEFetch(PPDMDEVINS pDevIns, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry) 619 { 603 620 AssertPtrReturn(pBDLE, VERR_INVALID_POINTER); 604 621 AssertReturn(u64BaseDMA, VERR_INVALID_PARAMETER); … … 611 628 /** @todo Compare u16Entry with LVI. */ 612 629 613 int rc = PDMDevHlpPhysRead(p This->CTX_SUFF(pDevIns), u64BaseDMA + (u16Entry * sizeof(HDABDLEDESC)),630 int rc = PDMDevHlpPhysRead(pDevIns, u64BaseDMA + (u16Entry * sizeof(HDABDLEDESC)), 614 631 &pBDLE->Desc, sizeof(pBDLE->Desc)); 615 632 … … 664 681 * 665 682 * @returns Whether the new expiration time was set or not. 666 * @param pDevIns The device instance.667 * @param pStream HDA stream to set timer for.668 * @param tsExpire New (virtual) expiration time to set.669 * @param fForce Whether to force setting the expiration time or not.670 * @param tsNow The current clock timestamp if available, 0 if not.683 * @param pDevIns The device instance. 684 * @param pStreamShared HDA stream to set timer for (shared). 685 * @param tsExpire New (virtual) expiration time to set. 686 * @param fForce Whether to force setting the expiration time or not. 687 * @param tsNow The current clock timestamp if available, 0 if not. 671 688 * 672 689 * @remark This function takes all active HDA streams and their … … 679 696 * Forcing a new expiration time will override the above mechanism. 680 697 */ 681 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStream , uint64_t tsExpire, bool fForce, uint64_t tsNow)682 { 683 AssertPtr(pStream );698 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStreamShared, uint64_t tsExpire, bool fForce, uint64_t tsNow) 699 { 700 AssertPtr(pStreamShared); 684 701 685 702 if (!tsNow) 686 tsNow = PDMDevHlpTimerGet(pDevIns, pStream ->hTimer);703 tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); 687 704 688 705 if (!fForce) … … 691 708 * PDMDevHlpTimerGet(), so, some callers does one, this does, and then we do 692 709 * right afterwards == very inefficient! */ 693 if (hdaR3StreamTransferIsScheduled(pStream , tsNow))710 if (hdaR3StreamTransferIsScheduled(pStreamShared, tsNow)) 694 711 { 695 uint64_t const tsNext = hdaR3StreamTransferGetNext(pStream );712 uint64_t const tsNext = hdaR3StreamTransferGetNext(pStreamShared); 696 713 if (tsExpire > tsNext) 697 714 tsExpire = tsNext; … … 706 723 tsExpire = tsNow; 707 724 708 int rc = PDMDevHlpTimerSet(pDevIns, pStream ->hTimer, tsExpire);725 int rc = PDMDevHlpTimerSet(pDevIns, pStreamShared->hTimer, tsExpire); 709 726 AssertRCReturn(rc, false); 710 727 -
trunk/src/VBox/Devices/Audio/DevHDACommon.h
r82417 r82450 25 25 #include <VBox/log.h> /* LOG_ENABLED */ 26 26 27 /** Read callback. */ 27 /** Pointer to an HDA stream (SDI / SDO). */ 28 typedef struct HDASTREAMR3 *PHDASTREAMR3; 29 30 31 32 /** Read callback. */ 28 33 typedef VBOXSTRICTRC FNHDAREGREAD(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 29 34 /** Write callback. */ 30 35 typedef VBOXSTRICTRC FNHDAREGWRITE(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 31 36 … … 598 603 */ 599 604 #ifdef IN_RING3 600 PHDAMIXERSINK hdaR3GetDefaultSink(PHDASTATE pThis, uint8_t uSD);605 PHDAMIXERSINK hdaR3GetDefaultSink(PHDASTATER3 pThisCC, uint8_t uSD); 601 606 #endif 602 607 PDMAUDIODIR hdaGetDirFromSD(uint8_t uSD); 603 PHDASTREAM hdaGetStreamFromSD(PHDASTATE pThis, uint8_t uSD);608 //PHDASTREAM hdaGetStreamFromSD(PHDASTATER3 pThisCC, uint8_t uSD); 604 609 #ifdef IN_RING3 605 PHDASTREAM hdaR3GetStreamFromSink(PHDASTATE pThis, PHDAMIXERSINK pSink); 610 PHDASTREAMR3 hdaR3GetR3StreamFromSink(PHDAMIXERSINK pSink); 611 PHDASTREAM hdaR3GetSharedStreamFromSink(PHDAMIXERSINK pSink); 606 612 #endif 607 613 /** @} */ … … 610 616 * @{ 611 617 */ 612 #if def LOG_ENABLED613 inthdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis, const char *pszSource);618 #if defined(LOG_ENABLED) || defined(DOXYGEN_RUNNING) 619 void hdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis, const char *pszSource); 614 620 # define HDA_PROCESS_INTERRUPT(a_pDevIns, a_pThis) hdaProcessInterrupt((a_pDevIns), (a_pThis), __FUNCTION__) 615 621 #else 616 inthdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis);622 void hdaProcessInterrupt(PPDMDEVINS pDevIns, PHDASTATE pThis); 617 623 # define HDA_PROCESS_INTERRUPT(a_pDevIns, a_pThis) hdaProcessInterrupt((a_pDevIns), (a_pThis)) 618 624 #endif … … 624 630 uint64_t hdaWalClkGetCurrent(PHDASTATE pThis); 625 631 #ifdef IN_RING3 626 bool hdaR3WalClkSet(PHDASTATE pThis, uint64_t u64WalClk, bool fForce);632 bool hdaR3WalClkSet(PHDASTATE pThis, PHDASTATER3 pThisCC, uint64_t u64WalClk, bool fForce); 627 633 #endif 628 634 /** @} */ … … 632 638 */ 633 639 #ifdef IN_RING3 634 int hdaR3DMARead(PHDASTATE pThis, PHDASTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead); 635 int hdaR3DMAWrite(PHDASTATE pThis, PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 640 int hdaR3DMARead(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, 641 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead); 642 int hdaR3DMAWrite(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, 643 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 636 644 #endif 637 645 /** @} */ … … 651 659 #ifdef IN_RING3 652 660 # ifdef LOG_ENABLED 653 void hdaR3BDLEDumpAll(P HDASTATE pThis, uint64_t u64BDLBase, uint16_t cBDLE);661 void hdaR3BDLEDumpAll(PPDMDEVINS pDevIns, PHDASTATE pThis, uint64_t u64BDLBase, uint16_t cBDLE); 654 662 # endif 655 int hdaR3BDLEFetch(P HDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry);663 int hdaR3BDLEFetch(PPDMDEVINS pDevIns, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry); 656 664 bool hdaR3BDLEIsComplete(PHDABDLE pBDLE); 657 665 bool hdaR3BDLENeedsInterrupt(PHDABDLE pBDLE); … … 663 671 */ 664 672 #ifdef IN_RING3 665 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStream , uint64_t u64Expire, bool fForce, uint64_t tsNow);673 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStreamShared, uint64_t u64Expire, bool fForce, uint64_t tsNow); 666 674 #endif 667 675 /** @} */ -
trunk/src/VBox/Devices/Audio/HDACodec.cpp
r82421 r82450 1631 1631 DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted")); 1632 1632 1633 return pThis->pfnCbMixerSetVolume(pThis->p HDAState, enmMixerCtl, &Vol);1633 return pThis->pfnCbMixerSetVolume(pThis->pDevIns, enmMixerCtl, &Vol); 1634 1634 } 1635 1635 … … 2412 2412 2413 2413 /* Propagate to the controller. */ 2414 pThis->pfnCbMixerControl(pThis->p HDAState, PDMAUDIOMIXERCTL_FRONT, uSD, uChannel);2414 pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_FRONT, uSD, uChannel); 2415 2415 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2416 pThis->pfnCbMixerControl(pThis->p HDAState, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);2417 pThis->pfnCbMixerControl(pThis->p HDAState, PDMAUDIOMIXERCTL_REAR, uSD, uChannel);2416 pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel); 2417 pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_REAR, uSD, uChannel); 2418 2418 #endif 2419 2419 } 2420 2420 else if (enmDir == PDMAUDIODIR_IN) 2421 2421 { 2422 pThis->pfnCbMixerControl(pThis->p HDAState, PDMAUDIOMIXERCTL_LINE_IN, uSD, uChannel);2422 pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_LINE_IN, uSD, uChannel); 2423 2423 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2424 pThis->pfnCbMixerControl(pThis->p HDAState, PDMAUDIOMIXERCTL_MIC_IN, uSD, uChannel);2424 pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_MIC_IN, uSD, uChannel); 2425 2425 #endif 2426 2426 } … … 3065 3065 case PDMAUDIOMIXERCTL_REAR: 3066 3066 #endif 3067 {3068 3067 break; 3069 } 3068 3070 3069 case PDMAUDIOMIXERCTL_LINE_IN: 3071 3070 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 3072 3071 case PDMAUDIOMIXERCTL_MIC_IN: 3073 3072 #endif 3074 {3075 3073 break; 3076 } 3074 3077 3075 default: 3078 3076 AssertMsgFailed(("Mixer control %d not implemented\n", enmMixerCtl)); … … 3082 3080 3083 3081 if (RT_SUCCESS(rc)) 3084 rc = pThis->pfnCbMixerAddStream(pThis->p HDAState, enmMixerCtl, pCfg);3082 rc = pThis->pfnCbMixerAddStream(pThis->pDevIns, enmMixerCtl, pCfg); 3085 3083 3086 3084 LogFlowFuncLeaveRC(rc); … … 3092 3090 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3093 3091 3094 int rc = pThis->pfnCbMixerRemoveStream(pThis->p HDAState, enmMixerCtl);3092 int rc = pThis->pfnCbMixerRemoveStream(pThis->pDevIns, enmMixerCtl); 3095 3093 3096 3094 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Devices/Audio/HDACodec.h
r82406 r82450 26 26 #include "AudioMixer.h" 27 27 28 /** The ICH HDA (Intel) controller.*/28 /** Pointer to a shared HDA device state. */ 29 29 typedef struct HDASTATE *PHDASTATE; 30 /** Pointer to a ring-3 HDA device state. */ 31 typedef struct HDASTATER3 *PHDASTATER3; 30 32 /** The ICH HDA (Intel) codec state. */ 31 33 typedef struct HDACODEC *PHDACODEC; 32 34 /** The HDA host driver backend. */ 33 35 typedef struct HDADRIVER *PHDADRIVER; 34 typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;35 typedef struct PDMAUDIOGSTSTRMOUT *PPDMAUDIOGSTSTRMOUT;36 typedef struct PDMAUDIOGSTSTRMIN *PPDMAUDIOGSTSTRMIN;37 36 38 37 /** … … 41 40 typedef DECLCALLBACK(int) FNHDACODECVERBPROCESSOR(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp); 42 41 typedef FNHDACODECVERBPROCESSOR *PFNHDACODECVERBPROCESSOR; 43 typedef FNHDACODECVERBPROCESSOR **PPFNHDACODECVERBPROCESSOR;44 42 45 43 /* PRM 5.3.1 */ … … 71 69 uint8_t u8BSKU; 72 70 uint8_t u8AssemblyId; 71 73 72 /** List of assigned HDA drivers to this codec. 74 73 * A driver only can be assigned to one codec at a time. */ … … 79 78 80 79 PCODECNODE paNodes; 81 /** Pointer to HDA state (controller) this 82 * codec is assigned to. */ 83 PHDASTATE pHDAState; 80 84 81 bool fInReset; 82 uint8_t abPadding1[3]; 85 83 86 84 const uint8_t cTotalNodes; 85 const uint8_t u8AdcVolsLineIn; 86 const uint8_t u8DacLineOut; 87 uint8_t bPadding2; 87 88 const uint8_t *au8Ports; 88 89 const uint8_t *au8Dacs; … … 98 99 const uint8_t *au8VolKnobs; 99 100 const uint8_t *au8Reserveds; 100 const uint8_t u8AdcVolsLineIn;101 const uint8_t u8DacLineOut;102 101 103 102 /** @name Public codec functions. … … 106 105 DECLR3CALLBACKMEMBER(void, pfnReset, (PHDACODEC pThis)); 107 106 DECLR3CALLBACKMEMBER(int, pfnNodeReset, (PHDACODEC pThis, uint8_t, PCODECNODE)); 107 DECLR3CALLBACKMEMBER(void, pfnDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 108 DECLR3CALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 108 109 /** @} */ 110 111 /** The parent device instance. */ 112 PPDMDEVINS pDevIns; 109 113 110 114 /** @name Callbacks to the HDA controller, mostly used for multiplexing to the 111 115 * various host backends. 112 116 * @{ */ 113 DECLR3CALLBACKMEMBER(int, pfnCbMixerAddStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)); 114 DECLR3CALLBACKMEMBER(int, pfnCbMixerRemoveStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)); 115 DECLR3CALLBACKMEMBER(int, pfnCbMixerControl, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel)); 116 DECLR3CALLBACKMEMBER(int, pfnCbMixerSetVolume, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol)); 117 /** @} */ 118 119 /** @name These callbacks are set by codec implementation to answer debugger requests. 120 * @{ */ 121 DECLR3CALLBACKMEMBER(void, pfnDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 122 DECLR3CALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 117 /** 118 * 119 * Adds a new audio stream to a specific mixer control. 120 * 121 * Depending on the mixer control the stream then gets assigned to one of the 122 * internal mixer sinks, which in turn then handle the mixing of all connected 123 * streams to that sink. 124 * 125 * @return VBox status code. 126 * @param pThisCC The ring-3 HDA device state. 127 * @param enmMixerCtl Mixer control to assign new stream to. 128 * @param pCfg Stream configuration for the new stream. 129 */ 130 DECLR3CALLBACKMEMBER(int, pfnCbMixerAddStream, (PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)); 131 /** 132 * Removes a specified mixer control from the HDA's mixer. 133 * 134 * @return VBox status code. 135 * @param pThisCC The ring-3 HDA device state. 136 * @param enmMixerCtl Mixer control to remove. 137 */ 138 DECLR3CALLBACKMEMBER(int, pfnCbMixerRemoveStream, (PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl)); 139 /** 140 * Controls an input / output converter widget, that is, which converter is 141 * connected to which stream (and channel). 142 * 143 * @return VBox status code. 144 * @param pThisCC The ring-3 HDA device state. 145 * @param enmMixerCtl Mixer control to set SD stream number and channel for. 146 * @param uSD SD stream number (number + 1) to set. Set to 0 for unassign. 147 * @param uChannel Channel to set. Only valid if a valid SD stream number is specified. 148 */ 149 DECLR3CALLBACKMEMBER(int, pfnCbMixerControl, (PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel)); 150 /** 151 * Sets the volume of a specified mixer control. 152 * 153 * @return IPRT status code. 154 * @param pThisCC The ring-3 HDA device state. 155 * @param enmMixerCtl Mixer control to set volume for. 156 * @param pVol Pointer to volume data to set. 157 */ 158 DECLR3CALLBACKMEMBER(int, pfnCbMixerSetVolume, (PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol)); 123 159 /** @} */ 124 160 -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r82420 r82450 36 36 37 37 38 #ifdef IN_RING3 38 #ifdef IN_RING3 /* whole file */ 39 40 /********************************************************************************************************************************* 41 * Internal Functions * 42 *********************************************************************************************************************************/ 43 static void hdaR3StreamSetPosition(PHDASTREAM pStreamShared, PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t u32LPIB); 44 45 static int hdaR3StreamAsyncIODestroy(PHDASTREAMR3 pStreamR3); 46 static int hdaR3StreamAsyncIONotify(PHDASTREAMR3 pStreamR3); 47 48 39 49 40 50 /** … … 42 52 * 43 53 * @returns IPRT status code. 44 * @param pStream HDA stream to create. 45 * @param pThis HDA state to assign the HDA stream to. 46 * @param u8SD Stream descriptor number to assign. 47 */ 48 int hdaR3StreamCreate(PHDASTREAM pStream, PHDASTATE pThis, uint8_t u8SD) 54 * @param pStreamShared The HDA stream to construct - shared bits. 55 * @param pStreamR3 The HDA stream to construct - ring-3 bits. 56 * @param pThis The shared HDA device instance. 57 * @param pThisCC The ring-3 HDA device instance. 58 * @param uSD Stream descriptor number to assign. 59 */ 60 int hdaR3StreamConstruct(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, PHDASTATE pThis, PHDASTATER3 pThisCC, uint8_t uSD) 49 61 { 50 62 int rc; 51 RT_NOREF(pThis); 52 AssertPtrReturn(pStream, VERR_INVALID_POINTER);53 54 pStream ->u8SD = u8SD;55 pStream ->pMixSink = NULL;56 pStream ->pHDAState = pThis;57 Assert(pStream ->hTimer != NIL_TMTIMERHANDLE); /* hdaR3Construct initalized this one already. */58 59 pStream ->State.fInReset = false;60 pStream ->State.fRunning = false;63 64 pStreamR3->u8SD = uSD; 65 pStreamShared->u8SD = uSD; 66 pStreamR3->pMixSink = NULL; 67 pStreamR3->pHDAStateShared = pThis; 68 pStreamR3->pHDAStateR3 = pThisCC; 69 Assert(pStreamShared->hTimer != NIL_TMTIMERHANDLE); /* hdaR3Construct initalized this one already. */ 70 71 pStreamShared->State.fInReset = false; 72 pStreamShared->State.fRunning = false; 61 73 #ifdef HDA_USE_DMA_ACCESS_HANDLER 62 RTListInit(&pStream ->State.lstDMAHandlers);74 RTListInit(&pStreamR3->State.lstDMAHandlers); 63 75 #endif 64 76 65 77 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 66 rc = RTCritSectInit(&pStream ->CritSect);78 rc = RTCritSectInit(&pStreamR3->CritSect); 67 79 AssertRCReturn(rc, rc); 68 80 # endif 69 81 70 rc = hdaR3StreamPeriodCreate(&pStream ->State.Period);82 rc = hdaR3StreamPeriodCreate(&pStreamShared->State.Period); 71 83 AssertRCReturn(rc, rc); 72 84 73 pStream ->State.tsLastUpdateNs = 0;85 pStreamShared->State.tsLastUpdateNs = 0; 74 86 75 87 #ifdef DEBUG 76 rc = RTCritSectInit(&pStream ->Dbg.CritSect);88 rc = RTCritSectInit(&pStreamR3->Dbg.CritSect); 77 89 AssertRCReturn(rc, rc); 78 90 #endif 79 91 80 pStream ->Dbg.Runtime.fEnabled = pThis->Dbg.fEnabled;81 82 if (pStream ->Dbg.Runtime.fEnabled)92 pStreamR3->Dbg.Runtime.fEnabled = pThisCC->Dbg.fEnabled; 93 94 if (pStreamR3->Dbg.Runtime.fEnabled) 83 95 { 84 96 char szFile[64]; 85 86 if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN) 87 RTStrPrintf(szFile, sizeof(szFile), "hdaStreamWriteSD%RU8", pStream->u8SD); 97 char szPath[RTPATH_MAX]; 98 99 /* pFileStream */ 100 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) 101 RTStrPrintf(szFile, sizeof(szFile), "hdaStreamWriteSD%RU8", uSD); 88 102 else 89 RTStrPrintf(szFile, sizeof(szFile), "hdaStreamReadSD%RU8", pStream->u8SD); 90 91 char szPath[RTPATH_MAX + 1]; 92 int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile, 103 RTStrPrintf(szFile, sizeof(szFile), "hdaStreamReadSD%RU8", uSD); 104 105 int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile, 93 106 0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE); 94 107 AssertRC(rc2); 95 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream->Dbg.Runtime.pFileStream); 108 109 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamR3->Dbg.Runtime.pFileStream); 96 110 AssertRC(rc2); 97 111 98 if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN) 99 RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawWriteSD%RU8", pStream->u8SD); 112 /* pFileDMARaw */ 113 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) 114 RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawWriteSD%RU8", uSD); 100 115 else 101 RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawReadSD%RU8", pStream->u8SD);102 103 rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis ->Dbg.szOutPath, szFile,116 RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawReadSD%RU8", uSD); 117 118 rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile, 104 119 0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE); 105 120 AssertRC(rc2); 106 121 107 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream ->Dbg.Runtime.pFileDMARaw);122 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamR3->Dbg.Runtime.pFileDMARaw); 108 123 AssertRC(rc2); 109 124 110 if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN) 111 RTStrPrintf(szFile, sizeof(szFile), "hdaDMAWriteMappedSD%RU8", pStream->u8SD); 125 /* pFileDMAMapped */ 126 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) 127 RTStrPrintf(szFile, sizeof(szFile), "hdaDMAWriteMappedSD%RU8", uSD); 112 128 else 113 RTStrPrintf(szFile, sizeof(szFile), "hdaDMAReadMappedSD%RU8", pStream->u8SD);114 115 rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis ->Dbg.szOutPath, szFile,129 RTStrPrintf(szFile, sizeof(szFile), "hdaDMAReadMappedSD%RU8", uSD); 130 131 rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile, 116 132 0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE); 117 133 AssertRC(rc2); 118 134 119 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream ->Dbg.Runtime.pFileDMAMapped);135 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamR3->Dbg.Runtime.pFileDMAMapped); 120 136 AssertRC(rc2); 121 137 122 138 /* Delete stale debugging files from a former run. */ 123 DrvAudioHlpFileDelete(pStream ->Dbg.Runtime.pFileStream);124 DrvAudioHlpFileDelete(pStream ->Dbg.Runtime.pFileDMARaw);125 DrvAudioHlpFileDelete(pStream ->Dbg.Runtime.pFileDMAMapped);139 DrvAudioHlpFileDelete(pStreamR3->Dbg.Runtime.pFileStream); 140 DrvAudioHlpFileDelete(pStreamR3->Dbg.Runtime.pFileDMARaw); 141 DrvAudioHlpFileDelete(pStreamR3->Dbg.Runtime.pFileDMAMapped); 126 142 } 127 143 … … 132 148 * Destroys an HDA stream. 133 149 * 134 * @param pStream HDA stream to destroy. 135 */ 136 void hdaR3StreamDestroy(PHDASTREAM pStream) 137 { 138 AssertPtrReturnVoid(pStream); 139 140 LogFlowFunc(("[SD%RU8] Destroying ...\n", pStream->u8SD)); 141 142 hdaR3StreamMapDestroy(&pStream->State.Mapping); 150 * @param pStreamShared The HDA stream to destroy - shared bits. 151 * @param pStreamR3 The HDA stream to destroy - ring-3 bits. 152 */ 153 void hdaR3StreamDestroy(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3) 154 { 155 LogFlowFunc(("[SD%RU8] Destroying ...\n", pStreamShared->u8SD)); 156 157 hdaR3StreamMapDestroy(&pStreamR3->State.Mapping); 143 158 144 159 int rc2; 145 160 146 161 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 147 rc2 = hdaR3StreamAsyncIODestroy(pStream );162 rc2 = hdaR3StreamAsyncIODestroy(pStreamR3); 148 163 AssertRC(rc2); 149 164 #endif 150 165 151 166 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 152 if (RTCritSectIsInitialized(&pStream ->CritSect))153 { 154 rc2 = RTCritSectDelete(&pStream ->CritSect);167 if (RTCritSectIsInitialized(&pStreamR3->CritSect)) 168 { 169 rc2 = RTCritSectDelete(&pStreamR3->CritSect); 155 170 AssertRC(rc2); 156 171 } 157 172 # endif 158 173 159 if (pStream ->State.pCircBuf)160 { 161 RTCircBufDestroy(pStream ->State.pCircBuf);162 pStream ->State.pCircBuf = NULL;163 } 164 165 hdaR3StreamPeriodDestroy(&pStream ->State.Period);174 if (pStreamR3->State.pCircBuf) 175 { 176 RTCircBufDestroy(pStreamR3->State.pCircBuf); 177 pStreamR3->State.pCircBuf = NULL; 178 } 179 180 hdaR3StreamPeriodDestroy(&pStreamShared->State.Period); 166 181 167 182 #ifdef DEBUG 168 if (RTCritSectIsInitialized(&pStream ->Dbg.CritSect))169 { 170 rc2 = RTCritSectDelete(&pStream ->Dbg.CritSect);183 if (RTCritSectIsInitialized(&pStreamR3->Dbg.CritSect)) 184 { 185 rc2 = RTCritSectDelete(&pStreamR3->Dbg.CritSect); 171 186 AssertRC(rc2); 172 187 } 173 188 #endif 174 189 175 if (pStream ->Dbg.Runtime.fEnabled)176 { 177 DrvAudioHlpFileDestroy(pStream ->Dbg.Runtime.pFileStream);178 pStream ->Dbg.Runtime.pFileStream = NULL;179 180 DrvAudioHlpFileDestroy(pStream ->Dbg.Runtime.pFileDMARaw);181 pStream ->Dbg.Runtime.pFileDMARaw = NULL;182 183 DrvAudioHlpFileDestroy(pStream ->Dbg.Runtime.pFileDMAMapped);184 pStream ->Dbg.Runtime.pFileDMAMapped = NULL;190 if (pStreamR3->Dbg.Runtime.fEnabled) 191 { 192 DrvAudioHlpFileDestroy(pStreamR3->Dbg.Runtime.pFileStream); 193 pStreamR3->Dbg.Runtime.pFileStream = NULL; 194 195 DrvAudioHlpFileDestroy(pStreamR3->Dbg.Runtime.pFileDMARaw); 196 pStreamR3->Dbg.Runtime.pFileDMARaw = NULL; 197 198 DrvAudioHlpFileDestroy(pStreamR3->Dbg.Runtime.pFileDMAMapped); 199 pStreamR3->Dbg.Runtime.pFileDMAMapped = NULL; 185 200 } 186 201 … … 189 204 190 205 /** 191 * Initializes an HDA stream. 192 * 193 * @returns IPRT status code. VINF_NO_CHANGE if the stream does not need (re-)initialization because the stream's (hardware) 194 * parameters did not change. 195 * @param pDevIns The device instance. 196 * @param pStream HDA stream to initialize. 197 * @param uSD SD (stream descriptor) number to assign the HDA stream to. 198 */ 199 int hdaR3StreamInit(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint8_t uSD) 200 { 201 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 202 203 PHDASTATE pThis = pStream->pHDAState; 204 AssertPtr(pThis); 206 * Sets up ((re-)iniitalizes) an HDA stream. 207 * 208 * @returns IPRT status code. VINF_NO_CHANGE if the stream does not need 209 * be set-up again because the stream's (hardware) parameters did 210 * not change. 211 * @param pDevIns The device instance. 212 * @param pThis The shared HDA device state (for HW register 213 * parameters). 214 * @param pStreamShared HDA stream to set up, shared portion. 215 * @param pStreamR3 HDA stream to set up, ring-3 portion. 216 * @param uSD Stream descriptor number to assign it. 217 */ 218 int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, uint8_t uSD) 219 { 220 /* These member can only change on data corruption, despite what the code does further down (bird). */ 221 Assert(pStreamShared->u8SD == uSD); 222 Assert(pStreamR3->u8SD == uSD); 205 223 206 224 const uint64_t u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, uSD), … … 232 250 233 251 /* Reset (any former) stream map. */ 234 hdaR3StreamMapReset(&pStream ->State.Mapping);252 hdaR3StreamMapReset(&pStreamR3->State.Mapping); 235 253 236 254 /* … … 242 260 * number of channels in a single audio stream. 243 261 */ 244 rc = hdaR3StreamMapInit(&pStream ->State.Mapping, &Props);262 rc = hdaR3StreamMapInit(&pStreamR3->State.Mapping, &Props); 245 263 AssertRCReturn(rc, rc); 246 264 247 ASSERT_GUEST_LOGREL_MSG_RETURN(u32CBL % pStream->State.Mapping.cbFrameSize == 0, 248 ("CBL for stream #%RU8 does not align to frame size\n", pStream->u8SD), 265 ASSERT_GUEST_LOGREL_MSG_RETURN( pStreamR3->State.Mapping.cbFrameSize > 0 266 && u32CBL % pStreamR3->State.Mapping.cbFrameSize == 0, 267 ("CBL for stream #%RU8 does not align to frame size (u32CBL=%u cbFrameSize=%u)\n", 268 uSD, u32CBL, pStreamR3->State.Mapping.cbFrameSize), 249 269 VERR_INVALID_PARAMETER); 250 270 … … 258 278 { 259 279 if (Props.cChannels >= 5) 260 pStream ->State.uTimerHz = 300;280 pStreamShared->State.uTimerHz = 300; 261 281 else if (Props.cChannels == 4) 262 pStream ->State.uTimerHz = 150;282 pStreamShared->State.uTimerHz = 150; 263 283 else 264 pStream ->State.uTimerHz = 100;284 pStreamShared->State.uTimerHz = 100; 265 285 } 266 286 else 267 pStream ->State.uTimerHz = pThis->uTimerHz;287 pStreamShared->State.uTimerHz = pThis->uTimerHz; 268 288 269 289 #ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND … … 286 306 * If not, we can skip a lot of the (re-)initialization and just (re-)use the existing stuff. 287 307 * Also, tell the caller so that further actions can be taken. */ 288 if ( uSD == pStream ->u8SD289 && u64BDLBase == pStream ->u64BDLBase290 && u16LVI == pStream ->u16LVI291 && u32CBL == pStream ->u32CBL292 && u16FIFOS == pStream ->u16FIFOS293 && u16FMT == pStream ->u16FMT)308 if ( uSD == pStreamShared->u8SD /* paranoia OFC */ 309 && u64BDLBase == pStreamShared->u64BDLBase 310 && u16LVI == pStreamShared->u16LVI 311 && u32CBL == pStreamShared->u32CBL 312 && u16FIFOS == pStreamShared->u16FIFOS 313 && u16FMT == pStreamShared->u16FMT) 294 314 { 295 315 LogFunc(("[SD%RU8] No format change, skipping (re-)initialization\n", uSD)); … … 297 317 } 298 318 299 pStream ->u8SD = uSD;319 pStreamShared->u8SD = uSD; 300 320 301 321 /* Update all register copies so that we later know that something has changed. */ 302 pStream ->u64BDLBase = u64BDLBase;303 pStream ->u16LVI = u16LVI;304 pStream ->u32CBL = u32CBL;305 pStream ->u16FIFOS = u16FIFOS;306 pStream ->u16FMT = u16FMT;307 308 PPDMAUDIOSTREAMCFG pCfg = &pStream ->State.Cfg;322 pStreamShared->u64BDLBase = u64BDLBase; 323 pStreamShared->u16LVI = u16LVI; 324 pStreamShared->u32CBL = u32CBL; 325 pStreamShared->u16FIFOS = u16FIFOS; 326 pStreamShared->u16FMT = u16FMT; 327 328 PPDMAUDIOSTREAMCFG pCfg = &pStreamShared->State.Cfg; 309 329 pCfg->Props = Props; 310 330 311 331 /* (Re-)Allocate the stream's internal DMA buffer, based on the PCM properties we just got above. */ 312 if (pStream ->State.pCircBuf)313 { 314 RTCircBufDestroy(pStream ->State.pCircBuf);315 pStream ->State.pCircBuf = NULL;332 if (pStreamR3->State.pCircBuf) 333 { 334 RTCircBufDestroy(pStreamR3->State.pCircBuf); 335 pStreamR3->State.pCircBuf = NULL; 316 336 } 317 337 318 338 /* By default we allocate an internal buffer of 100ms. */ 319 rc = RTCircBufCreate(&pStream ->State.pCircBuf,339 rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, 320 340 DrvAudioHlpMilliToBytes(100 /* ms */, &pCfg->Props)); /** @todo Make this configurable. */ 321 341 AssertRCReturn(rc, rc); 322 342 323 343 /* Set the stream's direction. */ 324 pCfg->enmDir = hdaGetDirFromSD( pStream->u8SD);344 pCfg->enmDir = hdaGetDirFromSD(uSD); 325 345 326 346 /* The the stream's name, based on the direction. */ … … 348 368 349 369 /* Set scheduling hint (if available). */ 350 if (pStream ->State.uTimerHz)351 pCfg->Device.cMsSchedulingHint = 1000 /* ms */ / pStream ->State.uTimerHz;370 if (pStreamShared->State.uTimerHz) 371 pCfg->Device.cMsSchedulingHint = 1000 /* ms */ / pStreamShared->State.uTimerHz; 352 372 353 373 LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n", 354 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS));374 uSD, pStreamShared->u64BDLBase, pStreamShared->u32CBL, pStreamShared->u16LVI, pStreamShared->u16FIFOS)); 355 375 356 376 if (RT_SUCCESS(rc)) 357 377 { 358 378 /* Make sure that the chosen Hz rate dividable by the stream's rate. */ 359 if (pStream ->State.Cfg.Props.uHz % pStream->State.uTimerHz != 0)379 if (pStreamShared->State.Cfg.Props.uHz % pStreamShared->State.uTimerHz != 0) 360 380 LogRel(("HDA: Stream timer Hz rate (%RU32) does not fit to stream #%RU8 timing (%RU32)\n", 361 pStream ->State.uTimerHz, pStream->u8SD, pStream->State.Cfg.Props.uHz));381 pStreamShared->State.uTimerHz, uSD, pStreamShared->State.Cfg.Props.uHz)); 362 382 363 383 /* Figure out how many transfer fragments we're going to use for this stream. */ 364 384 /** @todo Use a more dynamic fragment size? */ 365 uint8_t cFragments = pStream ->u16LVI + 1;385 uint8_t cFragments = pStreamShared->u16LVI + 1; 366 386 if (cFragments <= 1) 367 387 cFragments = 2; /* At least two fragments (BDLEs) must be present. */ … … 373 393 374 394 LogFunc(("[SD%RU8] fPosAdjustEnabled=%RTbool, cPosAdjustFrames=%RU16\n", 375 pStream->u8SD, pThis->fPosAdjustEnabled, pThis->cPosAdjustFrames));395 uSD, pThis->fPosAdjustEnabled, pThis->cPosAdjustFrames)); 376 396 377 397 if (pThis->fPosAdjustEnabled) /* Is the position adjustment enabled at all? */ … … 380 400 RT_ZERO(BDLE); 381 401 382 int rc2 = hdaR3BDLEFetch(p This, &BDLE, pStream->u64BDLBase, 0 /* Entry */);402 int rc2 = hdaR3BDLEFetch(pDevIns, &BDLE, pStreamShared->u64BDLBase, 0 /* Entry */); 383 403 AssertRC(rc2); 384 404 … … 400 420 #ifdef VBOX_WITH_INTEL_HDA 401 421 /* Intel ICH / PCH: 1 frame. */ 402 if (BDLE.Desc.u32BufSize == (uint32_t)(1 * pStream ->State.Mapping.cbFrameSize))422 if (BDLE.Desc.u32BufSize == (uint32_t)(1 * pStreamR3->State.Mapping.cbFrameSize)) 403 423 { 404 424 cfPosAdjust = 1; 405 425 } 406 426 /* Intel Baytrail / Braswell: 32 frames. */ 407 else if (BDLE.Desc.u32BufSize == (uint32_t)(32 * pStream ->State.Mapping.cbFrameSize))427 else if (BDLE.Desc.u32BufSize == (uint32_t)(32 * pStreamR3->State.Mapping.cbFrameSize)) 408 428 { 409 429 cfPosAdjust = 32; … … 426 446 * position adjustment. 427 447 */ 428 if ( (cfPosAdjust * pStream ->State.Mapping.cbFrameSize) == BDLE.Desc.u32BufSize448 if ( (cfPosAdjust * pStreamR3->State.Mapping.cbFrameSize) == BDLE.Desc.u32BufSize 429 449 && cFragments) 430 450 { … … 433 453 434 454 /* Initialize position adjustment counter. */ 435 pStream ->State.cfPosAdjustDefault = cfPosAdjust;436 pStream ->State.cfPosAdjustLeft = pStream->State.cfPosAdjustDefault;455 pStreamShared->State.cfPosAdjustDefault = cfPosAdjust; 456 pStreamShared->State.cfPosAdjustLeft = pStreamShared->State.cfPosAdjustDefault; 437 457 438 458 LogRel2(("HDA: Position adjustment for stream #%RU8 active (%RU32 frames)\n", 439 pStream->u8SD, pStream->State.cfPosAdjustDefault));459 uSD, pStreamShared->State.cfPosAdjustDefault)); 440 460 } 441 461 } 442 462 443 LogFunc(("[SD%RU8] cfPosAdjust=%RU32, cFragments=%RU8\n", pStream->u8SD, cfPosAdjust, cFragments));463 LogFunc(("[SD%RU8] cfPosAdjust=%RU32, cFragments=%RU8\n", uSD, cfPosAdjust, cFragments)); 444 464 445 465 /* … … 448 468 449 469 /* Calculate the fragment size the guest OS expects interrupt delivery at. */ 450 pStream ->State.cbTransferSize = pStream->u32CBL / cFragments;451 Assert(pStream ->State.cbTransferSize);452 Assert(pStream ->State.cbTransferSize % pStream->State.Mapping.cbFrameSize == 0);453 ASSERT_GUEST_LOGREL_MSG_STMT(pStream ->State.cbTransferSize,454 ("Transfer size for stream #%RU8 is invalid\n", pStream->u8SD), rc = VERR_INVALID_PARAMETER);470 pStreamShared->State.cbTransferSize = pStreamShared->u32CBL / cFragments; 471 Assert(pStreamShared->State.cbTransferSize); 472 Assert(pStreamShared->State.cbTransferSize % pStreamR3->State.Mapping.cbFrameSize == 0); 473 ASSERT_GUEST_LOGREL_MSG_STMT(pStreamShared->State.cbTransferSize, 474 ("Transfer size for stream #%RU8 is invalid\n", uSD), rc = VERR_INVALID_PARAMETER); 455 475 if (RT_SUCCESS(rc)) 456 476 { 457 477 /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration. 458 478 * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */ 459 pStream ->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pStream->State.uTimerHz) * pStream->State.Mapping.cbFrameSize;460 Assert(pStream ->State.cbTransferChunk);461 Assert(pStream ->State.cbTransferChunk % pStream->State.Mapping.cbFrameSize == 0);462 ASSERT_GUEST_LOGREL_MSG_STMT(pStream ->State.cbTransferChunk,463 ("Transfer chunk for stream #%RU8 is invalid\n", pStream->u8SD),479 pStreamShared->State.cbTransferChunk = (pStreamShared->State.Cfg.Props.uHz / pStreamShared->State.uTimerHz) * pStreamR3->State.Mapping.cbFrameSize; 480 Assert(pStreamShared->State.cbTransferChunk); 481 Assert(pStreamShared->State.cbTransferChunk % pStreamR3->State.Mapping.cbFrameSize == 0); 482 ASSERT_GUEST_LOGREL_MSG_STMT(pStreamShared->State.cbTransferChunk, 483 ("Transfer chunk for stream #%RU8 is invalid\n", uSD), 464 484 rc = VERR_INVALID_PARAMETER); 465 485 if (RT_SUCCESS(rc)) 466 486 { 467 487 /* Make sure that the transfer chunk does not exceed the overall transfer size. */ 468 if (pStream ->State.cbTransferChunk > pStream->State.cbTransferSize)469 pStream ->State.cbTransferChunk = pStream->State.cbTransferSize;470 471 const uint64_t cTicksPerHz = PDMDevHlpTimerGetFreq(pDevIns, pStream ->hTimer) / pStream->State.uTimerHz;488 if (pStreamShared->State.cbTransferChunk > pStreamShared->State.cbTransferSize) 489 pStreamShared->State.cbTransferChunk = pStreamShared->State.cbTransferSize; 490 491 const uint64_t cTicksPerHz = PDMDevHlpTimerGetFreq(pDevIns, pStreamShared->hTimer) / pStreamShared->State.uTimerHz; 472 492 473 493 /* Calculate the timer ticks per byte for this stream. */ 474 pStream ->State.cTicksPerByte = cTicksPerHz / pStream->State.cbTransferChunk;475 Assert(pStream ->State.cTicksPerByte);494 pStreamShared->State.cTicksPerByte = cTicksPerHz / pStreamShared->State.cbTransferChunk; 495 Assert(pStreamShared->State.cTicksPerByte); 476 496 477 497 /* Calculate timer ticks per transfer. */ 478 pStream ->State.cTransferTicks = pStream->State.cbTransferChunk * pStream->State.cTicksPerByte;479 Assert(pStream ->State.cTransferTicks);498 pStreamShared->State.cTransferTicks = pStreamShared->State.cbTransferChunk * pStreamShared->State.cTicksPerByte; 499 Assert(pStreamShared->State.cTransferTicks); 480 500 481 501 LogFunc(("[SD%RU8] Timer %uHz (%RU64 ticks per Hz), cTicksPerByte=%RU64, cbTransferChunk=%RU32, " \ 482 502 "cTransferTicks=%RU64, cbTransferSize=%RU32\n", 483 pStream->u8SD, pStream->State.uTimerHz, cTicksPerHz, pStream->State.cTicksPerByte,484 pStream ->State.cbTransferChunk, pStream->State.cTransferTicks, pStream->State.cbTransferSize));503 uSD, pStreamShared->State.uTimerHz, cTicksPerHz, pStreamShared->State.cTicksPerByte, 504 pStreamShared->State.cbTransferChunk, pStreamShared->State.cTransferTicks, pStreamShared->State.cbTransferSize)); 485 505 486 506 /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */ 487 hdaR3StreamSetPosition(pStream , HDA_STREAM_REG(pThis, LPIB, pStream->u8SD));507 hdaR3StreamSetPosition(pStreamShared, pDevIns, pThis, HDA_STREAM_REG(pThis, LPIB, uSD)); 488 508 489 509 #ifdef LOG_ENABLED 490 hdaR3BDLEDumpAll(p This, pStream->u64BDLBase, pStream->u16LVI + 1);510 hdaR3BDLEDumpAll(pDevIns, pThis, pStreamShared->u64BDLBase, pStreamShared->u16LVI + 1); 491 511 #endif 492 512 } … … 495 515 496 516 if (RT_FAILURE(rc)) 497 LogRel(("HDA: Initializing stream #%RU8 failed with %Rrc\n", pStream->u8SD, rc));517 LogRel(("HDA: Initializing stream #%RU8 failed with %Rrc\n", uSD, rc)); 498 518 499 519 return rc; … … 503 523 * Resets an HDA stream. 504 524 * 505 * @param pThis HDA state. 506 * @param pStream HDA stream to reset. 525 * @param pThis The shared HDA device state. 526 * @param pThisCC The ring-3 HDA device state. 527 * @param pStreamShared HDA stream to reset (shared). 528 * @param pStreamR3 HDA stream to reset (ring-3). 507 529 * @param uSD Stream descriptor (SD) number to use for this stream. 508 530 */ 509 void hdaR3StreamReset(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD) 510 { 511 AssertPtrReturnVoid(pThis); 512 AssertPtrReturnVoid(pStream); 513 AssertReturnVoid(uSD < HDA_MAX_STREAMS); 514 515 # ifdef VBOX_STRICT 516 AssertReleaseMsg(!pStream->State.fRunning, ("[SD%RU8] Cannot reset stream while in running state\n", uSD)); 517 # endif 531 void hdaR3StreamReset(PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, uint8_t uSD) 532 { 533 AssertPtr(pThis); 534 AssertPtr(pStreamShared); 535 AssertPtr(pStreamR3); 536 Assert(uSD < HDA_MAX_STREAMS); 537 AssertMsg(!pStreamShared->State.fRunning, ("[SD%RU8] Cannot reset stream while in running state\n", uSD)); 518 538 519 539 LogFunc(("[SD%RU8] Reset\n", uSD)); … … 522 542 * Set reset state. 523 543 */ 524 Assert(ASMAtomicReadBool(&pStream ->State.fInReset) == false); /* No nested calls. */525 ASMAtomicXchgBool(&pStream ->State.fInReset, true);544 Assert(ASMAtomicReadBool(&pStreamShared->State.fInReset) == false); /* No nested calls. */ 545 ASMAtomicXchgBool(&pStreamShared->State.fInReset, true); 526 546 527 547 /* … … 548 568 549 569 /* Assign the default mixer sink to the stream. */ 550 pStream ->pMixSink = hdaR3GetDefaultSink(pThis, uSD);570 pStreamR3->pMixSink = hdaR3GetDefaultSink(pThisCC, uSD); 551 571 552 572 /* Reset position adjustment counter. */ 553 pStream ->State.cfPosAdjustLeft = pStream->State.cfPosAdjustDefault;573 pStreamShared->State.cfPosAdjustLeft = pStreamShared->State.cfPosAdjustDefault; 554 574 555 575 /* Reset transfer stuff. */ 556 pStream ->State.cbTransferProcessed = 0;557 pStream ->State.cTransferPendingInterrupts = 0;558 pStream ->State.tsTransferLast = 0;559 pStream ->State.tsTransferNext = 0;576 pStreamShared->State.cbTransferProcessed = 0; 577 pStreamShared->State.cTransferPendingInterrupts = 0; 578 pStreamShared->State.tsTransferLast = 0; 579 pStreamShared->State.tsTransferNext = 0; 560 580 561 581 /* Initialize other timestamps. */ 562 pStream ->State.tsLastUpdateNs = 0;563 564 RT_ZERO(pStream ->State.BDLE);565 pStream ->State.uCurBDLE = 0;566 567 if (pStream ->State.pCircBuf)568 RTCircBufReset(pStream ->State.pCircBuf);582 pStreamShared->State.tsLastUpdateNs = 0; 583 584 RT_ZERO(pStreamShared->State.BDLE); 585 pStreamShared->State.uCurBDLE = 0; 586 587 if (pStreamR3->State.pCircBuf) 588 RTCircBufReset(pStreamR3->State.pCircBuf); 569 589 570 590 /* Reset the stream's period. */ 571 hdaR3StreamPeriodReset(&pStream ->State.Period);591 hdaR3StreamPeriodReset(&pStreamShared->State.Period); 572 592 573 593 #ifdef DEBUG 574 pStream ->Dbg.cReadsTotal = 0;575 pStream ->Dbg.cbReadTotal = 0;576 pStream ->Dbg.tsLastReadNs = 0;577 pStream ->Dbg.cWritesTotal = 0;578 pStream ->Dbg.cbWrittenTotal = 0;579 pStream ->Dbg.cWritesHz = 0;580 pStream ->Dbg.cbWrittenHz = 0;581 pStream ->Dbg.tsWriteSlotBegin = 0;594 pStreamR3->Dbg.cReadsTotal = 0; 595 pStreamR3->Dbg.cbReadTotal = 0; 596 pStreamR3->Dbg.tsLastReadNs = 0; 597 pStreamR3->Dbg.cWritesTotal = 0; 598 pStreamR3->Dbg.cbWrittenTotal = 0; 599 pStreamR3->Dbg.cWritesHz = 0; 600 pStreamR3->Dbg.cbWrittenHz = 0; 601 pStreamR3->Dbg.tsWriteSlotBegin = 0; 582 602 #endif 583 603 … … 588 608 589 609 /* Exit reset mode. */ 590 ASMAtomicXchgBool(&pStream ->State.fInReset, false);610 ASMAtomicXchgBool(&pStreamShared->State.fInReset, false); 591 611 } 592 612 … … 595 615 * 596 616 * @returns IPRT status code. 597 * @param pStream HDA stream to enable or disable. 617 * @param pStreamShared HDA stream to enable or disable - shared bits. 618 * @param pStreamR3 HDA stream to enable or disable - ring-3 bits. 598 619 * @param fEnable Whether to enable or disble the stream. 599 620 */ 600 int hdaR3StreamEnable(PHDASTREAM pStream, bool fEnable) 601 { 602 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 603 604 LogFunc(("[SD%RU8] fEnable=%RTbool, pMixSink=%p\n", pStream->u8SD, fEnable, pStream->pMixSink)); 621 int hdaR3StreamEnable(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fEnable) 622 { 623 AssertPtr(pStreamR3); 624 AssertPtr(pStreamShared); 625 626 LogFunc(("[SD%RU8] fEnable=%RTbool, pMixSink=%p\n", pStreamShared->u8SD, fEnable, pStreamR3->pMixSink)); 605 627 606 628 int rc = VINF_SUCCESS; … … 610 632 611 633 /* First, enable or disable the stream and the stream's sink, if any. */ 612 if ( pStream ->pMixSink613 && pStream ->pMixSink->pMixSink)614 rc = AudioMixerSinkCtl(pStream ->pMixSink->pMixSink, enmCmd);634 if ( pStreamR3->pMixSink 635 && pStreamR3->pMixSink->pMixSink) 636 rc = AudioMixerSinkCtl(pStreamR3->pMixSink->pMixSink, enmCmd); 615 637 616 638 if ( RT_SUCCESS(rc) 617 639 && fEnable 618 && pStream ->Dbg.Runtime.fEnabled)619 { 620 Assert(DrvAudioHlpPCMPropsAreValid(&pStream ->State.Cfg.Props));640 && pStreamR3->Dbg.Runtime.fEnabled) 641 { 642 Assert(DrvAudioHlpPCMPropsAreValid(&pStreamShared->State.Cfg.Props)); 621 643 622 644 if (fEnable) 623 645 { 624 if (!DrvAudioHlpFileIsOpen(pStream ->Dbg.Runtime.pFileStream))625 { 626 int rc2 = DrvAudioHlpFileOpen(pStream ->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,627 &pStream ->State.Cfg.Props);646 if (!DrvAudioHlpFileIsOpen(pStreamR3->Dbg.Runtime.pFileStream)) 647 { 648 int rc2 = DrvAudioHlpFileOpen(pStreamR3->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS, 649 &pStreamShared->State.Cfg.Props); 628 650 AssertRC(rc2); 629 651 } 630 652 631 if (!DrvAudioHlpFileIsOpen(pStream ->Dbg.Runtime.pFileDMARaw))632 { 633 int rc2 = DrvAudioHlpFileOpen(pStream ->Dbg.Runtime.pFileDMARaw, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,634 &pStream ->State.Cfg.Props);653 if (!DrvAudioHlpFileIsOpen(pStreamR3->Dbg.Runtime.pFileDMARaw)) 654 { 655 int rc2 = DrvAudioHlpFileOpen(pStreamR3->Dbg.Runtime.pFileDMARaw, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS, 656 &pStreamShared->State.Cfg.Props); 635 657 AssertRC(rc2); 636 658 } 637 659 638 if (!DrvAudioHlpFileIsOpen(pStream ->Dbg.Runtime.pFileDMAMapped))639 { 640 int rc2 = DrvAudioHlpFileOpen(pStream ->Dbg.Runtime.pFileDMAMapped, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,641 &pStream ->State.Cfg.Props);660 if (!DrvAudioHlpFileIsOpen(pStreamR3->Dbg.Runtime.pFileDMAMapped)) 661 { 662 int rc2 = DrvAudioHlpFileOpen(pStreamR3->Dbg.Runtime.pFileDMAMapped, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS, 663 &pStreamShared->State.Cfg.Props); 642 664 AssertRC(rc2); 643 665 } … … 647 669 if (RT_SUCCESS(rc)) 648 670 { 649 pStream ->State.fRunning = fEnable;650 } 651 652 LogFunc(("[SD%RU8] rc=%Rrc\n", pStream ->u8SD, rc));671 pStreamShared->State.fRunning = fEnable; 672 } 673 674 LogFunc(("[SD%RU8] rc=%Rrc\n", pStreamShared->u8SD, rc)); 653 675 return rc; 654 676 } 655 677 656 uint32_t hdaR3StreamGetPosition(PHDASTATE pThis, PHDASTREAM pStream)657 { 658 return HDA_STREAM_REG(pThis, LPIB, pStream ->u8SD);659 } 660 661 /* *678 static uint32_t hdaR3StreamGetPosition(PHDASTATE pThis, PHDASTREAM pStreamShared) 679 { 680 return HDA_STREAM_REG(pThis, LPIB, pStreamShared->u8SD); 681 } 682 683 /* 662 684 * Updates an HDA stream's current read or write buffer position (depending on the stream type) by 663 685 * updating its associated LPIB register and DMA position buffer (if enabled). 664 686 * 665 * @param pStream HDA stream to update read / write position for. 687 * @param pStreamShared HDA stream to update read / write position for (shared). 688 * @param pDevIns The device instance. 689 * @param pThis The shared HDA device state. 666 690 * @param u32LPIB Absolute position (in bytes) to set current read / write position to. 667 691 */ 668 void hdaR3StreamSetPosition(PHDASTREAM pStream, uint32_t u32LPIB) 669 { 670 AssertPtrReturnVoid(pStream); 671 672 Log3Func(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", 673 pStream->u8SD, u32LPIB, pStream->pHDAState->fDMAPosition)); 692 static void hdaR3StreamSetPosition(PHDASTREAM pStreamShared, PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t u32LPIB) 693 { 694 AssertPtrReturnVoid(pStreamShared); 695 696 Log3Func(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", pStreamShared->u8SD, u32LPIB, pThis->fDMAPosition)); 674 697 675 698 /* Update LPIB in any case. */ 676 HDA_STREAM_REG(p Stream->pHDAState, LPIB, pStream->u8SD) = u32LPIB;699 HDA_STREAM_REG(pThis, LPIB, pStreamShared->u8SD) = u32LPIB; 677 700 678 701 /* Do we need to tell the current DMA position? */ 679 if (p Stream->pHDAState->fDMAPosition)680 { 681 int rc2 = PDMDevHlpPCIPhysWrite(p Stream->pHDAState->CTX_SUFF(pDevIns),682 p Stream->pHDAState->u64DPBase + (pStream->u8SD * 2 * sizeof(uint32_t)),702 if (pThis->fDMAPosition) 703 { 704 int rc2 = PDMDevHlpPCIPhysWrite(pDevIns, 705 pThis->u64DPBase + (pStreamShared->u8SD * 2 * sizeof(uint32_t)), 683 706 (void *)&u32LPIB, sizeof(uint32_t)); 684 707 AssertRC(rc2); … … 690 713 * 691 714 * @returns Available data (in bytes). 692 * @param pStream HDA stream to retrieve size for. 693 */ 694 uint32_t hdaR3StreamGetUsed(PHDASTREAM pStream) 695 { 696 AssertPtrReturn(pStream, 0); 697 698 if (!pStream->State.pCircBuf) 699 return 0; 700 701 return (uint32_t)RTCircBufUsed(pStream->State.pCircBuf); 715 * @param pStreamR3 HDA stream to retrieve size for (ring-3). 716 */ 717 static uint32_t hdaR3StreamGetUsed(PHDASTREAMR3 pStreamR3) 718 { 719 AssertPtrReturn(pStreamR3, 0); 720 721 if (pStreamR3->State.pCircBuf) 722 return (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf); 723 return 0; 702 724 } 703 725 … … 706 728 * 707 729 * @returns Free data (in bytes). 708 * @param pStream HDA stream to retrieve size for. 709 */ 710 uint32_t hdaR3StreamGetFree(PHDASTREAM pStream) 711 { 712 AssertPtrReturn(pStream, 0); 713 714 if (!pStream->State.pCircBuf) 715 return 0; 716 717 return (uint32_t)RTCircBufFree(pStream->State.pCircBuf); 730 * @param pStreamR3 HDA stream to retrieve size for (ring-3). 731 */ 732 static uint32_t hdaR3StreamGetFree(PHDASTREAMR3 pStreamR3) 733 { 734 AssertPtrReturn(pStreamR3, 0); 735 736 if (pStreamR3->State.pCircBuf) 737 return (uint32_t)RTCircBufFree(pStreamR3->State.pCircBuf); 738 return 0; 718 739 } 719 740 … … 725 746 * 726 747 * @returns True if a next transfer is scheduled, false if not. 727 * @param pStream HDA stream to retrieve schedule status for.748 * @param pStreamShared HDA stream to retrieve schedule status for (shared). 728 749 * @param tsNow The current time. 729 750 */ 730 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStream, uint64_t tsNow) 731 { 732 if (pStream) 733 { 734 AssertPtrReturn(pStream->pHDAState, false); 735 736 if (pStream->State.fRunning) 737 { 738 if (pStream->State.cTransferPendingInterrupts) 739 { 740 Log3Func(("[SD%RU8] Scheduled (%RU8 IRQs pending)\n", pStream->u8SD, pStream->State.cTransferPendingInterrupts)); 751 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStreamShared, uint64_t tsNow) 752 { 753 if (pStreamShared) 754 { 755 if (pStreamShared->State.fRunning) 756 { 757 if (pStreamShared->State.cTransferPendingInterrupts) 758 { 759 Log3Func(("[SD%RU8] Scheduled (%RU8 IRQs pending)\n", pStreamShared->u8SD, pStreamShared->State.cTransferPendingInterrupts)); 741 760 return true; 742 761 } 743 762 744 if (pStream ->State.tsTransferNext > tsNow)745 { 746 Log3Func(("[SD%RU8] Scheduled in %RU64\n", pStream ->u8SD, pStream->State.tsTransferNext - tsNow));763 if (pStreamShared->State.tsTransferNext > tsNow) 764 { 765 Log3Func(("[SD%RU8] Scheduled in %RU64\n", pStreamShared->u8SD, pStreamShared->State.tsTransferNext - tsNow)); 747 766 return true; 748 767 } … … 757 776 * 758 777 * @returns The (virtual) clock timestamp of the next transfer. 759 * @param pStream HDA stream to retrieve timestamp for.760 */ 761 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStream )762 { 763 return pStream ->State.tsTransferNext;778 * @param pStreamShared HDA stream to retrieve timestamp for (shared). 779 */ 780 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStreamShared) 781 { 782 return pStreamShared->State.tsTransferNext; 764 783 } 765 784 … … 768 787 * 769 788 * @returns IPRT status code. 770 * @param pStream HDA stream to write to.789 * @param pStreamR3 HDA stream to write to (ring-3). 771 790 * @param pvBuf Data buffer to write. 772 791 * If NULL, silence will be written. … … 774 793 * @param pcbWritten Number of bytes written. Optional. 775 794 */ 776 int hdaR3StreamWrite(PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 777 { 778 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 779 /* pvBuf is optional. */ 780 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 781 /* pcbWritten is optional. */ 782 783 PRTCIRCBUF pCircBuf = pStream->State.pCircBuf; 795 static int hdaR3StreamWrite(PHDASTREAMR3 pStreamR3, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 796 { 797 Assert(cbBuf); 798 799 PRTCIRCBUF pCircBuf = pStreamR3->State.pCircBuf; 784 800 AssertPtr(pCircBuf); 785 786 int rc = VINF_SUCCESS;787 801 788 802 uint32_t cbWrittenTotal = 0; … … 793 807 void *pvDst; 794 808 size_t cbDst; 795 796 809 RTCircBufAcquireWriteBlock(pCircBuf, cbLeft, &pvDst, &cbDst); 797 810 … … 799 812 { 800 813 if (pvBuf) 801 {802 814 memcpy(pvDst, (uint8_t *)pvBuf + cbWrittenTotal, cbDst); 803 }804 815 else /* Send silence. */ 805 816 { … … 809 820 } 810 821 811 if (pStream->Dbg.Runtime.fEnabled) 812 DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileStream, pvDst, cbDst, 0 /* fFlags */); 822 if (RT_LIKELY(!pStreamR3->Dbg.Runtime.fEnabled)) 823 { /* likely */ } 824 else 825 DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileStream, pvDst, cbDst, 0 /* fFlags */); 813 826 } 814 827 815 828 RTCircBufReleaseWriteBlock(pCircBuf, cbDst); 816 817 if (RT_FAILURE(rc))818 break;819 829 820 830 Assert(cbLeft >= (uint32_t)cbDst); 821 831 cbLeft -= (uint32_t)cbDst; 822 823 832 cbWrittenTotal += (uint32_t)cbDst; 824 833 } … … 829 838 *pcbWritten = cbWrittenTotal; 830 839 831 return rc;840 return VINF_SUCCESS; 832 841 } 833 842 … … 837 846 * 838 847 * @returns IPRT status code. 839 * @param pStream HDA stream to read audio data from.848 * @param pStreamR3 HDA stream to read audio data from (ring-3). 840 849 * @param cbToRead Number of bytes to read. 841 850 * @param pcbRead Number of bytes read. Optional. 842 851 */ 843 int hdaR3StreamRead(PHDASTREAM pStream, uint32_t cbToRead, uint32_t *pcbRead) 844 { 845 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 846 AssertReturn(cbToRead, VERR_INVALID_PARAMETER); 847 /* pcbWritten is optional. */ 848 849 PHDAMIXERSINK pSink = pStream->pMixSink; 850 if (!pSink) 851 { 852 AssertMsgFailed(("[SD%RU8] Can't read from a stream with no sink attached\n", pStream->u8SD)); 853 854 if (pcbRead) 855 *pcbRead = 0; 856 return VINF_SUCCESS; 857 } 858 859 PRTCIRCBUF pCircBuf = pStream->State.pCircBuf; 852 static int hdaR3StreamRead(PHDASTREAMR3 pStreamR3, uint32_t cbToRead, uint32_t *pcbRead) 853 { 854 Assert(cbToRead); 855 856 PHDAMIXERSINK pSink = pStreamR3->pMixSink; 857 AssertMsgReturnStmt(pSink, ("[SD%RU8] Can't read from a stream with no sink attached\n", pStreamR3->u8SD), 858 if (pcbRead) *pcbRead = 0, 859 VINF_SUCCESS); 860 861 PRTCIRCBUF pCircBuf = pStreamR3->State.pCircBuf; 860 862 AssertPtr(pCircBuf); 861 863 … … 876 878 if (cbSrc) 877 879 { 878 if (pStream ->Dbg.Runtime.fEnabled)879 DrvAudioHlpFileWrite(pStream ->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */);880 if (pStreamR3->Dbg.Runtime.fEnabled) 881 DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */); 880 882 881 883 rc = AudioMixerSinkWrite(pSink->pMixSink, AUDMIXOP_COPY, pvSrc, (uint32_t)cbSrc, &cbWritten); … … 883 885 884 886 Assert(cbSrc >= cbWritten); 885 Log2Func(("[SD%RU8] %RU32/%zu bytes read\n", pStream ->u8SD, cbWritten, cbSrc));887 Log2Func(("[SD%RU8] %RU32/%zu bytes read\n", pStreamR3->u8SD, cbWritten, cbSrc)); 886 888 } 887 889 … … 915 917 * @returns IPRT status code. 916 918 * @param pDevIns The device instance. 917 * @param pStream HDA stream to update. 919 * @param pThis The shared HDA device state. 920 * @param pThisCC The ring-3 HDA device state. 921 * @param pStreamShared HDA stream to update (shared). 922 * @param pStreamR3 HDA stream to update (ring-3). 918 923 * @param cbToProcessMax How much data (in bytes) to process as maximum. 919 924 * @param fInTimer Set if we're in the timer callout. 920 925 */ 921 static int hdaR3StreamTransfer(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint32_t cbToProcessMax, bool fInTimer) 922 { 923 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 924 925 hdaR3StreamLock(pStream); 926 927 PHDASTATE pThis = pStream->pHDAState; 928 AssertPtr(pThis); 929 930 PHDASTREAMPERIOD pPeriod = &pStream->State.Period; 926 static int hdaR3StreamTransfer(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared, 927 PHDASTREAMR3 pStreamR3, uint32_t cbToProcessMax, bool fInTimer) 928 { 929 uint8_t const uSD = pStreamShared->u8SD; 930 hdaR3StreamLock(pStreamR3); 931 932 PHDASTREAMPERIOD pPeriod = &pStreamShared->State.Period; 931 933 hdaR3StreamPeriodLock(pPeriod); 932 934 … … 934 936 935 937 /* Stream not running? */ 936 if (!pStream ->State.fRunning)937 { 938 Log3Func(("[SD%RU8] Not running\n", pStream->u8SD));938 if (!pStreamShared->State.fRunning) 939 { 940 Log3Func(("[SD%RU8] Not running\n", uSD)); 939 941 fProceed = false; 940 942 } 941 else if (HDA_STREAM_REG(pThis, STS, pStream->u8SD) & HDA_SDSTS_BCIS)942 { 943 Log3Func(("[SD%RU8] BCIS bit set\n", pStream->u8SD));943 else if (HDA_STREAM_REG(pThis, STS, uSD) & HDA_SDSTS_BCIS) 944 { 945 Log3Func(("[SD%RU8] BCIS bit set\n", uSD)); 944 946 fProceed = false; 945 947 } … … 948 950 { 949 951 hdaR3StreamPeriodUnlock(pPeriod); 950 hdaR3StreamUnlock(pStream );952 hdaR3StreamUnlock(pStreamR3); 951 953 return VINF_SUCCESS; 952 954 } 953 955 954 const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream ->hTimer);955 956 if (!pStream ->State.tsTransferLast)957 pStream ->State.tsTransferLast = tsNow;956 const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); 957 958 if (!pStreamShared->State.tsTransferLast) 959 pStreamShared->State.tsTransferLast = tsNow; 958 960 959 961 #ifdef DEBUG 960 const int64_t iTimerDelta = tsNow - pStream ->State.tsTransferLast;962 const int64_t iTimerDelta = tsNow - pStreamShared->State.tsTransferLast; 961 963 Log3Func(("[SD%RU8] Time now=%RU64, last=%RU64 -> %RI64 ticks delta\n", 962 pStream->u8SD, tsNow, pStream->State.tsTransferLast, iTimerDelta));964 uSD, tsNow, pStreamShared->State.tsTransferLast, iTimerDelta)); 963 965 #endif 964 966 965 pStream ->State.tsTransferLast = tsNow;967 pStreamShared->State.tsTransferLast = tsNow; 966 968 967 969 /* Sanity checks. */ 968 Assert( pStream->u8SD < HDA_MAX_STREAMS);969 Assert(pStream ->u64BDLBase);970 Assert(pStream ->u32CBL);971 Assert(pStream ->u16FIFOS);970 Assert(uSD < HDA_MAX_STREAMS); 971 Assert(pStreamShared->u64BDLBase); 972 Assert(pStreamShared->u32CBL); 973 Assert(pStreamShared->u16FIFOS); 972 974 973 975 /* State sanity checks. */ 974 Assert(ASMAtomicReadBool(&pStream ->State.fInReset) == false);976 Assert(ASMAtomicReadBool(&pStreamShared->State.fInReset) == false); 975 977 976 978 int rc = VINF_SUCCESS; 977 979 978 980 /* Fetch first / next BDL entry. */ 979 PHDABDLE pBDLE = &pStream ->State.BDLE;981 PHDABDLE pBDLE = &pStreamShared->State.BDLE; 980 982 if (hdaR3BDLEIsComplete(pBDLE)) 981 983 { 982 rc = hdaR3BDLEFetch(p This, pBDLE, pStream->u64BDLBase, pStream->State.uCurBDLE);984 rc = hdaR3BDLEFetch(pDevIns, pBDLE, pStreamShared->u64BDLBase, pStreamShared->State.uCurBDLE); 983 985 AssertRC(rc); 984 986 } 985 987 986 uint32_t cbToProcess = RT_MIN(pStream ->State.cbTransferSize - pStream->State.cbTransferProcessed,987 pStream ->State.cbTransferChunk);988 989 Log3Func(("[SD%RU8] cbToProcess=%RU32, cbToProcessMax=%RU32\n", pStream->u8SD, cbToProcess, cbToProcessMax));988 uint32_t cbToProcess = RT_MIN(pStreamShared->State.cbTransferSize - pStreamShared->State.cbTransferProcessed, 989 pStreamShared->State.cbTransferChunk); 990 991 Log3Func(("[SD%RU8] cbToProcess=%RU32, cbToProcessMax=%RU32\n", uSD, cbToProcess, cbToProcessMax)); 990 992 991 993 if (cbToProcess > cbToProcessMax) 992 994 { 993 LogFunc(("[SD%RU8] Limiting transfer (cbToProcess=%RU32, cbToProcessMax=%RU32)\n", 994 pStream->u8SD, cbToProcess, cbToProcessMax)); 995 LogFunc(("[SD%RU8] Limiting transfer (cbToProcess=%RU32, cbToProcessMax=%RU32)\n", uSD, cbToProcess, cbToProcessMax)); 995 996 996 997 /* Never process more than a stream currently can handle. */ … … 1005 1006 { 1006 1007 /* Limit the chunk to the stream's FIFO size and what's left to process. */ 1007 uint32_t cbChunk = RT_MIN(cbLeft, pStream ->u16FIFOS);1008 uint32_t cbChunk = RT_MIN(cbLeft, pStreamShared->u16FIFOS); 1008 1009 1009 1010 /* Limit the chunk to the remaining data of the current BDLE. */ … … 1012 1013 /* If there are position adjustment frames left to be processed, 1013 1014 * make sure that we process them first as a whole. */ 1014 if (pStream ->State.cfPosAdjustLeft)1015 cbChunk = RT_MIN(cbChunk, uint32_t(pStream ->State.cfPosAdjustLeft * pStream->State.Mapping.cbFrameSize));1015 if (pStreamShared->State.cfPosAdjustLeft) 1016 cbChunk = RT_MIN(cbChunk, uint32_t(pStreamShared->State.cfPosAdjustLeft * pStreamR3->State.Mapping.cbFrameSize)); 1016 1017 1017 1018 Log3Func(("[SD%RU8] cbChunk=%RU32, cPosAdjustFramesLeft=%RU16\n", 1018 pStream->u8SD, cbChunk, pStream->State.cfPosAdjustLeft));1019 uSD, cbChunk, pStreamShared->State.cfPosAdjustLeft)); 1019 1020 1020 1021 if (!cbChunk) … … 1022 1023 1023 1024 uint32_t cbDMA = 0; 1024 PRTCIRCBUF pCircBuf = pStream ->State.pCircBuf;1025 1026 if (hdaGetDirFromSD( pStream->u8SD) == PDMAUDIODIR_IN) /* Input (SDI). */1025 PRTCIRCBUF pCircBuf = pStreamR3->State.pCircBuf; 1026 1027 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) /* Input (SDI). */ 1027 1028 { 1028 1029 STAM_PROFILE_START(&pThis->StatIn, a); … … 1054 1055 if (cbDMAToWrite) 1055 1056 { 1056 LogRel2(("HDA: FIFO underflow for stream #%RU8 (%RU32 bytes outstanding)\n", pStream->u8SD, cbDMAToWrite));1057 LogRel2(("HDA: FIFO underflow for stream #%RU8 (%RU32 bytes outstanding)\n", uSD, cbDMAToWrite)); 1057 1058 1058 1059 Assert(cbChunk == cbDMAWritten + cbDMAToWrite); … … 1061 1062 } 1062 1063 1063 rc = hdaR3DMAWrite(p This, pStream, abChunk, cbDMAWritten, &cbDMA /* pcbWritten */);1064 rc = hdaR3DMAWrite(pDevIns, pThis, pStreamShared, pStreamR3, abChunk, cbDMAWritten, &cbDMA /* pcbWritten */); 1064 1065 if (RT_FAILURE(rc)) 1065 LogRel(("HDA: Writing to stream #%RU8 DMA failed with %Rrc\n", pStream->u8SD, rc));1066 LogRel(("HDA: Writing to stream #%RU8 DMA failed with %Rrc\n", uSD, rc)); 1066 1067 1067 1068 STAM_PROFILE_STOP(&pThis->StatIn, a); 1068 1069 } 1069 else if (hdaGetDirFromSD( pStream->u8SD) == PDMAUDIODIR_OUT) /* Output (SDO). */1070 else if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) /* Output (SDO). */ 1070 1071 { 1071 1072 STAM_PROFILE_START(&pThis->StatOut, a); 1072 1073 1073 rc = hdaR3DMARead(p This, pStream, abChunk, cbChunk, &cbDMA /* pcbRead */);1074 rc = hdaR3DMARead(pDevIns, pThis, pStreamShared, pStreamR3, abChunk, cbChunk, &cbDMA /* pcbRead */); 1074 1075 if (RT_SUCCESS(rc)) 1075 1076 { … … 1083 1084 * Only macOS guests need the frame extraction branch below at the moment AFAIK. 1084 1085 */ 1085 if (pStream ->State.Mapping.cbFrameSize == HDA_FRAME_SIZE_DEFAULT)1086 if (pStreamR3->State.Mapping.cbFrameSize == HDA_FRAME_SIZE_DEFAULT) 1086 1087 { 1087 1088 uint32_t cbDMARead = 0; … … 1119 1120 */ 1120 1121 /** @todo Optimize channel data extraction! Use some SSE(3) / intrinsics? */ 1121 for (unsigned m = 0; m < pStream ->State.Mapping.cMappings; m++)1122 for (unsigned m = 0; m < pStreamR3->State.Mapping.cMappings; m++) 1122 1123 { 1123 const uint32_t cbFrame = pStream ->State.Mapping.cbFrameSize;1124 const uint32_t cbFrame = pStreamR3->State.Mapping.cbFrameSize; 1124 1125 1125 1126 Assert(cbFree >= cbDMA); 1126 1127 1127 PPDMAUDIOSTREAMMAP pMap = &pStream ->State.Mapping.paMappings[m];1128 PPDMAUDIOSTREAMMAP pMap = &pStreamR3->State.Mapping.paMappings[m]; 1128 1129 AssertPtr(pMap); 1129 1130 … … 1150 1151 1151 1152 #if 0 /* Too slow, even for release builds, so disabled it. */ 1152 if (pStream ->Dbg.Runtime.fEnabled)1153 DrvAudioHlpFileWrite(pStream ->Dbg.Runtime.pFileDMAMapped, pvDstBuf, cbDstBuf,1153 if (pStreamR3->Dbg.Runtime.fEnabled) 1154 DrvAudioHlpFileWrite(pStreamR3->Dbg.Runtime.pFileDMAMapped, pvDstBuf, cbDstBuf, 1154 1155 0 /* fFlags */); 1155 1156 #endif … … 1200 1201 } 1201 1202 else 1202 LogRel(("HDA: Reading from stream #%RU8 DMA failed with %Rrc\n", pStream->u8SD, rc));1203 LogRel(("HDA: Reading from stream #%RU8 DMA failed with %Rrc\n", uSD, rc)); 1203 1204 1204 1205 STAM_PROFILE_STOP(&pThis->StatOut, a); … … 1217 1218 /* Are we done doing the position adjustment? 1218 1219 * Only then do the transfer accounting .*/ 1219 if (pStream ->State.cfPosAdjustLeft == 0)1220 if (pStreamShared->State.cfPosAdjustLeft == 0) 1220 1221 { 1221 1222 Assert(cbLeft >= cbDMA); … … 1230 1231 * All guetsts rely on this, depending on the mechanism they use (LPIB register or DMA counters). 1231 1232 */ 1232 uint32_t cbStreamPos = hdaR3StreamGetPosition(pThis, pStream );1233 if (cbStreamPos == pStream ->u32CBL)1233 uint32_t cbStreamPos = hdaR3StreamGetPosition(pThis, pStreamShared); 1234 if (cbStreamPos == pStreamShared->u32CBL) 1234 1235 cbStreamPos = 0; 1235 1236 1236 hdaR3StreamSetPosition(pStream , cbStreamPos + cbDMA);1237 hdaR3StreamSetPosition(pStreamShared, pDevIns, pThis, cbStreamPos + cbDMA); 1237 1238 } 1238 1239 1239 1240 if (hdaR3BDLEIsComplete(pBDLE)) 1240 1241 { 1241 Log3Func(("[SD%RU8] Complete: %R[bdle]\n", pStream->u8SD, pBDLE));1242 Log3Func(("[SD%RU8] Complete: %R[bdle]\n", uSD, pBDLE)); 1242 1243 1243 1244 /* Does the current BDLE require an interrupt to be sent? */ … … 1248 1249 * 1249 1250 * In such a case we need to skip such an interrupt and just move on. */ 1250 && pStream ->State.cfPosAdjustLeft == 0)1251 && pStreamShared->State.cfPosAdjustLeft == 0) 1251 1252 { 1252 1253 /* If the IOCE ("Interrupt On Completion Enable") bit of the SDCTL register is set 1253 1254 * we need to generate an interrupt. 1254 1255 */ 1255 if (HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_SDCTL_IOCE)1256 if (HDA_STREAM_REG(pThis, CTL, uSD) & HDA_SDCTL_IOCE) 1256 1257 { 1257 pStream ->State.cTransferPendingInterrupts++;1258 1259 AssertMsg(pStream ->State.cTransferPendingInterrupts <= 32,1258 pStreamShared->State.cTransferPendingInterrupts++; 1259 1260 AssertMsg(pStreamShared->State.cTransferPendingInterrupts <= 32, 1260 1261 ("Too many pending interrupts (%RU8) for stream #%RU8\n", 1261 pStream ->State.cTransferPendingInterrupts, pStream->u8SD));1262 pStreamShared->State.cTransferPendingInterrupts, uSD)); 1262 1263 } 1263 1264 } 1264 1265 1265 if (pStream ->State.uCurBDLE == pStream->u16LVI)1266 { 1267 pStream ->State.uCurBDLE = 0;1266 if (pStreamShared->State.uCurBDLE == pStreamShared->u16LVI) 1267 { 1268 pStreamShared->State.uCurBDLE = 0; 1268 1269 } 1269 1270 else 1270 pStream ->State.uCurBDLE++;1271 pStreamShared->State.uCurBDLE++; 1271 1272 1272 1273 /* Fetch the next BDLE entry. */ 1273 hdaR3BDLEFetch(p This, pBDLE, pStream->u64BDLBase, pStream->State.uCurBDLE);1274 hdaR3BDLEFetch(pDevIns, pBDLE, pStreamShared->u64BDLBase, pStreamShared->State.uCurBDLE); 1274 1275 } 1275 1276 1276 1277 /* Do the position adjustment accounting. */ 1277 pStream ->State.cfPosAdjustLeft -=1278 RT_MIN(pStream ->State.cfPosAdjustLeft, cbDMA / pStream->State.Mapping.cbFrameSize);1278 pStreamShared->State.cfPosAdjustLeft -= 1279 RT_MIN(pStreamShared->State.cfPosAdjustLeft, cbDMA / pStreamR3->State.Mapping.cbFrameSize); 1279 1280 1280 1281 if (RT_FAILURE(rc)) … … 1283 1284 1284 1285 Log3Func(("[SD%RU8] cbToProcess=%RU32, cbProcessed=%RU32, cbLeft=%RU32, %R[bdle], rc=%Rrc\n", 1285 pStream->u8SD, cbToProcess, cbProcessed, cbLeft, pBDLE, rc));1286 uSD, cbToProcess, cbProcessed, cbLeft, pBDLE, rc)); 1286 1287 1287 1288 /* Sanity. */ … … 1291 1292 /* Only do the data accounting if we don't have to do any position 1292 1293 * adjustment anymore. */ 1293 if (pStream ->State.cfPosAdjustLeft == 0)1294 { 1295 hdaR3StreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStream ->State.Mapping.cbFrameSize,1294 if (pStreamShared->State.cfPosAdjustLeft == 0) 1295 { 1296 hdaR3StreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStreamR3->State.Mapping.cbFrameSize, 1296 1297 hdaR3StreamPeriodGetRemainingFrames(pPeriod))); 1297 1298 1298 pStream ->State.cbTransferProcessed += cbProcessed;1299 pStreamShared->State.cbTransferProcessed += cbProcessed; 1299 1300 } 1300 1301 1301 1302 /* Make sure that we never report more stuff processed than initially announced. */ 1302 if (pStream ->State.cbTransferProcessed > pStream->State.cbTransferSize)1303 pStream ->State.cbTransferProcessed = pStream->State.cbTransferSize;1304 1305 uint32_t cbTransferLeft = pStream ->State.cbTransferSize - pStream->State.cbTransferProcessed;1303 if (pStreamShared->State.cbTransferProcessed > pStreamShared->State.cbTransferSize) 1304 pStreamShared->State.cbTransferProcessed = pStreamShared->State.cbTransferSize; 1305 1306 uint32_t cbTransferLeft = pStreamShared->State.cbTransferSize - pStreamShared->State.cbTransferProcessed; 1306 1307 bool fTransferComplete = !cbTransferLeft; 1307 1308 uint64_t tsTransferNext = 0; … … 1321 1322 * sound output. Running VLC on the guest will tell! 1322 1323 */ 1323 const bool fWalClkSet = hdaR3WalClkSet(pThis, 1324 const bool fWalClkSet = hdaR3WalClkSet(pThis, pThisCC, 1324 1325 hdaWalClkGetCurrent(pThis) 1325 1326 + hdaR3StreamPeriodFramesToWalClk(pPeriod, 1326 pStream ->State.cbTransferProcessed1327 / pStream ->State.Mapping.cbFrameSize),1327 pStreamShared->State.cbTransferProcessed 1328 / pStreamR3->State.Mapping.cbFrameSize), 1328 1329 false /* fForce */); 1329 1330 RT_NOREF(fWalClkSet); … … 1331 1332 1332 1333 /* Does the period have any interrupts outstanding? */ 1333 if (pStream ->State.cTransferPendingInterrupts)1334 { 1335 Log3Func(("[SD%RU8] Scheduling interrupt\n", pStream->u8SD));1334 if (pStreamShared->State.cTransferPendingInterrupts) 1335 { 1336 Log3Func(("[SD%RU8] Scheduling interrupt\n", uSD)); 1336 1337 1337 1338 /* … … 1346 1347 * snd_hda_intel on Linux will tell. 1347 1348 */ 1348 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_SDSTS_BCIS;1349 HDA_STREAM_REG(pThis, STS, uSD) |= HDA_SDSTS_BCIS; 1349 1350 1350 1351 /* Trigger an interrupt first and let hdaRegWriteSDSTS() deal with 1351 1352 * ending / beginning a period. */ 1352 HDA_PROCESS_INTERRUPT(p This->pDevInsR3, pThis);1353 HDA_PROCESS_INTERRUPT(pDevIns, pThis); 1353 1354 } 1354 1355 else /* Transfer still in-flight -- schedule the next timing slot. */ … … 1359 1360 * than we can transfer per timing slot? Clamp. */ 1360 1361 if ( !cbTransferNext 1361 || cbTransferNext > pStream ->State.cbTransferChunk)1362 { 1363 cbTransferNext = pStream ->State.cbTransferChunk;1362 || cbTransferNext > pStreamShared->State.cbTransferChunk) 1363 { 1364 cbTransferNext = pStreamShared->State.cbTransferChunk; 1364 1365 } 1365 1366 1366 tsTransferNext = tsNow + (cbTransferNext * pStream ->State.cTicksPerByte);1367 tsTransferNext = tsNow + (cbTransferNext * pStreamShared->State.cTicksPerByte); 1367 1368 1368 1369 /* … … 1374 1375 */ 1375 1376 if (fTransferComplete) 1376 pStream ->State.cbTransferProcessed = 0;1377 pStreamShared->State.cbTransferProcessed = 0; 1377 1378 } 1378 1379 … … 1380 1381 if (tsTransferNext) /* Can be 0 if no next transfer is needed. */ 1381 1382 { 1382 Log3Func(("[SD%RU8] Scheduling timer\n", pStream->u8SD)); 1383 1384 LogFunc(("Timer set SD%RU8\n", pStream->u8SD)); 1385 Assert(!fInTimer || tsNow == PDMDevHlpTimerGet(pDevIns, pStream->hTimer)); 1386 hdaR3TimerSet(pDevIns, pStream, tsTransferNext, true /* fForce - skip tsTransferNext check */, fInTimer ? tsNow : 0); 1387 1388 pStream->State.tsTransferNext = tsTransferNext; 1389 } 1390 1391 pStream->State.tsTransferLast = tsNow; 1383 Log3Func(("[SD%RU8] Scheduling timer\n", uSD)); 1384 1385 LogFunc(("Timer set SD%RU8\n", uSD)); 1386 Assert(!fInTimer || tsNow == PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer)); 1387 hdaR3TimerSet(pDevIns, pStreamShared, tsTransferNext, 1388 true /* fForce - skip tsTransferNext check */, fInTimer ? tsNow : 0); 1389 1390 pStreamShared->State.tsTransferNext = tsTransferNext; 1391 } 1392 1393 pStreamShared->State.tsTransferLast = tsNow; 1392 1394 1393 1395 Log3Func(("[SD%RU8] cbTransferLeft=%RU32 -- %RU32/%RU32\n", 1394 pStream->u8SD, cbTransferLeft, pStream->State.cbTransferProcessed, pStream->State.cbTransferSize));1396 uSD, cbTransferLeft, pStreamShared->State.cbTransferProcessed, pStreamShared->State.cbTransferSize)); 1395 1397 Log3Func(("[SD%RU8] fTransferComplete=%RTbool, cTransferPendingInterrupts=%RU8\n", 1396 pStream->u8SD, fTransferComplete, pStream->State.cTransferPendingInterrupts));1398 uSD, fTransferComplete, pStreamShared->State.cTransferPendingInterrupts)); 1397 1399 Log3Func(("[SD%RU8] tsNow=%RU64, tsTransferNext=%RU64 (in %RU64 ticks)\n", 1398 pStream->u8SD, tsNow, tsTransferNext, tsTransferNext - tsNow));1400 uSD, tsNow, tsTransferNext, tsTransferNext - tsNow)); 1399 1401 1400 1402 hdaR3StreamPeriodUnlock(pPeriod); 1401 hdaR3StreamUnlock(pStream );1403 hdaR3StreamUnlock(pStreamR3); 1402 1404 1403 1405 return VINF_SUCCESS; … … 1421 1423 * (with fInTimer set to @c false). 1422 1424 * 1423 * @param pDevIns The device instance. 1424 * @param pStream HDA stream to update. 1425 * @param fInTimer Whether to this function was called from the timer 1426 * context or an asynchronous I/O stream thread (if supported). 1427 */ 1428 void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTREAM pStream, bool fInTimer) 1429 { 1430 if (!pStream) 1425 * @param pDevIns The device instance. 1426 * @param pThis The shared HDA device state. 1427 * @param pThisCC The ring-3 HDA device state. 1428 * @param pStreamShared HDA stream to update (shared bits). 1429 * @param pStreamR3 HDA stream to update (ring-3 bits). 1430 * @param fInTimer Whether to this function was called from the timer 1431 * context or an asynchronous I/O stream thread (if supported). 1432 */ 1433 void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, 1434 PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fInTimer) 1435 { 1436 if (!pStreamShared) 1431 1437 return; 1432 1438 1433 1439 PAUDMIXSINK pSink = NULL; 1434 if ( pStream->pMixSink 1435 && pStream->pMixSink->pMixSink) 1436 { 1437 pSink = pStream->pMixSink->pMixSink; 1438 } 1440 if (pStreamR3->pMixSink) 1441 pSink = pStreamR3->pMixSink->pMixSink; 1439 1442 1440 1443 if (!AudioMixerSinkIsActive(pSink)) /* No sink available? Bail out. */ … … 1443 1446 int rc2; 1444 1447 1445 if (hdaGetDirFromSD(pStream ->u8SD) == PDMAUDIODIR_OUT) /* Output (SDO). */1448 if (hdaGetDirFromSD(pStreamShared->u8SD) == PDMAUDIODIR_OUT) /* Output (SDO). */ 1446 1449 { 1447 1450 bool fDoRead = false; /* Whether to read from the HDA stream or not. */ … … 1451 1454 # endif 1452 1455 { 1453 const uint32_t cbStreamFree = hdaR3StreamGetFree(pStream );1456 const uint32_t cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1454 1457 if (cbStreamFree) 1455 1458 { 1456 1459 /* Do the DMA transfer. */ 1457 rc2 = hdaR3StreamTransfer(pDevIns, p Stream, cbStreamFree, fInTimer);1460 rc2 = hdaR3StreamTransfer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, cbStreamFree, fInTimer); 1458 1461 AssertRC(rc2); 1459 1462 } … … 1461 1464 /* Only read from the HDA stream at the given scheduling rate. */ 1462 1465 const uint64_t tsNowNs = RTTimeNanoTS(); 1463 if (tsNowNs - pStream ->State.tsLastUpdateNs >= pStream->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)1466 if (tsNowNs - pStreamShared->State.tsLastUpdateNs >= pStreamShared->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS) 1464 1467 { 1465 1468 fDoRead = true; 1466 pStream ->State.tsLastUpdateNs = tsNowNs;1469 pStreamShared->State.tsLastUpdateNs = tsNowNs; 1467 1470 } 1468 1471 } 1469 1472 1470 Log3Func(("[SD%RU8] fInTimer=%RTbool, fDoRead=%RTbool\n", pStream ->u8SD, fInTimer, fDoRead));1473 Log3Func(("[SD%RU8] fInTimer=%RTbool, fDoRead=%RTbool\n", pStreamShared->u8SD, fInTimer, fDoRead)); 1471 1474 1472 1475 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1473 1476 if (fDoRead) 1474 1477 { 1475 rc2 = hdaR3StreamAsyncIONotify(pStream );1478 rc2 = hdaR3StreamAsyncIONotify(pStreamR3); 1476 1479 AssertRC(rc2); 1477 1480 } … … 1486 1489 # endif 1487 1490 const uint32_t cbSinkWritable = AudioMixerSinkGetWritable(pSink); 1488 const uint32_t cbStreamReadable = hdaR3StreamGetUsed(pStream );1491 const uint32_t cbStreamReadable = hdaR3StreamGetUsed(pStreamR3); 1489 1492 const uint32_t cbToReadFromStream = RT_MIN(cbStreamReadable, cbSinkWritable); 1490 1493 1491 Log3Func(("[SD%RU8] cbSinkWritable=%RU32, cbStreamReadable=%RU32\n", pStream ->u8SD, cbSinkWritable, cbStreamReadable));1494 Log3Func(("[SD%RU8] cbSinkWritable=%RU32, cbStreamReadable=%RU32\n", pStreamShared->u8SD, cbSinkWritable, cbStreamReadable)); 1492 1495 1493 1496 if (cbToReadFromStream) 1494 1497 { 1495 1498 /* Read (guest output) data and write it to the stream's sink. */ 1496 rc2 = hdaR3StreamRead(pStream , cbToReadFromStream, NULL /* pcbRead */);1499 rc2 = hdaR3StreamRead(pStreamR3, cbToReadFromStream, NULL /* pcbRead */); 1497 1500 AssertRC(rc2); 1498 1501 } … … 1517 1520 1518 1521 /* How much (guest input) data is available for writing at the moment for the HDA stream? */ 1519 const uint32_t cbStreamFree = hdaR3StreamGetFree(pStream );1520 1521 Log3Func(("[SD%RU8] cbSinkReadable=%RU32, cbStreamFree=%RU32\n", pStream ->u8SD, cbSinkReadable, cbStreamFree));1522 const uint32_t cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1523 1524 Log3Func(("[SD%RU8] cbSinkReadable=%RU32, cbStreamFree=%RU32\n", pStreamShared->u8SD, cbSinkReadable, cbStreamFree)); 1522 1525 1523 1526 /* Do not read more than the HDA stream can hold at the moment. … … 1544 1547 /* Write (guest input) data to the stream which was read from stream's sink before. */ 1545 1548 uint32_t cbWritten; 1546 rc2 = hdaR3StreamWrite(pStream , abFIFO, cbRead, &cbWritten);1549 rc2 = hdaR3StreamWrite(pStreamR3, abFIFO, cbRead, &cbWritten); 1547 1550 AssertRCBreak(rc2); 1548 1549 if (!cbWritten) 1550 { 1551 AssertFailed(); /* Should never happen, as we know how much we can write. */ 1552 break; 1553 } 1551 AssertBreak(cbWritten > 0); /* Should never happen, as we know how much we can write. */ 1554 1552 1555 1553 Assert(cbSinkReadable >= cbRead); … … 1565 1563 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1566 1564 const uint64_t tsNowNs = RTTimeNanoTS(); 1567 if (tsNowNs - pStream ->State.tsLastUpdateNs >= pStream->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)1568 { 1569 rc2 = hdaR3StreamAsyncIONotify(pStream );1565 if (tsNowNs - pStreamShared->State.tsLastUpdateNs >= pStreamShared->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS) 1566 { 1567 rc2 = hdaR3StreamAsyncIONotify(pStreamR3); 1570 1568 AssertRC(rc2); 1571 1569 1572 pStream ->State.tsLastUpdateNs = tsNowNs;1570 pStreamShared->State.tsLastUpdateNs = tsNowNs; 1573 1571 } 1574 1572 # endif 1575 const uint32_t cbStreamUsed = hdaR3StreamGetUsed(pStream );1573 const uint32_t cbStreamUsed = hdaR3StreamGetUsed(pStreamR3); 1576 1574 if (cbStreamUsed) 1577 1575 { 1578 rc2 = hdaR3StreamTransfer(pDevIns, p Stream, cbStreamUsed, fInTimer);1576 rc2 = hdaR3StreamTransfer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, cbStreamUsed, fInTimer); 1579 1577 AssertRC(rc2); 1580 1578 } … … 1589 1587 * 1590 1588 * @returns IPRT status code. 1591 * @param pStream HDA stream to lock.1592 */ 1593 void hdaR3StreamLock(PHDASTREAM pStream)1594 { 1595 AssertPtrReturnVoid(pStream );1589 * @param pStreamR3 HDA stream to lock (ring-3 bits). 1590 */ 1591 void hdaR3StreamLock(PHDASTREAMR3 pStreamR3) 1592 { 1593 AssertPtrReturnVoid(pStreamR3); 1596 1594 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1597 int rc2 = RTCritSectEnter(&pStream ->CritSect);1595 int rc2 = RTCritSectEnter(&pStreamR3->CritSect); 1598 1596 AssertRC(rc2); 1599 1597 # else … … 1606 1604 * 1607 1605 * @returns IPRT status code. 1608 * @param pStream HDA stream to unlock.1609 */ 1610 void hdaR3StreamUnlock(PHDASTREAM pStream)1611 { 1612 AssertPtrReturnVoid(pStream );1606 * @param pStreamR3 HDA stream to unlock (ring-3 bits). 1607 */ 1608 void hdaR3StreamUnlock(PHDASTREAMR3 pStreamR3) 1609 { 1610 AssertPtrReturnVoid(pStreamR3); 1613 1611 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1614 int rc2 = RTCritSectLeave(&pStream ->CritSect);1612 int rc2 = RTCritSectLeave(&pStreamR3->CritSect); 1615 1613 AssertRC(rc2); 1616 1614 # endif 1617 1615 } 1618 1616 1617 #if 0 /* unused - no prototype even */ 1619 1618 /** 1620 1619 * Updates an HDA stream's current read or write buffer position (depending on the stream type) by … … 1622 1621 * 1623 1622 * @returns Set LPIB value. 1623 * @param pDevIns The device instance. 1624 1624 * @param pStream HDA stream to update read / write position for. 1625 1625 * @param u32LPIB New LPIB (position) value to set. 1626 1626 */ 1627 uint32_t hdaR3StreamUpdateLPIB(PHDASTREAM pStream, uint32_t u32LPIB) 1628 { 1629 AssertPtrReturn(pStream, 0); 1630 1631 AssertMsg(u32LPIB <= pStream->u32CBL, 1632 ("[SD%RU8] New LPIB (%RU32) exceeds CBL (%RU32)\n", pStream->u8SD, u32LPIB, pStream->u32CBL)); 1633 1634 const PHDASTATE pThis = pStream->pHDAState; 1635 1636 u32LPIB = RT_MIN(u32LPIB, pStream->u32CBL); 1627 uint32_t hdaR3StreamUpdateLPIB(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, uint32_t u32LPIB) 1628 { 1629 AssertMsg(u32LPIB <= pStreamShared->u32CBL, 1630 ("[SD%RU8] New LPIB (%RU32) exceeds CBL (%RU32)\n", pStreamShared->u8SD, u32LPIB, pStreamShared->u32CBL)); 1631 1632 u32LPIB = RT_MIN(u32LPIB, pStreamShared->u32CBL); 1637 1633 1638 1634 LogFlowFunc(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", 1639 pStream ->u8SD, u32LPIB, pThis->fDMAPosition));1635 pStreamShared->u8SD, u32LPIB, pThis->fDMAPosition)); 1640 1636 1641 1637 /* Update LPIB in any case. */ 1642 HDA_STREAM_REG(pThis, LPIB, pStream ->u8SD) = u32LPIB;1638 HDA_STREAM_REG(pThis, LPIB, pStreamShared->u8SD) = u32LPIB; 1643 1639 1644 1640 /* Do we need to tell the current DMA position? */ 1645 1641 if (pThis->fDMAPosition) 1646 1642 { 1647 int rc2 = PDMDevHlpPCIPhysWrite(p This->CTX_SUFF(pDevIns),1648 pThis->u64DPBase + (pStream ->u8SD * 2 * sizeof(uint32_t)),1643 int rc2 = PDMDevHlpPCIPhysWrite(pDevIns, 1644 pThis->u64DPBase + (pStreamShared->u8SD * 2 * sizeof(uint32_t)), 1649 1645 (void *)&u32LPIB, sizeof(uint32_t)); 1650 1646 AssertRC(rc2); … … 1653 1649 return u32LPIB; 1654 1650 } 1651 #endif 1655 1652 1656 1653 # ifdef HDA_USE_DMA_ACCESS_HANDLER … … 1664 1661 { 1665 1662 /* At least LVI and the BDL base must be set. */ 1666 if ( !pStream ->u16LVI1667 || !pStream ->u64BDLBase)1663 if ( !pStreamShared->u16LVI 1664 || !pStreamShared->u64BDLBase) 1668 1665 { 1669 1666 return false; … … 1688 1685 size_t cRanges = 0; 1689 1686 1690 for (uint16_t i = 0; i < pStream ->u16LVI + 1; i++)1687 for (uint16_t i = 0; i < pStreamShared->u16LVI + 1; i++) 1691 1688 { 1692 1689 HDABDLE BDLE; 1693 rc = hdaR3BDLEFetch(p This, &BDLE, pStream->u64BDLBase, i /* Index */);1690 rc = hdaR3BDLEFetch(pDevIns, &BDLE, pStreamShared->u64BDLBase, i /* Index */); 1694 1691 if (RT_FAILURE(rc)) 1695 1692 break; … … 1827 1824 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1828 1825 /** 1826 * @callback_method_impl{FNRTTHREAD, 1829 1827 * Asynchronous I/O thread for a HDA stream. 1830 * This will do the heavy lifting work for us as soon as it's getting notified by another thread. 1831 * 1832 * @returns IPRT status code. 1833 * @param hThreadSelf Thread handle. 1834 * @param pvUser User argument. Must be of type PHDASTREAMTHREADCTX. 1835 */ 1836 DECLCALLBACK(int) hdaR3StreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser) 1837 { 1838 PHDASTREAMTHREADCTX pCtx = (PHDASTREAMTHREADCTX)pvUser; 1839 AssertPtr(pCtx); 1840 PHDASTREAM pStream = pCtx->pStream; 1841 1842 AssertPtr(pStream); 1843 PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO; 1844 1845 PPDMDEVINS pDevIns = pCtx->pThis->pDevInsR3; 1846 1828 * 1829 * This will do the heavy lifting work for us as soon as it's getting notified 1830 * by another thread.} 1831 */ 1832 static DECLCALLBACK(int) hdaR3StreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser) 1833 { 1834 PHDASTREAMR3 const pStreamR3 = (PHDASTREAMR3)pvUser; 1835 PHDASTREAMSTATEAIO const pAIO = &pStreamR3->State.AIO; 1836 PHDASTATE const pThis = pStreamR3->pHDAStateShared; 1837 PHDASTATER3 const pThisCC = pStreamR3->pHDAStateR3; 1838 PPDMDEVINS const pDevIns = pThisCC->pDevIns; 1839 PHDASTREAM const pStreamShared = &pThis->aStreams[pStreamR3 - &pThisCC->aStreams[0]]; 1840 Assert(pStreamR3 - &pThisCC->aStreams[0] == pStreamR3->u8SD); 1841 Assert(pStreamShared->u8SD == pStreamR3->u8SD); 1842 1843 /* Signal parent thread that we've started */ 1847 1844 ASMAtomicXchgBool(&pAIO->fStarted, true); 1848 1849 1845 RTThreadUserSignal(hThreadSelf); 1850 1846 1851 LogFunc(("[SD%RU8] Started\n", pStream ->u8SD));1847 LogFunc(("[SD%RU8] Started\n", pStreamShared->u8SD)); 1852 1848 1853 1849 for (;;) 1854 1850 { 1855 int rc2 = RTSemEventWait(pAIO-> Event, RT_INDEFINITE_WAIT);1851 int rc2 = RTSemEventWait(pAIO->hEvent, RT_INDEFINITE_WAIT); 1856 1852 if (RT_FAILURE(rc2)) 1857 1853 break; … … 1861 1857 1862 1858 rc2 = RTCritSectEnter(&pAIO->CritSect); 1859 AssertRC(rc2); 1863 1860 if (RT_SUCCESS(rc2)) 1864 1861 { … … 1869 1866 } 1870 1867 1871 hdaR3StreamUpdate(pDevIns, p Stream, false /* fInTimer */);1868 hdaR3StreamUpdate(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, false /* fInTimer */); 1872 1869 1873 1870 int rc3 = RTCritSectLeave(&pAIO->CritSect); 1874 1871 AssertRC(rc3); 1875 1872 } 1876 1877 AssertRC(rc2); 1878 } 1879 1880 LogFunc(("[SD%RU8] Ended\n", pStream->u8SD)); 1881 1873 } 1874 1875 LogFunc(("[SD%RU8] Ended\n", pStreamShared->u8SD)); 1882 1876 ASMAtomicXchgBool(&pAIO->fStarted, false); 1883 1877 … … 1889 1883 * 1890 1884 * @returns IPRT status code. 1891 * @param pStream 1892 */ 1893 int hdaR3StreamAsyncIOCreate(PHDASTREAM pStream)1894 { 1895 PHDASTREAMSTATEAIO pAIO = &pStream ->State.AIO;1885 * @param pStreamR3 HDA audio stream to create the async I/O thread for. 1886 */ 1887 int hdaR3StreamAsyncIOCreate(PHDASTREAMR3 pStreamR3) 1888 { 1889 PHDASTREAMSTATEAIO pAIO = &pStreamR3->State.AIO; 1896 1890 1897 1891 int rc; … … 1902 1896 pAIO->fEnabled = true; /* Enabled by default. */ 1903 1897 1904 rc = RTSemEventCreate(&pAIO-> Event);1898 rc = RTSemEventCreate(&pAIO->hEvent); 1905 1899 if (RT_SUCCESS(rc)) 1906 1900 { … … 1908 1902 if (RT_SUCCESS(rc)) 1909 1903 { 1910 HDASTREAMTHREADCTX Ctx = { pStream->pHDAState, pStream }; 1911 1912 char szThreadName[64]; 1913 RTStrPrintf2(szThreadName, sizeof(szThreadName), "hdaAIO%RU8", pStream->u8SD); 1914 1915 rc = RTThreadCreate(&pAIO->Thread, hdaR3StreamAsyncIOThread, &Ctx, 1916 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, szThreadName); 1904 rc = RTThreadCreateF(&pAIO->hThread, hdaR3StreamAsyncIOThread, pStreamR3, 0 /*cbStack*/, 1905 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "hdaAIO%RU8", pStreamR3->u8SD); 1917 1906 if (RT_SUCCESS(rc)) 1918 rc = RTThreadUserWait(pAIO-> Thread, 10 * 1000 /* 10s timeout */);1907 rc = RTThreadUserWait(pAIO->hThread, 10 * 1000 /* 10s timeout */); 1919 1908 } 1920 1909 } … … 1923 1912 rc = VINF_SUCCESS; 1924 1913 1925 LogFunc(("[SD%RU8] Returning %Rrc\n", pStream ->u8SD, rc));1914 LogFunc(("[SD%RU8] Returning %Rrc\n", pStreamR3->u8SD, rc)); 1926 1915 return rc; 1927 1916 } … … 1931 1920 * 1932 1921 * @returns IPRT status code. 1933 * @param pStream 1934 */ 1935 int hdaR3StreamAsyncIODestroy(PHDASTREAM pStream)1936 { 1937 PHDASTREAMSTATEAIO pAIO = &pStream ->State.AIO;1922 * @param pStreamR3 HDA audio stream to destroy the async I/O thread for. 1923 */ 1924 static int hdaR3StreamAsyncIODestroy(PHDASTREAMR3 pStreamR3) 1925 { 1926 PHDASTREAMSTATEAIO pAIO = &pStreamR3->State.AIO; 1938 1927 1939 1928 if (!ASMAtomicReadBool(&pAIO->fStarted)) … … 1942 1931 ASMAtomicWriteBool(&pAIO->fShutdown, true); 1943 1932 1944 int rc = hdaR3StreamAsyncIONotify(pStream );1933 int rc = hdaR3StreamAsyncIONotify(pStreamR3); 1945 1934 AssertRC(rc); 1946 1935 1947 1936 int rcThread; 1948 rc = RTThreadWait(pAIO-> Thread, 30 * 1000 /* 30s timeout */, &rcThread);1937 rc = RTThreadWait(pAIO->hThread, 30 * 1000 /* 30s timeout */, &rcThread); 1949 1938 LogFunc(("Async I/O thread ended with %Rrc (%Rrc)\n", rc, rcThread)); 1950 1939 1951 1940 if (RT_SUCCESS(rc)) 1952 1941 { 1942 pAIO->hThread = NIL_RTTHREAD; 1943 1953 1944 rc = RTCritSectDelete(&pAIO->CritSect); 1954 1945 AssertRC(rc); 1955 1946 1956 rc = RTSemEventDestroy(pAIO-> Event);1947 rc = RTSemEventDestroy(pAIO->hEvent); 1957 1948 AssertRC(rc); 1949 pAIO->hEvent = NIL_RTSEMEVENT; 1958 1950 1959 1951 pAIO->fStarted = false; … … 1962 1954 } 1963 1955 1964 LogFunc(("[SD%RU8] Returning %Rrc\n", pStream ->u8SD, rc));1956 LogFunc(("[SD%RU8] Returning %Rrc\n", pStreamR3->u8SD, rc)); 1965 1957 return rc; 1966 1958 } … … 1970 1962 * 1971 1963 * @returns IPRT status code. 1972 * @param pStream 1973 */ 1974 int hdaR3StreamAsyncIONotify(PHDASTREAM pStream)1975 { 1976 return RTSemEventSignal(pStream ->State.AIO.Event);1964 * @param pStreamR3 HDA stream to notify async I/O thread for. 1965 */ 1966 static int hdaR3StreamAsyncIONotify(PHDASTREAMR3 pStreamR3) 1967 { 1968 return RTSemEventSignal(pStreamR3->State.AIO.hEvent); 1977 1969 } 1978 1970 … … 1980 1972 * Locks the async I/O thread of a specific HDA audio stream. 1981 1973 * 1982 * @param pStream 1983 */ 1984 void hdaR3StreamAsyncIOLock(PHDASTREAM pStream)1985 { 1986 PHDASTREAMSTATEAIO pAIO = &pStream ->State.AIO;1974 * @param pStreamR3 HDA stream to lock async I/O thread for. 1975 */ 1976 void hdaR3StreamAsyncIOLock(PHDASTREAMR3 pStreamR3) 1977 { 1978 PHDASTREAMSTATEAIO pAIO = &pStreamR3->State.AIO; 1987 1979 1988 1980 if (!ASMAtomicReadBool(&pAIO->fStarted)) … … 1996 1988 * Unlocks the async I/O thread of a specific HDA audio stream. 1997 1989 * 1998 * @param pStream 1999 */ 2000 void hdaR3StreamAsyncIOUnlock(PHDASTREAM pStream)2001 { 2002 PHDASTREAMSTATEAIO pAIO = &pStream ->State.AIO;1990 * @param pStreamR3 HDA stream to unlock async I/O thread for. 1991 */ 1992 void hdaR3StreamAsyncIOUnlock(PHDASTREAMR3 pStreamR3) 1993 { 1994 PHDASTREAMSTATEAIO pAIO = &pStreamR3->State.AIO; 2003 1995 2004 1996 if (!ASMAtomicReadBool(&pAIO->fStarted)) … … 2012 2004 * Enables (resumes) or disables (pauses) the async I/O thread. 2013 2005 * 2014 * @param pStream 2006 * @param pStreamR3 HDA stream to enable/disable async I/O thread for. 2015 2007 * @param fEnable Whether to enable or disable the I/O thread. 2016 2008 * 2017 2009 * @remarks Does not do locking. 2018 2010 */ 2019 void hdaR3StreamAsyncIOEnable(PHDASTREAM pStream, bool fEnable)2020 { 2021 PHDASTREAMSTATEAIO pAIO = &pStream ->State.AIO;2011 void hdaR3StreamAsyncIOEnable(PHDASTREAMR3 pStreamR3, bool fEnable) 2012 { 2013 PHDASTREAMSTATEAIO pAIO = &pStreamR3->State.AIO; 2022 2014 ASMAtomicXchgBool(&pAIO->fEnabled, fEnable); 2023 2015 } -
trunk/src/VBox/Devices/Audio/HDAStream.h
r82420 r82450 34 34 { 35 35 /** Thread handle for the actual I/O thread. */ 36 RTTHREAD Thread;36 RTTHREAD hThread; 37 37 /** Event for letting the thread know there is some data to process. */ 38 RTSEMEVENT Event;38 RTSEMEVENT hEvent; 39 39 /** Critical section for synchronizing access. */ 40 40 RTCRITSECT CritSect; … … 123 123 volatile bool fRunning; 124 124 /** Unused, padding. */ 125 uint8_t Padding0[4]; 126 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 127 /** Asynchronous I/O state members. */ 128 HDASTREAMSTATEAIO AIO; 129 #endif 130 /** This stream's data mapping. */ 131 HDASTREAMMAP Mapping; 125 uint8_t abPadding0[4]; 132 126 /** Current BDLE (Buffer Descriptor List Entry). */ 133 127 HDABDLE BDLE; 134 /** Circular buffer (FIFO) for holding DMA'ed data. */135 R3PTRTYPE(PRTCIRCBUF) pCircBuf;136 #if HC_ARCH_BITS == 32137 RTR3PTR Padding1;138 #endif139 128 /** Timestamp of the last DMA data transfer. */ 140 129 uint64_t tsTransferLast; … … 153 142 * BDLE interrupt-on-completion (IOC) bits set. */ 154 143 uint8_t cTransferPendingInterrupts; 155 uint8_t Padding2[2];144 uint8_t abPadding2[3]; 156 145 /** The stream's timer Hz rate. 157 146 * This value can can be different from the device's default Hz rate, … … 167 156 * 0 if position adjustment handling is done or inactive. */ 168 157 uint16_t cfPosAdjustLeft; 158 uint16_t u16Padding3; 169 159 /** (Virtual) clock ticks per byte. */ 170 160 uint64_t cTicksPerByte; … … 177 167 PDMAUDIOSTREAMCFG Cfg; 178 168 uint32_t Padding4; 179 #ifdef HDA_USE_DMA_ACCESS_HANDLER 180 /** List of DMA handlers. */ 181 RTLISTANCHORR3 lstDMAHandlers; 182 #endif 183 /** Timestamp (in ns) of last stream update. */ 169 /** Timestamp (in ns) of last stream update. */ 184 170 uint64_t tsLastUpdateNs; 185 171 } HDASTREAMSTATE; 186 172 AssertCompileSizeAlignment(HDASTREAMSTATE, 8); 187 /** Pointer to the internal state of an HDA stream. */ 188 typedef HDASTREAMSTATE *PHDASTREAMSTATE; 189 190 /** 191 * An HDA stream (SDI / SDO). 173 174 /** 175 * An HDA stream (SDI / SDO) - shared. 192 176 * 193 177 * @note This HDA stream has nothing to do with a regular audio stream handled … … 232 216 uint16_t u16LVI; 233 217 uint16_t au16Padding1[2]; 234 /** Pointer to the HDA state this stream is attached to. */ 235 R3PTRTYPE(PHDASTATE) pHDAState; 218 /** The timer for pumping data thru the attached LUN drivers. */ 219 TMTIMERHANDLE hTimer; 220 /** Internal state of this stream. */ 221 HDASTREAMSTATE State; 222 } HDASTREAM; 223 /** Pointer to an HDA stream (SDI / SDO). */ 224 typedef HDASTREAM *PHDASTREAM; 225 226 227 /** 228 * An HDA stream (SDI / SDO) - ring-3 bits. 229 */ 230 typedef struct HDASTREAMR3 231 { 232 /** Stream descriptor number (SDn). */ 233 uint8_t u8SD; 234 uint8_t abPadding[7]; 235 /** The shared state for the parent HDA device. */ 236 R3PTRTYPE(PHDASTATE) pHDAStateShared; 237 /** The ring-3 state for the parent HDA device. */ 238 R3PTRTYPE(PHDASTATER3) pHDAStateR3; 236 239 /** Pointer to HDA sink this stream is attached to. */ 237 240 R3PTRTYPE(PHDAMIXERSINK) pMixSink; 238 /** The timer for pumping data thru the attached LUN drivers. */239 TMTIMERHANDLE hTimer;240 241 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 241 242 /** The stream's critical section to serialize access between the async I/O … … 244 245 #endif 245 246 /** Internal state of this stream. */ 246 HDASTREAMSTATE State; 247 /** Debug information. */ 247 struct 248 { 249 /** This stream's data mapping. */ 250 HDASTREAMMAP Mapping; 251 /** Circular buffer (FIFO) for holding DMA'ed data. */ 252 R3PTRTYPE(PRTCIRCBUF) pCircBuf; 253 #ifdef HDA_USE_DMA_ACCESS_HANDLER 254 /** List of DMA handlers. */ 255 RTLISTANCHORR3 lstDMAHandlers; 256 #endif 257 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 258 /** Asynchronous I/O state members. */ 259 HDASTREAMSTATEAIO AIO; 260 #endif 261 } State; 262 /** Debug bits. */ 248 263 HDASTREAMDEBUG Dbg; 249 } HDASTREAM ;264 } HDASTREAMR3; 250 265 /** Pointer to an HDA stream (SDI / SDO). */ 251 typedef HDASTREAM *PHDASTREAM; 252 253 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 254 /** 255 * HDA stream thread context (arguments). 256 */ 257 typedef struct HDASTREAMTHREADCTX 258 { 259 PHDASTATE pThis; 260 PHDASTREAM pStream; 261 } HDASTREAMTHREADCTX, *PHDASTREAMTHREADCTX; 262 #endif 266 typedef HDASTREAMR3 *PHDASTREAMR3; 263 267 264 268 #ifdef IN_RING3 … … 267 271 * @{ 268 272 */ 269 int hdaR3StreamCreate(PHDASTREAM pStream, PHDASTATE pThis, uint8_t u8SD); 270 void hdaR3StreamDestroy(PHDASTREAM pStream); 271 int hdaR3StreamInit(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint8_t uSD); 272 void hdaR3StreamReset(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD); 273 int hdaR3StreamEnable(PHDASTREAM pStream, bool fEnable); 274 uint32_t hdaR3StreamGetPosition(PHDASTATE pThis, PHDASTREAM pStream); 275 void hdaR3StreamSetPosition(PHDASTREAM pStream, uint32_t u32LPIB); 276 uint32_t hdaR3StreamGetFree(PHDASTREAM pStream); 277 uint32_t hdaR3StreamGetUsed(PHDASTREAM pStream); 278 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStream, uint64_t tsNow); 279 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStream); 280 void hdaR3StreamLock(PHDASTREAM pStream); 281 void hdaR3StreamUnlock(PHDASTREAM pStream); 282 int hdaR3StreamRead(PHDASTREAM pStream, uint32_t cbToRead, uint32_t *pcbRead); 283 int hdaR3StreamWrite(PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 284 void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTREAM pStream, bool fAsync); 273 int hdaR3StreamConstruct(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, PHDASTATE pThis, 274 PHDASTATER3 pThisCC, uint8_t uSD); 275 void hdaR3StreamDestroy(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3); 276 int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, 277 PHDASTREAMR3 pStreamR3, uint8_t uSD); 278 void hdaR3StreamReset(PHDASTATE pThis, PHDASTATER3 pThisCC, 279 PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, uint8_t uSD); 280 int hdaR3StreamEnable(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fEnable); 281 /* uint32_t hdaR3StreamGetPosition(PHDASTATE pThis, PHDASTREAMR3 pStreamShared); - only used in HDAStream.cpp */ 282 /*void hdaR3StreamSetPosition(PHDASTREAM pStream, PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t u32LPIB); - only used in HDAStream.cpp */ 283 /*uint32_t hdaR3StreamGetFree(PHDASTREAM pStream); - only used in HDAStream.cpp */ 284 /*uint32_t hdaR3StreamGetUsed(PHDASTREAM pStream); - only used in HDAStream.cpp */ 285 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStreamShared, uint64_t tsNow); 286 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStreamShared); 287 void hdaR3StreamLock(PHDASTREAMR3 pStreamR3); 288 void hdaR3StreamUnlock(PHDASTREAMR3 pStreamR3); 289 /* int hdaR3StreamRead(PHDASTREAM pStream, uint32_t cbToRead, uint32_t *pcbRead); - only used in HDAStream.cpp */ 290 /*int hdaR3StreamWrite(PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); - only used in HDAStream.cpp */ 291 void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, 292 PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fInTimer); 293 PHDASTREAM hdaR3StreamR3ToShared(PHDASTREAMR3 pStreamCC); 285 294 # ifdef HDA_USE_DMA_ACCESS_HANDLER 286 bool hdaR3StreamRegisterDMAHandlers(PHDASTREAM pStream);287 void hdaR3StreamUnregisterDMAHandlers(PHDASTREAM pStream);295 bool hdaR3StreamRegisterDMAHandlers(PHDASTREAM pStream); 296 void hdaR3StreamUnregisterDMAHandlers(PHDASTREAM pStream); 288 297 # endif 289 298 /** @} */ … … 293 302 */ 294 303 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 295 DECLCALLBACK(int) hdaR3StreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser); 296 int hdaR3StreamAsyncIOCreate(PHDASTREAM pStream); 297 int hdaR3StreamAsyncIODestroy(PHDASTREAM pStream); 298 int hdaR3StreamAsyncIONotify(PHDASTREAM pStream); 299 void hdaR3StreamAsyncIOLock(PHDASTREAM pStream); 300 void hdaR3StreamAsyncIOUnlock(PHDASTREAM pStream); 301 void hdaR3StreamAsyncIOEnable(PHDASTREAM pStream, bool fEnable); 304 int hdaR3StreamAsyncIOCreate(PHDASTREAMR3 pStreamR3); 305 void hdaR3StreamAsyncIOLock(PHDASTREAMR3 pStreamR3); 306 void hdaR3StreamAsyncIOUnlock(PHDASTREAMR3 pStreamR3); 307 void hdaR3StreamAsyncIOEnable(PHDASTREAMR3 pStreamR3, bool fEnable); 302 308 # endif /* VBOX_WITH_AUDIO_HDA_ASYNC_IO */ 303 309 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.