Changeset 89770 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 18, 2021 12:21:50 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145222
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89768 r89770 401 401 /** Number of bytes involved in unresolved flow errors. */ 402 402 STAMCOUNTER StatDmaFlowErrorBytes; 403 STAMCOUNTER StatDmaSkippedDch; 404 STAMCOUNTER StatDmaSkippedPendingBcis; 403 405 STAMPROFILE StatStart; 404 406 STAMPROFILE StatReset; … … 1004 1006 PAC97BMREGS pRegs = &pStream->Regs; 1005 1007 1006 if (!(pRegs->sr & AC97_SR_DCH)) /* Controller halted? */ 1007 { /* not halted - likely */ } 1008 /* 1009 * Check that the controller is not halted (DCH) and that the buffer 1010 * completion interrupt isn't pending. 1011 */ 1012 /** @todo r=bird: Why do we not just barge ahead even when BCIS is set? Can't 1013 * find anything in spec indicating that we shouldn't. Linux shouldn't 1014 * care if be bundle IOCs, as it checks how many steps we've taken using 1015 * CIV. The Windows AC'97 sample driver doesn't care at all, since it 1016 * just sets LIV to CIV-1 (thought that's probably not what the real 1017 * windows driver does)... 1018 * 1019 * This is not going to sound good if it happens often enough, because 1020 * each time we'll lose one DMA period (exact length depends on the 1021 * buffer here). 1022 * 1023 * If we're going to keep this hack, there should be a 1024 * PDMDevHlpTimerSetRelative call arm-ing the DMA timer to fire shortly 1025 * after BCIS is cleared. Otherwise, we might lag behind even more 1026 * before we get stuff going again. 1027 * 1028 * I just wish there was some clear reasoning in the source code for 1029 * weird shit like this. This is just random voodoo. Sigh^3! */ 1030 if (!(pRegs->sr & (AC97_SR_DCH | AC97_SR_BCIS))) /* Controller halted? */ 1031 { /* not halted nor does it have pending interrupt - likely */ } 1008 1032 else 1009 1033 { 1010 if (pRegs-> cr & AC97_CR_RPBM) /* Bus master operation starts. */1034 if (pRegs->sr & AC97_SR_DCH) 1011 1035 { 1012 switch (pStream->u8SD) 1013 { 1014 case AC97SOUNDSOURCE_PO_INDEX: 1015 /*ichac97R3WriteBUP(pThis, cbToProcess);*/ 1016 break; 1017 1018 default: 1019 break; 1020 } 1036 STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaSkippedDch); 1037 LogFunc(("[SD%RU8] DCH set\n", pStream->u8SD)); 1038 } 1039 if (pRegs->sr & AC97_SR_BCIS) 1040 { 1041 STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaSkippedPendingBcis); 1042 LogFunc(("[SD%RU8] BCIS set\n", pStream->u8SD)); 1043 } 1044 if ((pRegs->cr & AC97_CR_RPBM) /* Bus master operation started. */ && !fInput) 1045 { 1046 /*ichac97R3WriteBUP(pThis, cbToProcess);*/ 1021 1047 } 1022 1048 … … 1025 1051 } 1026 1052 1027 /* BCIS flag still set? Skip iteration. */ 1028 /** @todo combine with the above test. */ 1029 if (!(pRegs->sr & AC97_SR_BCIS)) 1030 { /* likely */ } 1031 else 1032 { 1033 /** @todo counter */ 1034 Log3Func(("[SD%RU8] BCIS set\n", pStream->u8SD)); 1035 1036 ichac97R3StreamUnlock(pStreamCC); 1037 return VINF_SUCCESS; 1038 } 1039 1040 uint32_t cbLeft = RT_MIN((uint32_t)(pRegs->picb << 1), cbToProcessMax); /** @todo r=andy Assumes 16bit samples. */ 1041 uint32_t cbProcessedTotal = 0; 1042 1043 PRTCIRCBUF pCircBuf = pStreamCC->State.pCircBuf; 1053 /* 1054 * How much to transfer. 1055 */ 1056 /** @todo r=bird: This is wrong, isn't it? We should just transfer 1057 * cbToProcessMax. The caller does a RT_MIN(cbPeriod, buffer), so 1058 * we'll get the min number of bytes to transfer in. It should equal 1059 * PICB, but it doesn't technically have to and the loop below seems to 1060 * think we can work with PICB=0, which this code here contratradicts. 1061 * 1062 * When it was introduced in r108022, it might've made some sense... 1063 * 1064 * Which is inconsistent. I hate inconsistencies. */ 1065 uint32_t cbLeft = pRegs->picb * PDMAudioPropsSampleSize(&pStreamCC->State.Cfg.Props); 1066 cbLeft = RT_MIN(cbLeft, cbToProcessMax); 1067 Log3Func(("[SD%RU8] cbToProcessMax=%#x cbLeft=%#x\n", pStream->u8SD, cbToProcessMax, cbLeft)); 1068 1069 /* 1070 * Transfer loop. 1071 */ 1072 uint32_t cbProcessedTotal = 0; 1073 int rc = VINF_SUCCESS; 1074 PRTCIRCBUF pCircBuf = pStreamCC->State.pCircBuf; 1044 1075 AssertReturnStmt(pCircBuf, ichac97R3StreamUnlock(pStreamCC), VINF_SUCCESS); 1045 1076 1046 int rc = VINF_SUCCESS; 1047 1048 Log3Func(("[SD%RU8] cbToProcessMax=%RU32, cbLeft=%RU32\n", pStream->u8SD, cbToProcessMax, cbLeft)); 1049 1050 while (cbLeft) 1051 { 1052 if (!pRegs->picb) /* Got a new buffer descriptor, that is, the position is 0? */ 1077 while (cbLeft > 0) 1078 { 1079 /** @todo as mentioned above, this is utter non-sense as it won't _ever_ be 1080 * taken, given that cbLeft == PICB * 2. */ 1081 if (!pRegs->picb) /* Get a new buffer descriptor, that is, the position is 0? */ 1053 1082 { 1054 1083 Log3Func(("Fresh buffer descriptor %RU8 is empty, addr=%#x, len=%#x, skipping\n", … … 1133 1162 } 1134 1163 1135 if (cbChunk) 1136 { 1137 Assert(PDMAudioPropsIsSizeAligned(&pStreamCC->State.Cfg.Props, cbChunk)); 1138 Assert(cbChunk <= cbLeft); 1139 1140 cbProcessedTotal += cbChunk; 1141 Assert(cbProcessedTotal <= cbToProcessMax); 1142 cbLeft -= cbChunk; 1143 pRegs->picb -= (cbChunk >> 1); /** @todo r=andy Assumes 16bit samples. */ 1144 pRegs->bd.addr += cbChunk; 1145 } 1164 Assert(PDMAudioPropsIsSizeAligned(&pStreamCC->State.Cfg.Props, cbChunk)); 1165 Assert(cbChunk <= cbLeft); 1166 1167 cbProcessedTotal += cbChunk; 1168 Assert(cbProcessedTotal <= cbToProcessMax); 1169 cbLeft -= cbChunk; 1170 pRegs->picb -= (cbChunk >> 1); /** @todo r=andy Assumes 16bit samples. */ 1171 pRegs->bd.addr += cbChunk; 1146 1172 1147 1173 LogFlowFunc(("[SD%RU8] cbChunk=%RU32, cbLeft=%RU32, cbTotal=%RU32, rc=%Rrc\n", 1148 1174 pStream->u8SD, cbChunk, cbLeft, cbProcessedTotal, rc)); 1149 1175 1176 /** @todo r=bird: again, given that cbLeft == PICB * 2, we could put this 1177 * outside the loop and save a lot of clutter (VINF_EOF). */ 1150 1178 if (!pRegs->picb) 1151 1179 { … … 4551 4579 "Number of bytes of silence added to cope with underruns.", "Stream%u/DMABufferSilence", idxStream); 4552 4580 } 4581 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaSkippedDch, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, 4582 "DMA transfer period skipped, controller halted (DCH).", "Stream%u/DMASkippedDch", idxStream); 4583 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaSkippedPendingBcis, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, 4584 "DMA transfer period skipped because of BCIS pending.", "Stream%u/DMASkippedPendingBCIS", idxStream); 4553 4585 4554 4586 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatStart, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_NS_PER_CALL,
Note:
See TracChangeset
for help on using the changeset viewer.