Changeset 82401 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Dec 4, 2019 11:33:29 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r82399 r82401 532 532 }; 533 533 534 #endif /* IN_RING3 */ 535 534 536 /** 535 537 * 32-bit size indexed masks, i.e. g_afMasks[2 bytes] = 0xffff. … … 540 542 }; 541 543 542 #endif /* IN_RING3 */543 544 544 545 … … 2981 2982 } 2982 2983 2983 #endif /* IN_RING3 */ 2984 #else /* !IN_RING3 */ 2985 2986 /** 2987 * Checks if a dword read starting with @a idxRegDsc is safe. 2988 * 2989 * We can guarentee it only standard reader callbacks are used. 2990 * @returns true if it will always succeed, false if it may return back to 2991 * ring-3 or we're just not sure. 2992 * @param idxRegDsc The first register descriptor in the DWORD being read. 2993 */ 2994 DECLINLINE(bool) hdaIsMultiReadSafeInRZ(unsigned idxRegDsc) 2995 { 2996 int32_t cbLeft = 4; /* signed on purpose */ 2997 do 2998 { 2999 if ( g_aHdaRegMap[idxRegDsc].pfnRead == hdaRegReadU24 3000 || g_aHdaRegMap[idxRegDsc].pfnRead == hdaRegReadU16 3001 || g_aHdaRegMap[idxRegDsc].pfnRead == hdaRegReadU8 3002 || g_aHdaRegMap[idxRegDsc].pfnRead == hdaRegReadUnimpl) 3003 { /* okay */ } 3004 else 3005 { 3006 Log4(("hdaIsMultiReadSafeInRZ: idxRegDsc=%u %s\n", idxRegDsc, g_aHdaRegMap[idxRegDsc].abbrev)); 3007 return false; 3008 } 3009 3010 idxRegDsc++; 3011 if (idxRegDsc < RT_ELEMENTS(g_aHdaRegMap)) 3012 cbLeft -= g_aHdaRegMap[idxRegDsc].offset - g_aHdaRegMap[idxRegDsc - 1].offset; 3013 else 3014 break; 3015 } while (cbLeft > 0); 3016 return true; 3017 } 3018 3019 3020 #endif /* !IN_RING3 */ 3021 2984 3022 2985 3023 /* MMIO callbacks */ … … 3029 3067 STAM_COUNTER_INC(&pThis->aStatRegReads[idxRegDsc]); 3030 3068 } 3069 #ifndef IN_RING3 3070 else if (!hdaIsMultiReadSafeInRZ(idxRegDsc)) 3071 3072 { 3073 STAM_COUNTER_INC(&pThis->aStatRegReadsToR3[idxRegDsc]); 3074 rc = VINF_IOM_R3_MMIO_READ; 3075 } 3076 #endif 3031 3077 else 3032 3078 { … … 3035 3081 * ASSUMES that only DWORD reads have sideeffects. 3036 3082 */ 3037 #ifdef IN_RING3 3038 STAM_COUNTER_INC(&pThis->StatRegMultiReads);3083 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatRegMultiReads)); 3084 Log4(("hdaMmioRead: multi read: %#x LB %#x %s\n", off, cb, g_aHdaRegMap[idxRegDsc].abbrev)); 3039 3085 uint32_t u32Value = 0; 3040 3086 unsigned cbLeft = 4; … … 3045 3091 3046 3092 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pDevIns, pThis, idxRegDsc, &u32Tmp); 3047 Log 3Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, VBOXSTRICTRC_VAL(rc)));3093 Log4Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, VBOXSTRICTRC_VAL(rc))); 3048 3094 STAM_COUNTER_INC(&pThis->aStatRegReads[idxRegDsc]); 3095 #ifdef IN_RING3 3049 3096 if (rc != VINF_SUCCESS) 3050 3097 break; 3098 #else 3099 AssertMsgBreak(rc == VINF_SUCCESS, ("rc=%Rrc - impossible, we sanitized the readers!\n", VBOXSTRICTRC_VAL(rc))); 3100 #endif 3051 3101 u32Value |= (u32Tmp & g_afMasks[cbReg]) << ((4 - cbLeft) * 8); 3052 3102 … … 3060 3110 else 3061 3111 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 3112 } 3068 3113 } … … 3197 3242 #ifdef LOG_ENABLED 3198 3243 uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX; 3199 if (idxRegDsc == -1)3200 Log3Func(("@%#05x u32=%#010x cb=%d\n", (uint32_t)off, *(uint32_t const *)pv, cb));3201 else3202 Log3Func(("@%#05x u%u=%#0*RX64 %s\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, g_aHdaRegMap[idxRegDsc].abbrev));3203 3244 #endif 3204 3245 … … 3209 3250 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size == cb) 3210 3251 { 3252 Log3Func(("@%#05x u%u=%#0*RX64 %s\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, g_aHdaRegMap[idxRegDsc].abbrev)); 3211 3253 rc = hdaWriteReg(pDevIns, pThis, idxRegDsc, u64Value, ""); 3212 3254 Log3Func(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX)); 3255 } 3256 /* 3257 * Sub-register access. Supply missing bits as needed. 3258 */ 3259 else if ( idxRegDsc >= 0 3260 && cb < g_aHdaRegMap[idxRegDsc].size) 3261 { 3262 u64Value |= pThis->au32Regs[g_aHdaRegMap[idxRegDsc].mem_idx] 3263 & g_afMasks[g_aHdaRegMap[idxRegDsc].size] 3264 & ~g_afMasks[cb]; 3265 Log4Func(("@%#05x u%u=%#0*RX64 cb=%#x cbReg=%x %s\n" 3266 "\tSupplying missing bits (%#x): %#llx -> %#llx ...\n", 3267 (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, cb, g_aHdaRegMap[idxRegDsc].size, g_aHdaRegMap[idxRegDsc].abbrev, 3268 g_afMasks[g_aHdaRegMap[idxRegDsc].size] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value)); 3269 rc = hdaWriteReg(pDevIns, pThis, idxRegDsc, u64Value, ""); 3270 Log4Func(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX)); 3271 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatRegSubWrite)); 3213 3272 } 3214 3273 /* … … 3218 3277 { 3219 3278 #ifdef IN_RING3 3220 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 3221 Log3Func(("\tSize mismatch: %RU32 (reg) vs %u (access)!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 3279 if (idxRegDsc == -1) 3280 Log4Func(("@%#05x u32=%#010x cb=%d\n", (uint32_t)off, *(uint32_t const *)pv, cb)); 3281 else if (g_aHdaRegMap[idxRegDsc].size == cb) 3282 Log4Func(("@%#05x u%u=%#0*RX64 %s\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, g_aHdaRegMap[idxRegDsc].abbrev)); 3283 else 3284 Log4Func(("@%#05x u%u=%#0*RX64 %s - mismatch cbReg=%u\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, 3285 g_aHdaRegMap[idxRegDsc].abbrev, g_aHdaRegMap[idxRegDsc].size)); 3222 3286 3223 3287 /* … … 3238 3302 u64Value <<= cbBefore * 8; 3239 3303 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 3240 Log 3Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n",3304 Log4Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n", 3241 3305 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 3242 STAM_COUNTER_INC(&pThis-> StatRegMultiWrites);3306 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatRegMultiWrites)); 3243 3307 } 3244 3308 else … … 3246 3310 } 3247 3311 else 3248 STAM_COUNTER_INC(&pThis->StatRegMultiWrites); 3249 3312 { 3313 Log4(("hdaMmioWrite: multi write: %s\n", g_aHdaRegMap[idxRegDsc].abbrev)); 3314 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatRegMultiWrites)); 3315 } 3250 3316 3251 3317 /* Loop thru the write area, it may cover multiple registers. */ … … 3261 3327 { 3262 3328 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb]; 3263 Log 3Func(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n",3329 Log4Func(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n", 3264 3330 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value)); 3265 3331 } … … 3268 3334 # endif 3269 3335 rc = hdaWriteReg(pDevIns, pThis, idxRegDsc, u64Value, "*"); 3270 Log 3Func(("\t%#x -> %#x\n", uLogOldVal, pThis->au32Regs[idxRegMem]));3336 Log4Func(("\t%#x -> %#x\n", uLogOldVal, pThis->au32Regs[idxRegMem])); 3271 3337 } 3272 3338 else … … 4717 4783 AssertRCReturn(rc, rc); 4718 4784 4785 /** @todo r=bird: The IOMMMIO_FLAGS_READ_DWORD flag isn't entirely optimal, 4786 * as several frequently used registers aren't dword sized. 6.0 and earlier 4787 * will go to ring-3 to handle accesses to any such register, where-as 6.1 and 4788 * later will do trivial register reads in ring-0. Real optimal code would use 4789 * IOMMMIO_FLAGS_READ_PASSTHRU and do the necessary extra work to deal with 4790 * anything the guest may throw at us. */ 4719 4791 rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaMmioWrite, hdaMmioRead, NULL /*pvUser*/, 4720 4792 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU, "HDA", &pThis->hMmio); … … 5077 5149 g_aHdaRegMap[i].desc, "Regs/%03x-%s-Writes-ToR3", g_aHdaRegMap[i].offset, g_aHdaRegMap[i].abbrev); 5078 5150 } 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"); 5151 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiReadsR3, STAMTYPE_COUNTER, "RegMultiReadsR3", STAMUNIT_OCCURENCES, "Register read not targeting just one register, handled in ring-3"); 5152 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiReadsRZ, STAMTYPE_COUNTER, "RegMultiReadsRZ", STAMUNIT_OCCURENCES, "Register read not targeting just one register, handled in ring-0"); 5153 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiWritesR3, STAMTYPE_COUNTER, "RegMultiWritesR3", STAMUNIT_OCCURENCES, "Register writes not targeting just one register, handled in ring-3"); 5154 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegMultiWritesRZ, STAMTYPE_COUNTER, "RegMultiWritesRZ", STAMUNIT_OCCURENCES, "Register writes not targeting just one register, handled in ring-0"); 5155 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegSubWriteR3, STAMTYPE_COUNTER, "RegSubWritesR3", STAMUNIT_OCCURENCES, "Trucated register writes, handled in ring-3"); 5156 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegSubWriteRZ, STAMTYPE_COUNTER, "RegSubWritesRZ", STAMUNIT_OCCURENCES, "Trucated register writes, handled in ring-0"); 5081 5157 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegUnknownReads, STAMTYPE_COUNTER, "RegUnknownReads", STAMUNIT_OCCURENCES, "Reads of unknown registers."); 5082 5158 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRegUnknownWrites, STAMTYPE_COUNTER, "RegUnknownWrites", STAMUNIT_OCCURENCES, "Writes to unknown registers."); -
trunk/src/VBox/Devices/Audio/DevHDA.h
r82399 r82401 209 209 STAMCOUNTER aStatRegWrites[HDA_NUM_REGS]; 210 210 STAMCOUNTER aStatRegWritesToR3[HDA_NUM_REGS]; 211 STAMCOUNTER StatRegMultiReads; 212 STAMCOUNTER StatRegMultiWrites; 211 STAMCOUNTER StatRegMultiReadsRZ; 212 STAMCOUNTER StatRegMultiReadsR3; 213 STAMCOUNTER StatRegMultiWritesRZ; 214 STAMCOUNTER StatRegMultiWritesR3; 215 STAMCOUNTER StatRegSubWriteRZ; 216 STAMCOUNTER StatRegSubWriteR3; 213 217 STAMCOUNTER StatRegUnknownReads; 214 218 STAMCOUNTER StatRegUnknownWrites;
Note:
See TracChangeset
for help on using the changeset viewer.