儲存庫 vbox 的更動 67533
- 時間撮記:
- 2017-6-21 上午09:47:08 (7 年 以前)
- 位置:
- trunk/src/VBox/Devices
- 檔案:
-
- 修改 2 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r67508 r67533 930 930 HDAMIXERSINK SinkMicIn; 931 931 #endif 932 /** The controller's base time stamp which the WALCLK register933 * derives its current value from. */934 uint64_t u64BaseTS;935 932 /** Last updated WALCLK counter. */ 936 933 uint64_t u64WalClk; … … 1313 1310 SSMFIELD_ENTRY_TERM() 1314 1311 }; 1312 1313 /** HDASTREAMPERIOD field descriptors for the v7 saved state. */ 1314 static SSMFIELD const g_aSSMStreamPeriodFields7[] = 1315 { 1316 SSMFIELD_ENTRY(HDASTREAMPERIOD, u64StartWalClk), 1317 SSMFIELD_ENTRY(HDASTREAMPERIOD, u64ElapsedWalClk), 1318 SSMFIELD_ENTRY(HDASTREAMPERIOD, framesTransferred), 1319 SSMFIELD_ENTRY(HDASTREAMPERIOD, cIntPending), 1320 SSMFIELD_ENTRY_TERM() 1321 }; 1315 1322 #endif 1316 1323 … … 1951 1958 pStream->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, pStream->u8SD) + 1; 1952 1959 1953 RT_ZERO(pStream->State.BDLE);1954 pStream->State.uCurBDLE = 0;1955 1956 if (pStream->State.pCircBuf)1957 RTCircBufReset(pStream->State.pCircBuf);1958 1959 1960 /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */ 1960 1961 hdaStreamUpdateLPIB(pThis, pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD)); … … 1962 1963 int rc = hdaSDFMTToStrmCfg(HDA_STREAM_REG(pThis, FMT, uSD), &pStream->State.strmCfg); 1963 1964 if (RT_FAILURE(rc)) 1965 { 1964 1966 LogRel(("HDA: Warning: Format 0x%x for stream #%RU8 not supported\n", HDA_STREAM_REG(pThis, FMT, uSD), uSD)); 1965 1966 /* Reset stream map. */ 1967 hdaStreamMapReset(&pStream->State.Mapping); 1968 1969 /* (Re-)init the stream's period. */ 1970 hdaStreamPeriodInit(&pStream->State.Period, pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.strmCfg); 1967 return rc; 1968 } 1969 1970 PPDMAUDIOSTREAMCFG pCfg = &pStream->State.strmCfg; 1971 1972 /* Set the stream's direction. */ 1973 pCfg->enmDir = hdaGetDirFromSD(pStream->u8SD); 1974 1975 /* The the stream's name, based on the direction. */ 1976 switch (pCfg->enmDir) 1977 { 1978 case PDMAUDIODIR_IN: 1979 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 1980 # error "Implement me!" 1981 # else 1982 pCfg->DestSource.Source = PDMAUDIORECSOURCE_LINE; 1983 RTStrCopy(pCfg->szName, sizeof(pCfg->szName), "Line In"); 1984 # endif 1985 break; 1986 1987 case PDMAUDIODIR_OUT: 1988 /* Destination(s) will be set in hdaAddStreamOut(), 1989 * based on the channels / stream layout. */ 1990 break; 1991 1992 default: 1993 rc = VERR_NOT_SUPPORTED; 1994 break; 1995 } 1996 1997 /* 1998 * Initialize the stream mapping in any case, regardless if 1999 * we support surround audio or not. This is needed to handle 2000 * the supported channels within a single audio stream, e.g. mono/stereo. 2001 * 2002 * In other words, the stream mapping *always* knows the real 2003 * number of channels in a single audio stream. 2004 */ 2005 rc = hdaStreamMapInit(&pStream->State.Mapping, pCfg); 2006 AssertRCReturn(rc, rc); 1971 2007 1972 2008 LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16, rc=%Rrc\n", … … 2024 2060 #endif 2025 2061 2062 RT_ZERO(pStream->State.BDLE); 2063 pStream->State.uCurBDLE = 0; 2064 2065 if (pStream->State.pCircBuf) 2066 RTCircBufReset(pStream->State.pCircBuf); 2067 2068 /* Reset stream map. */ 2069 hdaStreamMapReset(&pStream->State.Mapping); 2070 2026 2071 /* (Re-)initialize the stream with current values. */ 2027 2072 int rc2 = hdaStreamInit(pThis, pStream, uSD); 2028 2073 AssertRC(rc2); 2074 2075 /* Reset the stream's period. */ 2076 hdaStreamPeriodReset(&pStream->State.Period); 2029 2077 2030 2078 #ifdef DEBUG … … 2065 2113 int rc = VINF_SUCCESS; 2066 2114 2067 hdaStreamLock(pStream);2068 2069 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO2070 hdaStreamAsyncIOLock(pStream);2071 hdaStreamAsyncIOEnable(pStream, fEnable);2072 #endif2073 2074 2115 if (pStream->pMixSink) /* Stream attached to a sink? */ 2075 2116 { … … 2082 2123 } 2083 2124 2084 if (fEnable) 2085 { 2086 /* (Re-)initialize the stream with current values. */ 2087 int rc2 = hdaStreamInit(pThis, pStream, pStream->u8SD); 2088 AssertRC(rc2); 2089 2090 /* Begin a new period for this stream. */ 2091 rc2 = hdaStreamPeriodBegin(&pStream->State.Period, hdaWalClkGetCurrent(pThis)/* Use current wall clock time */); 2092 AssertRC(rc2); 2093 } 2094 else 2095 { 2096 /* Reset the period. */ 2097 hdaStreamPeriodReset(&pStream->State.Period); 2098 } 2099 2100 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 2101 hdaStreamAsyncIOUnlock(pStream); 2102 #endif 2103 2104 /* Make sure to leave the lock before (eventually) starting the timer. */ 2105 hdaStreamUnlock(pStream); 2106 2107 #ifndef VBOX_WITH_AUDIO_HDA_CALLBACKS 2108 /* Second, see if we need to start or stop the timer. */ 2109 if (!fEnable) 2110 hdaTimerMaybeStop(pThis); 2111 else 2112 hdaTimerMaybeStart(pThis); 2113 #endif 2114 2115 LogFunc(("[SD%RU8]: cStreamsActive=%RU8, rc=%Rrc\n", pStream->u8SD, pThis->cStreamsActive, rc)); 2125 LogFunc(("[SD%RU8] rc=%Rrc\n", pStream->u8SD, rc)); 2116 2126 return rc; 2117 2127 } … … 2670 2680 hdaStreamLock(pStream); 2671 2681 2682 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 2683 hdaStreamAsyncIOLock(pStream); 2684 hdaStreamAsyncIOEnable(pStream, false /* fEnable */); 2685 #endif 2672 2686 hdaStreamReset(pThis, pStream, pStream->u8SD); 2673 2687 2688 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 2689 hdaStreamAsyncIOUnlock(pStream); 2690 #endif 2674 2691 hdaStreamUnlock(pStream); 2675 2692 } … … 2684 2701 LogFunc(("[SD%RU8]: State changed (fRun=%RTbool)\n", pStream->u8SD, fRun)); 2685 2702 2703 hdaStreamLock(pStream); 2704 2705 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 2706 hdaStreamAsyncIOLock(pStream); 2707 hdaStreamAsyncIOEnable(pStream, fRun /* fEnable */); 2708 #endif 2709 /* (Re-)initialize the stream with current values. */ 2710 int rc2 = hdaStreamInit(pThis, pStream, pStream->u8SD); 2711 AssertRC(rc2); 2712 2713 /* Enable/disable the stream. */ 2686 2714 hdaStreamEnable(pThis, pStream, fRun /* fEnable */); 2687 2715 2688 if (!fRun) 2716 if (fRun) 2717 { 2718 /* (Re-)init the stream's period. */ 2719 hdaStreamPeriodInit(&pStream->State.Period, 2720 pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.strmCfg); 2721 2722 /* Begin a new period for this stream. */ 2723 rc2 = hdaStreamPeriodBegin(&pStream->State.Period, hdaWalClkGetCurrent(pThis)/* Use current wall clock time */); 2724 AssertRC(rc2); 2725 } 2726 else 2689 2727 { 2690 2728 /* Make sure to (re-)schedule outstanding (delayed) interrupts. */ 2691 2729 hdaReschedulePendingInterrupts(pThis); 2730 2731 /* Reset the period. */ 2732 hdaStreamPeriodReset(&pStream->State.Period); 2692 2733 } 2734 2735 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 2736 hdaStreamAsyncIOUnlock(pStream); 2737 #endif 2738 /* Make sure to leave the lock before (eventually) starting the timer. */ 2739 hdaStreamUnlock(pStream); 2740 2741 #ifndef VBOX_WITH_AUDIO_HDA_CALLBACKS 2742 /* See if we need to start or stop the timer. */ 2743 if (!fRun) 2744 hdaTimerMaybeStop(pThis); 2745 else 2746 hdaTimerMaybeStart(pThis); 2747 #endif 2693 2748 } 2694 2749 } … … 2986 3041 } 2987 3042 3043 /** 3044 * Adds an audio output stream to the device setup using the given configuration. 3045 * 3046 * @returns IPRT status code. 3047 * @param pThis Device state. 3048 * @param pCfg Stream configuration to use for adding a stream. 3049 */ 2988 3050 static int hdaAddStreamOut(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 2989 3051 { … … 3110 3172 } 3111 3173 3174 /** 3175 * Adds an audio input stream to the device setup using the given configuration. 3176 * 3177 * @returns IPRT status code. 3178 * @param pThis Device state. 3179 * @param pCfg Stream configuration to use for adding a stream. 3180 */ 3112 3181 static int hdaAddStreamIn(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 3113 3182 { … … 3147 3216 return rc; 3148 3217 } 3218 3219 /** 3220 * Adds an audio stream to the device setup using the given configuration. 3221 * 3222 * @returns IPRT status code. 3223 * @param pThis Device state. 3224 * @param pCfg Stream configuration to use for adding a stream. 3225 */ 3226 static int hdaAddStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg) 3227 { 3228 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3229 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3230 3231 int rc = VINF_SUCCESS; 3232 3233 PHDADRIVER pDrv; 3234 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 3235 { 3236 int rc2; 3237 3238 switch (pCfg->enmDir) 3239 { 3240 case PDMAUDIODIR_OUT: 3241 rc2 = hdaAddStreamOut(pThis, pCfg); 3242 break; 3243 3244 case PDMAUDIODIR_IN: 3245 rc2 = hdaAddStreamIn(pThis, pCfg); 3246 break; 3247 3248 default: 3249 rc2 = VERR_NOT_SUPPORTED; 3250 AssertFailed(); 3251 break; 3252 } 3253 3254 if ( RT_FAILURE(rc2) 3255 && (pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY)) /* We only care about primary drivers here, the rest may fail. */ 3256 { 3257 if (RT_SUCCESS(rc)) 3258 rc = rc2; 3259 /* Keep going. */ 3260 } 3261 } 3262 3263 return rc; 3264 } 3149 3265 #endif /* IN_RING3 */ 3150 3266 … … 3160 3276 } 3161 3277 3162 PPDMAUDIOSTREAMCFG pCfg = &pStream->State.strmCfg; 3163 3164 int rc = hdaSDFMTToStrmCfg(u32Value, pCfg); 3165 if (RT_FAILURE(rc)) 3166 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 3167 3168 LogFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, cBits=%RU8\n", 3169 pStream->u8SD, pCfg->Props.uHz, pCfg->Props.cChannels, pCfg->Props.cBits)); 3170 3171 /* Set audio direction. */ 3172 pCfg->enmDir = hdaGetDirFromSD(pStream->u8SD); 3173 switch (pCfg->enmDir) 3174 { 3175 case PDMAUDIODIR_IN: 3176 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 3177 # error "Implement me!" 3178 # else 3179 pCfg->DestSource.Source = PDMAUDIORECSOURCE_LINE; 3180 RTStrCopy(pCfg->szName, sizeof(pCfg->szName), "Line In"); 3181 # endif 3182 break; 3183 3184 case PDMAUDIODIR_OUT: 3185 /* Destination(s) will be set in hdaAddStreamOut(), 3186 * based on the channels / stream layout. */ 3187 break; 3188 3189 default: 3190 rc = VERR_NOT_SUPPORTED; 3191 break; 3192 } 3193 3278 int rc = hdaRegWriteU16(pThis, iReg, u32Value); 3279 AssertRC(rc); 3280 3281 rc = hdaStreamInit(pThis, pStream, pStream->u8SD); 3282 if (RT_SUCCESS(rc)) 3283 { 3284 /* Add the stream to the device setup. */ 3285 rc = hdaAddStream(pThis, &pStream->State.strmCfg); 3194 3286 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 3195 if (RT_SUCCESS(rc))3196 {3197 rc = hdaStreamAsyncIOCreate(pThis, pStream);3198 AssertRC(rc);3199 }3200 #endif3201 3202 /*3203 * Initialize the stream mapping in any case, regardless if3204 * we support surround audio or not. This is needed to handle3205 * the supported channels within a single audio stream, e.g. mono/stereo.3206 *3207 * In other words, the stream mapping *always* knows the real3208 * number of channels in a single audio stream.3209 */3210 if (RT_SUCCESS(rc))3211 {3212 rc = hdaStreamMapInit(&pStream->State.Mapping, pCfg);3213 AssertRC(rc);3214 }3215 3216 if (RT_SUCCESS(rc))3217 {3218 PHDADRIVER pDrv;3219 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)3220 {3221 int rc2;3222 switch (pCfg->enmDir)3223 {3224 case PDMAUDIODIR_OUT:3225 rc2 = hdaAddStreamOut(pThis, pCfg);3226 break;3227 3228 case PDMAUDIODIR_IN:3229 rc2 = hdaAddStreamIn(pThis, pCfg);3230 break;3231 3232 default:3233 rc2 = VERR_NOT_SUPPORTED;3234 AssertFailed();3235 break;3236 }3237 3238 if ( RT_FAILURE(rc2)3239 && (pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY)) /* We only care about primary drivers here, the rest may fail. */3240 {3241 if (RT_SUCCESS(rc))3242 rc = rc2;3243 /* Keep going. */3244 }3245 }3246 3247 /* If (re-)opening the stream by the codec above failed, don't write the new3248 * format to the register so that the guest is aware it didn't work. */3249 3287 if (RT_SUCCESS(rc)) 3250 { 3251 rc = hdaRegWriteU16(pThis, iReg, u32Value); 3252 AssertRC(rc); 3253 } 3254 else 3255 LogFunc(("[SD%RU8]: (Re-)Opening stream failed with rc=%Rrc\n", pStream->u8SD, rc)); 3256 } 3257 3288 rc = hdaStreamAsyncIOCreate(pThis, pStream); 3289 } 3290 #endif 3258 3291 return VINF_SUCCESS; /* Never return failure. */ 3259 3292 #else /* !IN_RING3 */ … … 5949 5982 AssertRCReturn(rc, rc); 5950 5983 5984 rc = SSMR3PutStructEx(pSSM, &pStrm->State.Period, sizeof(HDASTREAMPERIOD), 5985 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL); 5986 AssertRCReturn(rc, rc); 5987 5951 5988 #ifdef VBOX_STRICT /* Sanity checks. */ 5952 5989 PHDABDLE pBDLE = &pStrm->State.BDLE; … … 6052 6089 SSMR3PutMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs)); 6053 6090 6054 /* Save the controller's base timestamp (for handling the WALCLK register).6055 * This is needed to continue with correct time keeping on VM resume. */6056 SSMR3PutU 64(pSSM, pThis->u64BaseTS);6091 /* Load controller-specifc internals. */ 6092 SSMR3PutU64(pSSM, pThis->u64WalClk); 6093 SSMR3PutU8(pSSM, pThis->u8IRQL); 6057 6094 6058 6095 /* Save number of streams. */ … … 6088 6125 if (pStream) 6089 6126 { 6090 hdaStreamEnable(pThis, pStream, false /* fEnable */);6127 int rc2; 6091 6128 6092 6129 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_SDCTL_RUN); 6093 6130 if (fActive) 6094 6131 { 6095 int rc2;6096 6097 6132 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 6098 6133 /* Make sure to also create the async I/O thread before actually enabling the stream. */ 6099 6134 rc2 = hdaStreamAsyncIOCreate(pThis, pStream); 6100 6135 AssertRC(rc2); 6101 #endif 6136 6137 /* ... and enabling it. */ 6138 hdaStreamAsyncIOEnable(pStream, true /* fEnable */); 6139 #endif 6140 /* (Re-)initialize the stream with current values. */ 6141 rc2 = hdaStreamInit(pThis, pStream, pStream->u8SD); 6142 AssertRC(rc2); 6143 6144 /* Resume the stream's period. */ 6145 hdaStreamPeriodResume(&pStream->State.Period); 6146 6147 /* (Re-)enable the stream. */ 6102 6148 rc2 = hdaStreamEnable(pThis, pStream, true /* fEnable */); 6103 6149 AssertRC(rc2); 6104 6150 6151 /* Add the stream to the device setup. */ 6152 rc2 = hdaAddStream(pThis, &pStream->State.strmCfg); 6153 AssertRC(rc2); 6154 6105 6155 #ifdef HDA_USE_DMA_ACCESS_HANDLER 6156 /* (Re-)install the DMA handler. */ 6106 6157 hdaStreamRegisterDMAHandlers(pThis, pStream); 6107 6158 #endif … … 6112 6163 6113 6164 #ifndef VBOX_WITH_AUDIO_CALLBACKS 6114 if ( fStartTimer 6115 && pThis->pTimer 6116 && !TMTimerIsActive(pThis->pTimer)) 6117 { 6118 pThis->tsTimerExpire = TMTimerGet(pThis->pTimer) + pThis->cTimerTicks; 6119 6120 /* Resume timer. */ 6121 int rc2 = TMTimerSet(pThis->pTimer, pThis->tsTimerExpire); 6122 AssertRC(rc2); 6123 } 6165 /* Start the timer if one of the above streams were active during taking the saved state. */ 6166 if (fStartTimer) 6167 hdaTimerMaybeStart(pThis); 6124 6168 #endif 6125 6169 … … 6470 6514 * Load controller-specifc internals. 6471 6515 */ 6472 rc = SSMR3GetU64(pSSM, &pThis->u64BaseTS); 6473 AssertRC(rc); 6516 if (SSMR3HandleRevision(pSSM) >= 116273) /* Don't annoy other team mates (forgot this for state v7). */ 6517 { 6518 rc = SSMR3GetU64(pSSM, &pThis->u64WalClk); 6519 AssertRC(rc); 6520 6521 rc = SSMR3GetU8(pSSM, &pThis->u8IRQL); 6522 AssertRC(rc); 6523 } 6474 6524 6475 6525 /* … … 6522 6572 6523 6573 Log2Func(("[SD%RU8] %R[bdle]\n", pStrm->u8SD, &pStrm->State.BDLE)); 6574 6575 /* 6576 * Load period state. 6577 */ 6578 hdaStreamPeriodInit(&pStrm->State.Period, 6579 pStrm->u8SD, pStrm->u16LVI, pStrm->u32CBL, &pStrm->State.strmCfg); 6580 6581 if (SSMR3HandleRevision(pSSM) >= 116273) /* Don't annoy other team mates (forgot this for state v7). */ 6582 { 6583 rc = SSMR3GetStructEx(pSSM, &pStrm->State.Period, sizeof(HDASTREAMPERIOD), 6584 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL); 6585 AssertRC(rc); 6586 } 6524 6587 6525 6588 /* … … 6976 7039 else 6977 7040 pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf); 6978 6979 pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);6980 7041 6981 7042 for (uint8_t uSD = 0; uSD < HDA_MAX_STREAMS; ++uSD) -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r67410 r67533 1899 1899 GEN_CHECK_OFF(HDASTATE, SinkMicIn); 1900 1900 #endif 1901 GEN_CHECK_OFF(HDASTATE, u64 BaseTS);1901 GEN_CHECK_OFF(HDASTATE, u64WalClk); 1902 1902 GEN_CHECK_OFF(HDASTATE, u8RespIntCnt); 1903 GEN_CHECK_OFF(HDASTATE, u8IRQL); 1903 1904 1904 1905 #ifdef VBOX_WITH_NVME_IMPL
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器