Changeset 82399 in vbox for trunk/src/VBox
- Timestamp:
- Dec 4, 2019 8:50:10 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r82391 r82399 3011 3011 Assert(cb == 4); Assert((off & 3) == 0); 3012 3012 3013 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ); 3014 3015 if (!(HDA_REG(pThis, GCTL) & HDA_GCTL_CRST) && idxRegDsc != HDA_REG_GCTL) 3016 LogFunc(("Access to registers except GCTL is blocked while resetting\n")); 3017 3018 if (idxRegDsc >= 0) 3019 { 3020 /* ASSUMES gapless DWORD at end of map. */ 3021 if (g_aHdaRegMap[idxRegDsc].size == 4) 3022 { 3023 /* 3024 * Straight forward DWORD access. 3025 */ 3026 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pDevIns, pThis, idxRegDsc, (uint32_t *)pv); 3027 Log3Func(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, VBOXSTRICTRC_VAL(rc))); 3013 rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VINF_IOM_R3_MMIO_READ); 3014 if (rc == VINF_SUCCESS) 3015 { 3016 if (!(HDA_REG(pThis, GCTL) & HDA_GCTL_CRST) && idxRegDsc != HDA_REG_GCTL) 3017 LogFunc(("Access to registers except GCTL is blocked while resetting\n")); 3018 3019 if (idxRegDsc >= 0) 3020 { 3021 /* ASSUMES gapless DWORD at end of map. */ 3022 if (g_aHdaRegMap[idxRegDsc].size == 4) 3023 { 3024 /* 3025 * Straight forward DWORD access. 3026 */ 3027 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pDevIns, pThis, idxRegDsc, (uint32_t *)pv); 3028 Log3Func(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, VBOXSTRICTRC_VAL(rc))); 3029 STAM_COUNTER_INC(&pThis->aStatRegReads[idxRegDsc]); 3030 } 3031 else 3032 { 3033 /* 3034 * Multi register read (unless there are trailing gaps). 3035 * ASSUMES that only DWORD reads have sideeffects. 3036 */ 3037 #ifdef IN_RING3 3038 STAM_COUNTER_INC(&pThis->StatRegMultiReads); 3039 uint32_t u32Value = 0; 3040 unsigned cbLeft = 4; 3041 do 3042 { 3043 uint32_t const cbReg = g_aHdaRegMap[idxRegDsc].size; 3044 uint32_t u32Tmp = 0; 3045 3046 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pDevIns, pThis, idxRegDsc, &u32Tmp); 3047 Log3Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, VBOXSTRICTRC_VAL(rc))); 3048 STAM_COUNTER_INC(&pThis->aStatRegReads[idxRegDsc]); 3049 if (rc != VINF_SUCCESS) 3050 break; 3051 u32Value |= (u32Tmp & g_afMasks[cbReg]) << ((4 - cbLeft) * 8); 3052 3053 cbLeft -= cbReg; 3054 off += cbReg; 3055 idxRegDsc++; 3056 } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == off); 3057 3058 if (rc == VINF_SUCCESS) 3059 *(uint32_t *)pv = u32Value; 3060 else 3061 Assert(!IOM_SUCCESS(rc)); 3062 #else /* !IN_RING3 */ 3063 /* Take the easy way out. */ 3064 STAM_COUNTER_INC(&pThis->aStatRegReadsToR3[idxRegDsc]); 3065 rc = VINF_IOM_R3_MMIO_READ; 3066 #endif /* !IN_RING3 */ 3067 } 3028 3068 } 3029 3069 else 3030 3070 { 3031 /* 3032 * Multi register read (unless there are trailing gaps). 3033 * ASSUMES that only DWORD reads have sideeffects. 3034 */ 3035 #ifdef IN_RING3 3036 uint32_t u32Value = 0; 3037 unsigned cbLeft = 4; 3038 do 3039 { 3040 uint32_t const cbReg = g_aHdaRegMap[idxRegDsc].size; 3041 uint32_t u32Tmp = 0; 3042 3043 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pDevIns, pThis, idxRegDsc, &u32Tmp); 3044 Log3Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, VBOXSTRICTRC_VAL(rc))); 3045 if (rc != VINF_SUCCESS) 3046 break; 3047 u32Value |= (u32Tmp & g_afMasks[cbReg]) << ((4 - cbLeft) * 8); 3048 3049 cbLeft -= cbReg; 3050 off += cbReg; 3051 idxRegDsc++; 3052 } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == off); 3053 3054 if (rc == VINF_SUCCESS) 3055 *(uint32_t *)pv = u32Value; 3056 else 3057 Assert(!IOM_SUCCESS(rc)); 3058 #else /* !IN_RING3 */ 3059 /* Take the easy way out. */ 3060 rc = VINF_IOM_R3_MMIO_READ; 3061 #endif /* !IN_RING3 */ 3062 } 3071 LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", (uint32_t)off, cb)); 3072 Log3Func(("\tHole at %x is accessed for read\n", offRegLog)); 3073 STAM_COUNTER_INC(&pThis->StatRegUnknownReads); 3074 rc = VINF_IOM_MMIO_UNUSED_FF; 3075 } 3076 3077 DEVHDA_UNLOCK(pDevIns, pThis); 3078 3079 /* 3080 * Log the outcome. 3081 */ 3082 #ifdef LOG_ENABLED 3083 if (cbLog == 4) 3084 Log3Func(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, VBOXSTRICTRC_VAL(rc))); 3085 else if (cbLog == 2) 3086 Log3Func(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, VBOXSTRICTRC_VAL(rc))); 3087 else if (cbLog == 1) 3088 Log3Func(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, VBOXSTRICTRC_VAL(rc))); 3089 #endif 3063 3090 } 3064 3091 else 3065 3092 { 3066 LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", (uint32_t)off, cb)); 3067 Log3Func(("\tHole at %x is accessed for read\n", offRegLog)); 3068 rc = VINF_IOM_MMIO_UNUSED_FF; 3069 } 3070 3071 DEVHDA_UNLOCK(pDevIns, pThis); 3072 3073 /* 3074 * Log the outcome. 3075 */ 3076 #ifdef LOG_ENABLED 3077 if (cbLog == 4) 3078 Log3Func(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, VBOXSTRICTRC_VAL(rc))); 3079 else if (cbLog == 2) 3080 Log3Func(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, VBOXSTRICTRC_VAL(rc))); 3081 else if (cbLog == 1) 3082 Log3Func(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, VBOXSTRICTRC_VAL(rc))); 3083 #endif 3093 if (idxRegDsc >= 0) 3094 STAM_COUNTER_INC(&pThis->aStatRegReadsToR3[idxRegDsc]); 3095 } 3084 3096 return rc; 3085 3097 } … … 3095 3107 LogRel2(("HDA: Warning: Access to register %s is blocked while controller is in reset mode\n", 3096 3108 g_aHdaRegMap[idxRegDsc].abbrev)); 3109 STAM_COUNTER_INC(&pThis->StatRegWritesBlockedByReset); 3097 3110 3098 3111 DEVHDA_UNLOCK(pDevIns, pThis); … … 3114 3127 */ 3115 3128 3116 3129 /* Is the RUN bit currently set? */ 3117 3130 if ( RT_BOOL(uSDCTL & HDA_SDCTL_RUN) 3118 3131 /* Are writes to the register denied if RUN bit is set? */ … … 3122 3135 LogRel2(("HDA: Warning: Access to register %s is blocked while the stream's RUN bit is set\n", 3123 3136 g_aHdaRegMap[idxRegDsc].abbrev)); 3137 STAM_COUNTER_INC(&pThis->StatRegWritesBlockedByRun); 3124 3138 3125 3139 DEVHDA_UNLOCK(pDevIns, pThis); … … 3135 3149 Log3Func(("Written value %#x to %s[%d byte]; %x => %x%s, rc=%d\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev, 3136 3150 g_aHdaRegMap[idxRegDsc].size, u32OldValue, pThis->au32Regs[idxRegMem], pszLog, VBOXSTRICTRC_VAL(rc))); 3151 #ifndef IN_RING3 3152 if (rc == VINF_IOM_R3_MMIO_WRITE) 3153 STAM_COUNTER_INC(&pThis->aStatRegWritesToR3[idxRegDsc]); 3154 else 3155 #endif 3156 STAM_COUNTER_INC(&pThis->aStatRegWrites[idxRegDsc]); 3137 3157 3138 3158 DEVHDA_UNLOCK(pDevIns, pThis); … … 3207 3227 * shifting out input values. 3208 3228 */ 3209 if (idxRegDsc < 0 && (idxRegDsc = hdaR3RegLookupWithin(off)) != -1) 3210 { 3211 uint32_t const cbBefore = (uint32_t)off - g_aHdaRegMap[idxRegDsc].offset; Assert(cbBefore > 0 && cbBefore < 4); 3212 off -= cbBefore; 3213 idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; 3214 u64Value <<= cbBefore * 8; 3215 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 3216 Log3Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n", 3217 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 3218 } 3229 if (idxRegDsc < 0) 3230 { 3231 idxRegDsc = hdaR3RegLookupWithin(off); 3232 if (idxRegDsc != -1) 3233 { 3234 uint32_t const cbBefore = (uint32_t)off - g_aHdaRegMap[idxRegDsc].offset; 3235 Assert(cbBefore > 0 && cbBefore < 4); 3236 off -= cbBefore; 3237 idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; 3238 u64Value <<= cbBefore * 8; 3239 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 3240 Log3Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n", 3241 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 3242 STAM_COUNTER_INC(&pThis->StatRegMultiWrites); 3243 } 3244 else 3245 STAM_COUNTER_INC(&pThis->StatRegUnknownWrites); 3246 } 3247 else 3248 STAM_COUNTER_INC(&pThis->StatRegMultiWrites); 3249 3219 3250 3220 3251 /* Loop thru the write area, it may cover multiple registers. */ … … 5024 5055 * Register statistics. 5025 5056 */ 5026 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "/Devices/HDA/Timer", STAMUNIT_TICKS_PER_CALL, "Profiling hdaR3Timer."); 5027 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn, STAMTYPE_PROFILE, "/Devices/HDA/Input", STAMUNIT_TICKS_PER_CALL, "Profiling input."); 5028 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut, STAMTYPE_PROFILE, "/Devices/HDA/Output", STAMUNIT_TICKS_PER_CALL, "Profiling output."); 5029 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead, STAMTYPE_COUNTER, "/Devices/HDA/BytesRead" , STAMUNIT_BYTES, "Bytes read from HDA emulation."); 5030 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, "/Devices/HDA/BytesWritten", STAMUNIT_BYTES, "Bytes written to HDA emulation."); 5057 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "Timer", STAMUNIT_TICKS_PER_CALL, "Profiling hdaR3Timer."); 5058 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn, STAMTYPE_PROFILE, "Input", STAMUNIT_TICKS_PER_CALL, "Profiling input."); 5059 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut, STAMTYPE_PROFILE, "Output", STAMUNIT_TICKS_PER_CALL, "Profiling output."); 5060 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead, STAMTYPE_COUNTER, "BytesRead" , STAMUNIT_BYTES, "Bytes read from HDA emulation."); 5061 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, "BytesWritten", STAMUNIT_BYTES, "Bytes written to HDA emulation."); 5062 5063 AssertCompile(RT_ELEMENTS(g_aHdaRegMap) == HDA_NUM_REGS); 5064 AssertCompile(RT_ELEMENTS(pThis->aStatRegReads) == HDA_NUM_REGS); 5065 AssertCompile(RT_ELEMENTS(pThis->aStatRegReadsToR3) == HDA_NUM_REGS); 5066 AssertCompile(RT_ELEMENTS(pThis->aStatRegWrites) == HDA_NUM_REGS); 5067 AssertCompile(RT_ELEMENTS(pThis->aStatRegWritesToR3) == HDA_NUM_REGS); 5068 for (size_t i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++) 5069 { 5070 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegReads[i], STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 5071 g_aHdaRegMap[i].desc, "Regs/%03x-%s-Reads", g_aHdaRegMap[i].offset, g_aHdaRegMap[i].abbrev); 5072 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegReadsToR3[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 5073 g_aHdaRegMap[i].desc, "Regs/%03x-%s-Reads-ToR3", g_aHdaRegMap[i].offset, g_aHdaRegMap[i].abbrev); 5074 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegWrites[i], STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 5075 g_aHdaRegMap[i].desc, "Regs/%03x-%s-Writes", g_aHdaRegMap[i].offset, g_aHdaRegMap[i].abbrev); 5076 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegWritesToR3[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 5077 g_aHdaRegMap[i].desc, "Regs/%03x-%s-Writes-ToR3", g_aHdaRegMap[i].offset, g_aHdaRegMap[i].abbrev); 5078 } 5079 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiReads, STAMTYPE_COUNTER, "RegMultiReads", STAMUNIT_OCCURENCES, "Register read not targeting just one register"); 5080 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiWrites, STAMTYPE_COUNTER, "RegMultiWrites", STAMUNIT_OCCURENCES, "Register writes not targeting just one register"); 5081 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegUnknownReads, STAMTYPE_COUNTER, "RegUnknownReads", STAMUNIT_OCCURENCES, "Reads of unknown registers."); 5082 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegUnknownWrites, STAMTYPE_COUNTER, "RegUnknownWrites", STAMUNIT_OCCURENCES, "Writes to unknown registers."); 5083 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegWritesBlockedByReset, STAMTYPE_COUNTER, "RegWritesBlockedByReset", STAMUNIT_OCCURENCES, "Writes blocked by pending reset (GCTL/CRST)"); 5084 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegWritesBlockedByRun, STAMTYPE_COUNTER, "RegWritesBlockedByRun", STAMUNIT_OCCURENCES, "Writes blocked by byte RUN bit."); 5031 5085 # endif 5032 5086 -
trunk/src/VBox/Devices/Audio/DevHDA.h
r82345 r82399 201 201 STAMCOUNTER StatBytesRead; 202 202 STAMCOUNTER StatBytesWritten; 203 204 /** @name Register statistics. 205 * The array members run parallel to g_aHdaRegMap. 206 * @{ */ 207 STAMCOUNTER aStatRegReads[HDA_NUM_REGS]; 208 STAMCOUNTER aStatRegReadsToR3[HDA_NUM_REGS]; 209 STAMCOUNTER aStatRegWrites[HDA_NUM_REGS]; 210 STAMCOUNTER aStatRegWritesToR3[HDA_NUM_REGS]; 211 STAMCOUNTER StatRegMultiReads; 212 STAMCOUNTER StatRegMultiWrites; 213 STAMCOUNTER StatRegUnknownReads; 214 STAMCOUNTER StatRegUnknownWrites; 215 STAMCOUNTER StatRegWritesBlockedByReset; 216 STAMCOUNTER StatRegWritesBlockedByRun; 217 /** @} */ 203 218 #endif 204 219 /** This is for checking that the build was correctly configured in all contexts. -
trunk/src/VBox/Devices/Audio/DevHDACommon.h
r82382 r82399 30 30 typedef VBOXSTRICTRC FNHDAREGWRITE(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 31 31 32 /** See 302349 p 6.2. */ 32 /** 33 * HDA register descriptor. 34 * 35 * See 302349 p 6.2. 36 */ 33 37 typedef struct HDAREGDESC 34 38 { … … 56 60 const char *desc; 57 61 } HDAREGDESC; 62 /** Pointer to a a const HDA register descriptor. */ 63 typedef HDAREGDESC const *PCHDAREGDESC; 58 64 59 65 /** -
trunk/src/VBox/Devices/Audio/HDACodec.cpp
r82309 r82399 3028 3028 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3029 3029 AssertPtrReturn(puResp, VERR_INVALID_POINTER); 3030 STAM_COUNTER_INC(&pThis->StatLookups); 3030 3031 3031 3032 if (CODEC_CAD(cmd) != pThis->id) … … 3278 3279 #endif 3279 3280 3281 /* 3282 * Statistics 3283 */ 3284 #ifdef VBOX_WITH_STATISTICS 3285 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLookups, STAMTYPE_COUNTER, "Codec/Lookups", STAMUNIT_OCCURENCES, "Number of codecLookup calls"); 3286 #endif 3287 3280 3288 LogFlowFuncLeaveRC(rc); 3281 3289 return rc; -
trunk/src/VBox/Devices/Audio/HDACodec.h
r82309 r82399 122 122 DECLR3CALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 123 123 /** @} */ 124 125 #ifdef VBOX_WITH_STATISTICS 126 STAMCOUNTER StatLookups; 127 #endif 124 128 } HDACODEC; 125 129
Note:
See TracChangeset
for help on using the changeset viewer.