Changeset 64800 in vbox for trunk/src/VBox
- Timestamp:
- Dec 7, 2016 10:20:50 AM (8 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r64792 r64800 547 547 #define HDA_RMX_SD7BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 70) 548 548 549 #define HDA_BDLE_FLAG_IOC RT_BIT(0) /* Interrupt on completion (IOC). */ 550 549 551 #define HDA_CODEC_CAD_SHIFT 28 550 552 /* Encodes the (required) LUN into a codec command. */ … … 575 577 576 578 /** 577 * Buffer Descriptor List Entry (BDLE) (3.6.3). 578 * 579 * Contains only register values which do *not* change until a 580 * stream reset occurs. 581 */ 582 typedef struct HDABDLE 579 * BDL description structure. 580 * Do not touch this, as this must match to the HDA specs. 581 */ 582 typedef struct HDABDLEDESC 583 583 { 584 584 /** Starting address of the actual buffer. Must be 128-bit aligned. */ … … 586 586 /** Size of the actual buffer (in bytes). */ 587 587 uint32_t u32BufSize; 588 /** Interrupt on completion; the controller will generate588 /** Bit 0: Interrupt on completion; the controller will generate 589 589 * an interrupt when the last byte of the buffer has been 590 * fetched by the DMA engine. */ 591 bool fIntOnCompletion; 590 * fetched by the DMA engine. 591 * 592 * Rest is reserved for further use and must be 0. */ 593 uint32_t fFlags; 594 } HDABDLEDESC, *PHDABDLEDESC; 595 AssertCompileSize(HDABDLEDESC, 16); /* Always 16 byte. Also must be aligned on 128-byte boundary. */ 596 597 /** 598 * Buffer Descriptor List Entry (BDLE) (3.6.3). 599 */ 600 typedef struct HDABDLE 601 { 602 /** The actual BDL description. */ 603 HDABDLEDESC Desc; 592 604 /** Internal state of this BDLE. 593 605 * Not part of the actual BDLE registers. */ … … 1141 1153 1142 1154 #ifdef IN_RING3 1143 /** HDABDLE field descriptors for the v6+ saved state. */1144 static SSMFIELD const g_aSSMBDLE Fields6[] =1145 { 1146 SSMFIELD_ENTRY(HDABDLE , u64BufAdr),1147 SSMFIELD_ENTRY(HDABDLE , u32BufSize),1148 SSMFIELD_ENTRY(HDABDLE , fIntOnCompletion),1155 /** HDABDLEDESC field descriptors for the v6+ saved state. */ 1156 static SSMFIELD const g_aSSMBDLEDescFields6[] = 1157 { 1158 SSMFIELD_ENTRY(HDABDLEDESC, u64BufAdr), 1159 SSMFIELD_ENTRY(HDABDLEDESC, u32BufSize), 1160 SSMFIELD_ENTRY(HDABDLEDESC, fFlags), 1149 1161 SSMFIELD_ENTRY_TERM() 1150 1162 }; … … 1255 1267 bool fWrapAround = false; 1256 1268 1257 AssertMsg(pBDLE->State.u32BufOff == pBDLE-> u32BufSize, ("BDLE not finished yet: %R[bdle]\n", pBDLE));1269 AssertMsg(pBDLE->State.u32BufOff == pBDLE->Desc.u32BufSize, ("BDLE not finished yet: %R[bdle]\n", pBDLE)); 1258 1270 1259 1271 /* … … 3139 3151 /** @todo Compare u16Entry with LVI. */ 3140 3152 3141 uint8_t uBundleEntry[16]; /** @todo Define a BDLE length. */ 3142 int rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + u16Entry * 16, /** @todo Define a BDLE length. */ 3143 uBundleEntry, RT_ELEMENTS(uBundleEntry)); 3153 int rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + u16Entry * sizeof(HDABDLEDESC), 3154 &pBDLE->Desc, sizeof(pBDLE->Desc)); 3144 3155 if (RT_FAILURE(rc)) 3145 3156 return rc; 3146 3157 3147 RT_BZERO(pBDLE, sizeof(HDABDLE)); 3158 /* Clear internal state. */ 3159 RT_BZERO(&pBDLE->State, sizeof(HDABDLESTATE)); 3148 3160 3149 3161 pBDLE->State.u32BDLIndex = u16Entry; 3150 pBDLE->u64BufAdr = *(uint64_t *) uBundleEntry;3151 pBDLE->u32BufSize = *(uint32_t *)&uBundleEntry[8];3152 if (pBDLE->u32BufSize < sizeof(uint16_t)) /* Must be at least one word. */3153 return VERR_INVALID_STATE;3154 3155 pBDLE->fIntOnCompletion = (*(uint32_t *)&uBundleEntry[12]) & RT_BIT(0);3156 3162 3157 3163 return VINF_SUCCESS; … … 3179 3185 3180 3186 /* Limit to the available free space of the current BDLE. */ 3181 cbData = RT_MIN(cbData, pBDLE-> u32BufSize - pBDLE->State.u32BufOff);3182 AssertMsg(cbData, ("No BDLE space left (%RU32/%RU32): %R[bdle]\n", pBDLE->State.u32BufOff, pBDLE-> u32BufSize, pBDLE));3187 cbData = RT_MIN(cbData, pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 3188 AssertMsg(cbData, ("No BDLE space left (%RU32/%RU32): %R[bdle]\n", pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize, pBDLE)); 3183 3189 3184 3190 /* Make sure we only transfer as many bytes as requested. */ … … 3213 3219 return; 3214 3220 3215 Assert(pBDLE-> u32BufSize >= cbProcessed);3221 Assert(pBDLE->Desc.u32BufSize >= cbProcessed); 3216 3222 3217 3223 /* Fewer than cbBelowFIFOW bytes were copied. … … 3227 3233 { 3228 3234 LogFlowFunc(("BDLE(cbUnderFifoW:%RU32, off:%RU32, size:%RU32)\n", 3229 pBDLE->State.cbBelowFIFOW, pBDLE->State.u32BufOff, pBDLE-> u32BufSize));3235 pBDLE->State.cbBelowFIFOW, pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize)); 3230 3236 } 3231 3237 #endif … … 3236 3242 /* We always increment the position of DMA buffer counter because we're always reading 3237 3243 * into an intermediate buffer. */ 3238 Assert(pBDLE-> u32BufSize >= (pBDLE->State.u32BufOff + cbProcessed));3244 Assert(pBDLE->Desc.u32BufSize >= (pBDLE->State.u32BufOff + cbProcessed)); 3239 3245 pBDLE->State.u32BufOff += cbProcessed; 3240 3246 … … 3365 3371 * the CBL limit or our internal DMA buffer is full. */ 3366 3372 bool fNeedsNextBDLE = ( fCBLLimitReached 3367 || (pBDLE->State.u32BufOff >= pBDLE-> u32BufSize));3373 || (pBDLE->State.u32BufOff >= pBDLE->Desc.u32BufSize)); 3368 3374 3369 3375 Assert(u32LPIB <= pStream->u32CBL); 3370 Assert(pBDLE->State.u32BufOff <= pBDLE-> u32BufSize);3376 Assert(pBDLE->State.u32BufOff <= pBDLE->Desc.u32BufSize); 3371 3377 3372 3378 LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, fCBLLimitReached=%RTbool, fNeedsNextBDLE=%RTbool, %R[bdle]\n", … … 3409 3415 3410 3416 /* Check if the current BDLE entry is complete (full). */ 3411 if (pBDLE->State.u32BufOff >= pBDLE-> u32BufSize)3412 { 3413 Assert(pBDLE->State.u32BufOff <= pBDLE-> u32BufSize);3417 if (pBDLE->State.u32BufOff >= pBDLE->Desc.u32BufSize) 3418 { 3419 Assert(pBDLE->State.u32BufOff <= pBDLE->Desc.u32BufSize); 3414 3420 3415 3421 if (/* IOC (Interrupt On Completion) bit set? */ 3416 pBDLE-> fIntOnCompletion3422 pBDLE->Desc.fFlags & HDA_BDLE_FLAG_IOC 3417 3423 /* All data put into the DMA FIFO? */ 3418 3424 && pBDLE->State.cbBelowFIFOW == 0 … … 3473 3479 Assert(cbRead <= cbToRead); 3474 3480 Assert(cbRead <= sizeof(pBDLE->State.au8FIFO)); 3475 Assert(cbRead <= pBDLE-> u32BufSize - pBDLE->State.u32BufOff);3481 Assert(cbRead <= pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 3476 3482 3477 3483 /* … … 3479 3485 */ 3480 3486 rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 3481 pBDLE-> u64BufAdr + pBDLE->State.u32BufOff,3487 pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff, 3482 3488 pBDLE->State.au8FIFO, cbRead); 3483 3489 AssertRC(rc); … … 3492 3498 if (pBDLE->State.cbBelowFIFOW + cbRead > hdaStreamGetFIFOW(pThis, pStream)) 3493 3499 { 3494 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE-> u32BufSize);3500 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->Desc.u32BufSize); 3495 3501 pBDLE->State.u32BufOff += cbRead; 3496 3502 pBDLE->State.cbBelowFIFOW = 0; … … 3499 3505 else 3500 3506 { 3501 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE-> u32BufSize);3507 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->Desc.u32BufSize); 3502 3508 pBDLE->State.u32BufOff += cbRead; 3503 3509 pBDLE->State.cbBelowFIFOW += cbRead; … … 3551 3557 */ 3552 3558 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 3553 pBDLE-> u64BufAdr + pBDLE->State.u32BufOff,3559 pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff, 3554 3560 pvBuf, cbBuf); 3555 3561 AssertRC(rc); … … 3649 3655 AssertFailed(); 3650 3656 3651 Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE-> u32BufSize);3657 Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE->Desc.u32BufSize); 3652 3658 pBDLE->State.u32BufOff += cbWritten; 3653 3659 pBDLE->State.cbBelowFIFOW += cbWritten; … … 4316 4322 { 4317 4323 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 4318 pBDLE-> u64BufAdr + pBDLE->State.u32BufOff,4324 pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff, 4319 4325 (uint8_t *)pvBuf + cbTotal, cbChunk); 4320 4326 } … … 4322 4328 { 4323 4329 PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), 4324 pBDLE-> u64BufAdr + pBDLE->State.u32BufOff,4330 pBDLE->Desc.u64BufAdr + pBDLE->State.u32BufOff, 4325 4331 (uint8_t *)pvBuf + cbTotal, cbChunk); 4326 4332 } … … 4340 4346 4341 4347 LogFunc(("DMA: Entry %RU32 Pos %RU32/%RU32 Chunk %RU32\n", 4342 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE-> u32BufSize, cbChunk));4348 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->Desc.u32BufSize, cbChunk)); 4343 4349 4344 4350 Assert(cbLeft >= cbChunkProcessed); … … 4850 4856 4851 4857 rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE), 4852 0 /*fFlags*/, g_aSSMBDLE Fields6, NULL);4858 0 /*fFlags*/, g_aSSMBDLEDescFields6, NULL); 4853 4859 AssertRCReturn(rc, rc); 4854 4860 … … 4867 4873 AssertRC(rc); 4868 4874 4869 Assert(curBDLE. u32BufSize == pBDLE->u32BufSize);4870 Assert(curBDLE. u64BufAdr == pBDLE->u64BufAdr);4871 Assert(curBDLE. fIntOnCompletion == pBDLE->fIntOnCompletion);4875 Assert(curBDLE.Desc.u32BufSize == pBDLE->Desc.u32BufSize); 4876 Assert(curBDLE.Desc.u64BufAdr == pBDLE->Desc.u64BufAdr); 4877 Assert(curBDLE.Desc.fFlags == pBDLE->Desc.fFlags); 4872 4878 } 4873 4879 else 4874 4880 { 4875 Assert(pBDLE-> u64BufAdr == 0);4876 Assert(pBDLE-> u32BufSize == 0);4881 Assert(pBDLE->Desc.u64BufAdr == 0); 4882 Assert(pBDLE->Desc.u32BufSize == 0); 4877 4883 } 4878 4884 #endif … … 4988 4994 * according to the spec). 4989 4995 */ 4990 #define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x) \ 4991 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */ \ 4992 AssertRCReturn(rc, rc); \ 4993 rc = SSMR3GetU64(pSSM, &x.u64BufAdr); /* u64BdleCviAddr */ \ 4994 AssertRCReturn(rc, rc); \ 4995 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* u32BdleMaxCvi */ \ 4996 AssertRCReturn(rc, rc); \ 4997 rc = SSMR3GetU32(pSSM, &x.State.u32BDLIndex); /* u32BdleCvi */ \ 4998 AssertRCReturn(rc, rc); \ 4999 rc = SSMR3GetU32(pSSM, &x.u32BufSize); /* u32BdleCviLen */ \ 5000 AssertRCReturn(rc, rc); \ 5001 rc = SSMR3GetU32(pSSM, &x.State.u32BufOff); /* u32BdleCviPos */ \ 5002 AssertRCReturn(rc, rc); \ 5003 rc = SSMR3GetBool(pSSM, &x.fIntOnCompletion); /* fBdleCviIoc */ \ 5004 AssertRCReturn(rc, rc); \ 5005 rc = SSMR3GetU32(pSSM, &x.State.cbBelowFIFOW); /* cbUnderFifoW */ \ 5006 AssertRCReturn(rc, rc); \ 5007 rc = SSMR3Skip(pSSM, sizeof(uint8_t) * 256); /* FIFO */ \ 5008 AssertRCReturn(rc, rc); \ 5009 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* End marker */ \ 5010 AssertRCReturn(rc, rc); \ 4996 #define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x) \ 4997 { \ 4998 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */ \ 4999 AssertRCReturn(rc, rc); \ 5000 rc = SSMR3GetU64(pSSM, &x.Desc.u64BufAdr); /* u64BdleCviAddr */ \ 5001 AssertRCReturn(rc, rc); \ 5002 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* u32BdleMaxCvi */ \ 5003 AssertRCReturn(rc, rc); \ 5004 rc = SSMR3GetU32(pSSM, &x.State.u32BDLIndex); /* u32BdleCvi */ \ 5005 AssertRCReturn(rc, rc); \ 5006 rc = SSMR3GetU32(pSSM, &x.Desc.u32BufSize); /* u32BdleCviLen */ \ 5007 AssertRCReturn(rc, rc); \ 5008 rc = SSMR3GetU32(pSSM, &x.State.u32BufOff); /* u32BdleCviPos */ \ 5009 AssertRCReturn(rc, rc); \ 5010 bool fIOC; \ 5011 rc = SSMR3GetBool(pSSM, &fIOC); /* fBdleCviIoc */ \ 5012 AssertRCReturn(rc, rc); \ 5013 x.Desc.fFlags = fIOC ? HDA_BDLE_FLAG_IOC : 0; \ 5014 rc = SSMR3GetU32(pSSM, &x.State.cbBelowFIFOW); /* cbUnderFifoW */ \ 5015 AssertRCReturn(rc, rc); \ 5016 rc = SSMR3Skip(pSSM, sizeof(uint8_t) * 256); /* FIFO */ \ 5017 AssertRCReturn(rc, rc); \ 5018 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* End marker */ \ 5019 AssertRCReturn(rc, rc); \ 5020 } \ 5011 5021 5012 5022 /* … … 5141 5151 5142 5152 rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE), 5143 0 /* fFlags */, g_aSSMBDLE Fields6, NULL);5153 0 /* fFlags */, g_aSSMBDLEDescFields6, NULL); 5144 5154 if (RT_FAILURE(rc)) 5145 5155 break; … … 5213 5223 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, 5214 5224 "BDLE(idx:%RU32, off:%RU32, fifow:%RU32, IOC:%RTbool, DMA[%RU32 bytes @ 0x%x])", 5215 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->State.cbBelowFIFOW, pBDLE->fIntOnCompletion,5216 pBDLE-> u32BufSize, pBDLE->u64BufAdr);5225 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->State.cbBelowFIFOW, 5226 pBDLE->Desc.fFlags & HDA_BDLE_FLAG_IOC, pBDLE->Desc.u32BufSize, pBDLE->Desc.u64BufAdr); 5217 5227 } 5218 5228 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r64761 r64800 1844 1844 GEN_CHECK_OFF(HDABDLESTATE, u32BufOff); 1845 1845 1846 GEN_CHECK_SIZE(HDABDLEDESC); 1847 GEN_CHECK_OFF(HDABDLEDESC, u64BufAdr); 1848 GEN_CHECK_OFF(HDABDLEDESC, u32BufSize); 1849 GEN_CHECK_OFF(HDABDLEDESC, fFlags); 1850 1846 1851 GEN_CHECK_SIZE(HDABDLE); 1847 GEN_CHECK_OFF(HDABDLE, u64BufAdr); 1848 GEN_CHECK_OFF(HDABDLE, u32BufSize); 1849 GEN_CHECK_OFF(HDABDLE, fIntOnCompletion); 1852 GEN_CHECK_OFF(HDABDLE, Desc); 1850 1853 GEN_CHECK_OFF(HDABDLE, State); 1851 1854
Note:
See TracChangeset
for help on using the changeset viewer.