Changeset 82300 in vbox
- Timestamp:
- Nov 30, 2019 5:10:05 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 135124
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r82257 r82300 3141 3141 3142 3142 /** 3143 * @callback_method_impl{FNIOMMMIO READ, Looks up and calls the appropriate handler.}3143 * @callback_method_impl{FNIOMMMIONEWREAD, Looks up and calls the appropriate handler.} 3144 3144 * 3145 3145 * @note During implementation, we discovered so-called "forgotten" or "hole" … … 3147 3147 * spec. 3148 3148 */ 3149 PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)3149 static DECLCALLBACK(VBOXSTRICTRC) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 3150 3150 { 3151 3151 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); … … 3157 3157 * Look up and log. 3158 3158 */ 3159 uint32_t offReg = GCPhysAddr - pThis->MMIOBaseAddr; 3160 int idxRegDsc = hdaRegLookup(offReg); /* Register descriptor index. */ 3159 int idxRegDsc = hdaRegLookup(off); /* Register descriptor index. */ 3161 3160 #ifdef LOG_ENABLED 3162 3161 unsigned const cbLog = cb; 3163 uint32_t offRegLog = offReg;3162 uint32_t offRegLog = (uint32_t)off; 3164 3163 #endif 3165 3164 3166 Log3Func(("off Reg=%#x cb=%#x\n", offReg, cb));3167 Assert(cb == 4); Assert((off Reg& 3) == 0);3165 Log3Func(("off=%#x cb=%#x\n", offRegLog, cb)); 3166 Assert(cb == 4); Assert((off & 3) == 0); 3168 3167 3169 3168 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ); … … 3173 3172 3174 3173 if (idxRegDsc == -1) 3175 LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", offReg, cb));3174 LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", (uint32_t)off, cb)); 3176 3175 3177 3176 if (idxRegDsc != -1) … … 3210 3209 3211 3210 cbLeft -= cbReg; 3212 off Reg+= cbReg;3211 off += cbReg; 3213 3212 idxRegDsc++; 3214 } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == off Reg);3213 } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == off); 3215 3214 3216 3215 if (rc == VINF_SUCCESS) … … 3229 3228 3230 3229 rc = VINF_IOM_MMIO_UNUSED_FF; 3231 Log3Func(("\tHole at %x is accessed for read\n", offReg ));3230 Log3Func(("\tHole at %x is accessed for read\n", offRegLog)); 3232 3231 } 3233 3232 … … 3314 3313 3315 3314 /** 3316 * @callback_method_impl{FNIOMMMIOWRITE, Looks up and calls the appropriate handler.} 3317 */ 3318 PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 3315 * @callback_method_impl{FNIOMMMIOWNEWRITE, 3316 * Looks up and calls the appropriate handler.} 3317 */ 3318 static DECLCALLBACK(VBOXSTRICTRC) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 3319 3319 { 3320 3320 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); … … 3324 3324 3325 3325 /* 3326 * The behavior of accesses that aren't aligned on natural boundraries is3327 * undefined. Just reject them outright.3328 */3329 /** @todo IOM could check this, it could also split the 8 byte accesses for us. */3330 Assert(cb == 1 || cb == 2 || cb == 4 || cb == 8);3331 if (GCPhysAddr & (cb - 1))3332 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "misaligned write access: GCPhysAddr=%RGp cb=%u\n", GCPhysAddr, cb);3333 3334 /*3335 3326 * Look up and log the access. 3336 3327 */ 3337 uint32_t offReg = GCPhysAddr - pThis->MMIOBaseAddr; 3338 int idxRegDsc = hdaRegLookup(offReg); 3328 int idxRegDsc = hdaRegLookup(off); 3339 3329 #if defined(IN_RING3) || defined(LOG_ENABLED) 3340 3330 uint32_t idxRegMem = idxRegDsc != -1 ? g_aHdaRegMap[idxRegDsc].mem_idx : UINT32_MAX; … … 3346 3336 else if (cb == 8) u64Value = *(uint64_t const *)pv; 3347 3337 else 3348 { 3349 u64Value = 0; /* shut up gcc. */ 3350 AssertReleaseMsgFailed(("%u\n", cb)); 3351 } 3338 ASSERT_GUEST_MSG_FAILED_RETURN(("cb=%u %.*Rhxs\n", cb, cb, pv), 3339 PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "odd write size: off=%RGp cb=%u\n", off, cb)); 3340 3341 /* 3342 * The behavior of accesses that aren't aligned on natural boundraries is 3343 * undefined. Just reject them outright. 3344 */ 3345 ASSERT_GUEST_MSG_RETURN((off & (cb - 1)) == 0, ("off=%RGp cb=%u %.*Rhxs\n", off, cb, cb, pv), 3346 PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "misaligned write access: off=%RGp cb=%u\n", off, cb)); 3352 3347 3353 3348 #ifdef LOG_ENABLED 3354 3349 uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX; 3355 3350 if (idxRegDsc == -1) 3356 Log3Func(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb)); 3357 else if (cb == 4) 3358 Log3Func(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3359 else if (cb == 2) 3360 Log3Func(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3361 else if (cb == 1) 3362 Log3Func(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3363 3364 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 3365 Log3Func(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 3351 Log3Func(("@%#05x u32=%#010x cb=%d\n", (uint32_t)off, *(uint32_t const *)pv, cb)); 3352 else 3353 Log3Func(("@%#05x u%u=%#0*RX64 %s\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, g_aHdaRegMap[idxRegDsc].abbrev)); 3366 3354 #endif 3367 3355 … … 3369 3357 * Try for a direct hit first. 3370 3358 */ 3371 if (idxRegDsc != -1&& g_aHdaRegMap[idxRegDsc].size == cb)3359 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size == cb) 3372 3360 { 3373 3361 rc = hdaWriteReg(pDevIns, pThis, idxRegDsc, u64Value, ""); … … 3380 3368 { 3381 3369 #ifdef IN_RING3 3370 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 3371 Log3Func(("\tSize mismatch: %RU32 (reg) vs %u (access)!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 3372 3382 3373 /* 3383 3374 * If it's an access beyond the start of the register, shift the input … … 3386 3377 * shifting out input values. 3387 3378 */ 3388 if (idxRegDsc == -1 && (idxRegDsc = hdaR3RegLookupWithin(offReg)) != -1)3389 { 3390 uint32_t const cbBefore = offReg- g_aHdaRegMap[idxRegDsc].offset; Assert(cbBefore > 0 && cbBefore < 4);3391 off Reg-= cbBefore;3379 if (idxRegDsc < 0 && (idxRegDsc = hdaR3RegLookupWithin(off)) != -1) 3380 { 3381 uint32_t const cbBefore = (uint32_t)off - g_aHdaRegMap[idxRegDsc].offset; Assert(cbBefore > 0 && cbBefore < 4); 3382 off -= cbBefore; 3392 3383 idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; 3393 3384 u64Value <<= cbBefore * 8; … … 3402 3393 { 3403 3394 uint32_t cbReg; 3404 if (idxRegDsc != -1)3395 if (idxRegDsc >= 0) 3405 3396 { 3406 3397 idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; 3407 cbReg = g_aHdaRegMap[idxRegDsc].size;3398 cbReg = g_aHdaRegMap[idxRegDsc].size; 3408 3399 if (cb < cbReg) 3409 3400 { … … 3420 3411 else 3421 3412 { 3422 LogRel(("HDA: Invalid write access @0x%x\n", offReg));3413 LogRel(("HDA: Invalid write access @0x%x\n", (uint32_t)off)); 3423 3414 cbReg = 1; 3424 3415 } … … 3429 3420 3430 3421 /* Advance. */ 3431 off Reg+= cbReg;3432 cb 3422 off += cbReg; 3423 cb -= cbReg; 3433 3424 u64Value >>= cbReg * 8; 3434 3425 if (idxRegDsc == -1) 3435 idxRegDsc = hdaRegLookup(off Reg);3426 idxRegDsc = hdaRegLookup(off); 3436 3427 else 3437 3428 { 3438 3429 idxRegDsc++; 3439 3430 if ( (unsigned)idxRegDsc >= RT_ELEMENTS(g_aHdaRegMap) 3440 || g_aHdaRegMap[idxRegDsc].offset != offReg) 3441 { 3431 || g_aHdaRegMap[idxRegDsc].offset != off) 3442 3432 idxRegDsc = -1; 3443 }3444 3433 } 3445 3434 } … … 3458 3447 3459 3448 #ifdef IN_RING3 3460 /** 3461 * @callback_method_impl{FNPCIIOREGIONMAP} 3462 */ 3463 static DECLCALLBACK(int) hdaR3PciIoRegionMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 3464 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType) 3465 { 3449 3450 /* Saved state workers and callbacks. */ 3451 3452 static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStream) 3453 { 3454 RT_NOREF(pDevIns); 3455 # ifdef LOG_ENABLED 3466 3456 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3467 RT_NOREF(pPciDev, iRegion, enmType); 3468 3469 Assert(enmType == PCI_ADDRESS_SPACE_MEM); 3470 Assert(iRegion == 0); 3471 Assert(pPciDev == pDevIns->apPciDevs[0]); 3472 3473 /* 3474 * 18.2 of the ICH6 datasheet defines the valid access widths as byte, word, and double word. 3475 * 3476 * Let IOM talk DWORDs when reading, saves a lot of complications. On 3477 * writing though, we have to do it all ourselves because of sideeffects. 3478 */ 3479 Assert(enmType == PCI_ADDRESS_SPACE_MEM); 3480 int rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 3481 IOMMMIO_FLAGS_READ_DWORD 3482 | IOMMMIO_FLAGS_WRITE_PASSTHRU, 3483 hdaMMIOWrite, hdaMMIORead, "HDA"); 3484 3485 if (RT_FAILURE(rc)) 3486 return rc; 3487 3488 if (pThis->fRZEnabled) 3489 { 3490 rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/, 3491 "hdaMMIOWrite", "hdaMMIORead"); 3492 if (RT_FAILURE(rc)) 3493 return rc; 3494 3495 rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/, 3496 "hdaMMIOWrite", "hdaMMIORead"); 3497 if (RT_FAILURE(rc)) 3498 return rc; 3499 } 3500 3501 pThis->MMIOBaseAddr = GCPhysAddress; 3502 return VINF_SUCCESS; 3503 } 3504 3505 3506 /* Saved state workers and callbacks. */ 3507 3508 static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStream) 3509 { 3510 RT_NOREF(pDevIns); 3511 #if defined(LOG_ENABLED) 3512 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 3513 #endif 3457 # endif 3514 3458 3515 3459 Log2Func(("[SD%RU8]\n", pStream->u8SD)); … … 4921 4865 AssertRCReturn(rc, rc); 4922 4866 4923 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaR3PciIoRegionMap); 4867 rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaMMIOWrite, hdaMMIORead, NULL /*pvUser*/, 4868 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU, "HDA", &pThis->hMmio); 4924 4869 AssertRCReturn(rc, rc); 4925 4870 … … 5263 5208 } 5264 5209 5265 #endif /* IN_RING3 */ 5210 #else /* !IN_RING3 */ 5211 5212 /** 5213 * @callback_method_impl{PDMDEVREGR0,pfnConstruct} 5214 */ 5215 static DECLCALLBACK(int) ohciRZConstruct(PPDMDEVINS pDevIns) 5216 { 5217 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */ 5218 PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE); 5219 5220 int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, hdaMMIOWrite, hdaMMIORead, NULL /*pvUser*/); 5221 AssertRCReturn(rc, rc); 5222 5223 return VINF_SUCCESS; 5224 } 5225 5226 #endif /* !IN_RING3 */ 5266 5227 5267 5228 /** -
trunk/src/VBox/Devices/Audio/DevHDA.h
r81031 r82300 109 109 /** The base interface for LUN\#0. */ 110 110 PDMIBASE IBase; 111 RTGCPHYS MMIOBaseAddr;112 111 /** The HDA's register set. */ 113 112 uint32_t au32Regs[HDA_NUM_REGS]; … … 196 195 uint8_t au8Padding3[3]; 197 196 HDASTATEDBGINFO Dbg; 197 198 /** PCI Region \#0: 16KB of MMIO stuff. */ 199 IOMMMIOHANDLE hMmio; 200 198 201 #ifdef VBOX_WITH_STATISTICS 199 202 STAMPROFILE StatTimer;
Note:
See TracChangeset
for help on using the changeset viewer.