Changeset 34146 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Nov 17, 2010 8:41:56 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 67866
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r34062 r34146 301 301 #define ICH6_HDA_REG_SD7FIFOW (HDA_STREAM_REG_DEF(FIFOW, 0) + 70) /* 0x16E */ 302 302 303 /* 304 * ICH6 datasheet defined limits for FIFOW values (18.2.38) 305 */ 306 #define HDA_SDFIFOW_8B (0x2) 307 #define HDA_SDFIFOW_16B (0x3) 308 #define HDA_SDFIFOW_32B (0x4) 309 #define SDFIFOW(pState, num) HDA_REG((pState), SD(FIFOW, num)) 310 303 311 #define ICH6_HDA_REG_SD0FIFOS 38 /* 0x90 */ 304 312 #define ICH6_HDA_REG_SD1FIFOS (HDA_STREAM_REG_DEF(FIFOS, 0) + 10) /* 0xB0 */ … … 376 384 uint32_t u32BdleCviPos; 377 385 bool fBdleCviIoc; 386 uint32_t cbUnderFifoW; 387 uint8_t au8HdaBuffer[HDA_SDONFIFO_256B + 1]; 378 388 } HDABDLEDESC, *PHDABDLEDESC; 379 389 … … 430 440 } PCIINTELHDLinkState; 431 441 442 432 443 DECLCALLBACK(int)hdaRegReadUnimplemented(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value); 433 444 DECLCALLBACK(int)hdaRegWriteUnimplemented(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value); … … 452 463 DECLCALLBACK(int)hdaRegWriteSDSTS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value); 453 464 DECLCALLBACK(int)hdaRegWriteSDLVI(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value); 465 DECLCALLBACK(int)hdaRegWriteSDFIFOW(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value); 454 466 DECLCALLBACK(int)hdaRegWriteSDFIFOS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value); 455 467 DECLCALLBACK(int)hdaRegWriteSDBDPL(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value); … … 530 542 { 0x00088, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "ISD0CBL" , "ISD0 Cyclic Buffer Length" }, 531 543 { 0x0008C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "ISD0LVI" , "ISD0 Last Valid Index" }, 532 { 0x0008E, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "ISD0FIFOW", "ISD0 FIFO Watermark" },544 { 0x0008E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "ISD0FIFOW", "ISD0 FIFO Watermark" }, 533 545 { 0x00090, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16 , hdaRegWriteU16 , "ISD0FIFOS", "ISD0 FIFO Size" }, 534 546 { 0x00092, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "ISD0FMT" , "ISD0 Format" }, … … 541 553 { 0x000A8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "ISD1CBL" , "ISD1 Cyclic Buffer Length" }, 542 554 { 0x000AC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "ISD1LVI" , "ISD1 Last Valid Index" }, 543 { 0x000AE, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "ISD1FIFOW", "ISD1 FIFO Watermark" },555 { 0x000AE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "ISD1FIFOW", "ISD1 FIFO Watermark" }, 544 556 { 0x000B0, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16 , hdaRegWriteU16 , "ISD1FIFOS", "ISD1 FIFO Size" }, 545 557 { 0x000B2, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "ISD1FMT" , "ISD1 Format" }, … … 552 564 { 0x000C8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "ISD2CBL" , "ISD2 Cyclic Buffer Length" }, 553 565 { 0x000CC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "ISD2LVI" , "ISD2 Last Valid Index" }, 554 { 0x000CE, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "ISD2FIFOW", "ISD2 FIFO Watermark" },566 { 0x000CE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "ISD2FIFOW", "ISD2 FIFO Watermark" }, 555 567 { 0x000D0, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16 , hdaRegWriteU16 , "ISD2FIFOS", "ISD2 FIFO Size" }, 556 568 { 0x000D2, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "ISD2FMT" , "ISD2 Format" }, … … 574 586 { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "OSD0CBL" , "OSD0 Cyclic Buffer Length" }, 575 587 { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "OSD0LVI" , "OSD0 Last Valid Index" }, 576 { 0x0010E, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "OSD0FIFOW", "OSD0 FIFO Watermark" },588 { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "OSD0FIFOW", "OSD0 FIFO Watermark" }, 577 589 { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , "OSD0FIFOS", "OSD0 FIFO Size" }, 578 590 { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "OSD0FMT" , "OSD0 Format" }, … … 585 597 { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "OSD1CBL" , "OSD1 Cyclic Buffer Length" }, 586 598 { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "OSD1LVI" , "OSD1 Last Valid Index" }, 587 { 0x0012E, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "OSD1FIFOW", "OSD1 FIFO Watermark" },599 { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "OSD1FIFOW", "OSD1 FIFO Watermark" }, 588 600 { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , "OSD1FIFOS", "OSD1 FIFO Size" }, 589 601 { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "OSD1FMT" , "OSD1 Format" }, … … 596 608 { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "OSD2CBL" , "OSD2 Cyclic Buffer Length" }, 597 609 { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "OSD2LVI" , "OSD2 Last Valid Index" }, 598 { 0x0014E, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "OSD2FIFOW", "OSD2 FIFO Watermark" },610 { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "OSD2FIFOW", "OSD2 FIFO Watermark" }, 599 611 { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , "OSD2FIFOS", "OSD2 FIFO Size" }, 600 612 { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "OSD2FMT" , "OSD2 Format" }, … … 607 619 { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , "OSD3CBL" , "OSD3 Cyclic Buffer Length" }, 608 620 { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , "OSD3LVI" , "OSD3 Last Valid Index" }, 609 { 0x0016E, 0x00002, 0x0000000 5, 0x00000005, hdaRegReadU16 , hdaRegWriteU16, "OSD3FIFOW", "OSD3 FIFO Watermark" },621 { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , "OSD3FIFOW", "OSD3 FIFO Watermark" }, 610 622 { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , "OSD3FIFOS", "OSD3 FIFO Size" }, 611 623 { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteU16 , "OSD3FMT" , "OSD3 Format" }, … … 613 625 { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , "OSD3BDPU" , "OSD3 Buffer Descriptor List Pointer-Upper Base Address" }, 614 626 }; 627 628 static uint32_t inline hdaFifoWToSz(INTELHDLinkState *pState, int iNum) 629 { 630 switch (ICH6_HDA_REG_SD0FIFOW + 10*iNum) 631 { 632 case ICH6_HDA_REG_SD0FIFOW: 633 case ICH6_HDA_REG_SD1FIFOW: 634 case ICH6_HDA_REG_SD2FIFOW: 635 case ICH6_HDA_REG_SD3FIFOW: 636 case ICH6_HDA_REG_SD4FIFOW: 637 case ICH6_HDA_REG_SD5FIFOW: 638 case ICH6_HDA_REG_SD6FIFOW: 639 case ICH6_HDA_REG_SD7FIFOW: 640 switch(HDA_REG_IND(pState, ICH6_HDA_REG_SD0FIFOW + 10*iNum)) 641 { 642 case HDA_SDFIFOW_8B: return 8; 643 case HDA_SDFIFOW_16B: return 16; 644 case HDA_SDFIFOW_32B: return 32; 645 default: 646 AssertMsgFailed(("hda: unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pState, iNum), iNum)); 647 } 648 default: 649 AssertMsgFailed(("hda: Not SDnFIFOW register")); 650 return 0; 651 } 652 } 615 653 616 654 static int hdaProcessInterrupt(INTELHDLinkState* pState) … … 1005 1043 if (offset == 0x100) 1006 1044 { 1007 uint64_t u64BaseDMA = SDBDPL(pState, 4); 1008 u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32); 1045 uint64_t u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4)); 1009 1046 if (u64BaseDMA) 1010 1047 AUD_set_active_out(OSD0FMT_TO_AUDIO_SELECTOR(pState), 1); … … 1056 1093 } 1057 1094 1095 DECLCALLBACK(int)hdaRegWriteSDFIFOW(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value) 1096 { 1097 switch (u32Value) 1098 { 1099 case HDA_SDFIFOW_8B: 1100 case HDA_SDFIFOW_16B: 1101 case HDA_SDFIFOW_32B: 1102 return hdaRegWriteU16(pState, offset, index, u32Value); 1103 default: 1104 Log(("hda: Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value)); 1105 return hdaRegWriteU16(pState, offset, index, HDA_SDFIFOW_32B); 1106 } 1107 return VINF_SUCCESS; 1108 } 1058 1109 /* 1059 1110 * Note this method could be called for changing value on Output Streams only (ICH6 datacheet 18.2.39) … … 1242 1293 len = *(uint32_t *)&bdle[8]; 1243 1294 ioc = *(uint32_t *)&bdle[12]; 1244 Log(("hda: %s bdle[%d] a:%lx, len:% x, ioc:%d\n", (i == pBdle->u32BdleCvi? "[C]": " "), i, addr, len, ioc));1295 Log(("hda: %s bdle[%d] a:%lx, len:%d, ioc:%d\n", (i == pBdle->u32BdleCvi? "[C]": " "), i, addr, len, ioc & 0x1)); 1245 1296 sum += len; 1246 1297 } … … 1264 1315 } 1265 1316 1266 static uint32_t hdaReadAudio(INTELHDLinkState *pState, int avail, bool *fStop) 1267 { 1268 uint8_t tmpbuf[256]; 1269 uint32_t temp; 1270 uint32_t u32Rest = 0; 1271 uint32_t cbRead = 0; 1272 uint32_t to_copy = 0; 1273 /* todo: add input line detection */ 1317 static uint32_t hdaReadAudio(INTELHDLinkState *pState, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit) 1318 { 1274 1319 PHDABDLEDESC pBdle = &pState->stInBdle; 1275 SWVoiceIn *voice = ISD0FMT_TO_AUDIO_SELECTOR(pState); 1276 u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; 1277 temp = audio_MIN(u32Rest, (uint32_t)avail); 1278 if (!temp) 1279 { 1280 *fStop = true; 1281 return cbRead; 1282 } 1283 while (temp) 1284 { 1285 int copied; 1286 to_copy = audio_MIN(temp, SDFIFOS(pState, 4) + 1); 1287 copied = AUD_read (voice, tmpbuf, to_copy); 1288 Log (("hda: read_audio max=%x to_copy=%x copied=%x\n", 1289 avail, to_copy, copied)); 1290 if (!copied) 1291 { 1320 uint32_t cbTransfered = 0; 1321 while( *pu32Avail 1322 && pBdle->u32BdleCviPos < pBdle->u32BdleCviLen) 1323 { 1324 uint32_t cb2Copy = 0; 1325 uint32_t cbBackendCopy = 0; 1326 bool fUnderFifoCleared = false; 1327 if ( !pBdle->u32BdleCviLen 1328 || (*pu32Avail < hdaFifoWToSz(pState, 0))) 1329 { 1330 *fStop = true; 1331 return 0; 1332 } 1333 Log(("hda:ra: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1334 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */ 1335 cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; 1336 cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 0) + 1 - pBdle->cbUnderFifoW); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */ 1337 Assert((*pu32Avail > 0)); 1338 cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* sanity check to avoid overriding sound backend buffer */ 1339 cb2Copy = RT_MIN(cb2Copy, u32CblLimit); 1340 if ( !cb2Copy 1341 || cb2Copy < pBdle->cbUnderFifoW) 1342 { 1343 *fStop = true; 1344 return 0; 1345 } 1346 1347 /* 1348 * read from backend input line 1349 */ 1350 cbBackendCopy = AUD_read (ISD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy); 1351 /* 1352 * write on the HDA DMA 1353 */ 1354 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer, cbBackendCopy); 1355 1356 Assert((cbBackendCopy == cb2Copy && (*pu32Avail) >= cb2Copy)); /* sanity */ 1357 *pu32Avail -= cb2Copy; 1358 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1359 if (pBdle->cbUnderFifoW + cbBackendCopy > hdaFifoWToSz(pState, 0)) 1360 { 1361 Log(("hda:ra: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1362 cbTransfered += cbBackendCopy + pBdle->cbUnderFifoW; 1363 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1364 Assert(!pBdle->cbUnderFifoW); /* we assume, we've read Under FIFO W fully */ 1365 } 1366 else 1367 { 1368 Log(("hda:ra: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1369 pBdle->cbUnderFifoW += RT_MIN(cbBackendCopy, cb2Copy); 1370 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 0))); 1292 1371 *fStop = true; 1293 1372 break; 1294 1373 } 1295 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, copied); 1296 temp -= copied; 1297 cbRead += copied; 1298 pBdle->u32BdleCviPos += copied; 1299 } 1300 return cbRead; 1301 } 1302 static uint32_t hdaWriteAudio(INTELHDLinkState *pState, int avail, bool *fStop) 1303 { 1304 uint8_t tmpbuf[256]; 1305 uint32_t temp; 1306 uint32_t u32Rest; 1307 uint32_t written = 0; 1308 int to_copy = 0; 1374 Log(("hda:ra: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1375 if ( cbTransfered == (SDFIFOS(pState, 0) + 1) 1376 || pBdle->u32BdleCviLen == pBdle->u32BdleCviPos) 1377 break; 1378 } 1379 Assert((cbTransfered <= (SDFIFOS(pState, 0) + 1))); 1380 Log(("hda:ra: cbTransfered: %d\n", cbTransfered)); 1381 return cbTransfered; 1382 } 1383 1384 static uint32_t hdaWriteAudio(INTELHDLinkState *pState, uint32_t *pu32Avail, bool *fStop, uint32_t u32LcblLimit) 1385 { 1309 1386 PHDABDLEDESC pBdle = &pState->stOutBdle; 1310 u 32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;1311 temp = audio_MIN(u32Rest, (uint32_t)avail);1312 if (!temp)1313 {1314 *fStop = true;1315 return written;1316 }1317 while (temp)1318 {1319 int copied;1320 to_copy = audio_MIN(SDFIFOS(pState, 4) + 1, temp);1321 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, to_copy);1322 copied = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), tmpbuf, to_copy);1323 Log(("hda: write_audio max=%x to_copy=%x copied=%x\n",1324 avail, to_copy, copied));1325 if (!copied)1326 {1387 uint32_t cbTransfered = 0; 1388 /* 1389 * We're coping data from DMA using chuks of size FIFOS(pState, 4) + 1 1390 */ 1391 while( *pu32Avail 1392 && pBdle->u32BdleCviPos < pBdle->u32BdleCviLen) 1393 { 1394 uint32_t cb2Copy = 0; /* local byte counter (on local buffer) */ 1395 uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */ 1396 Log(("hda:wa: CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1397 /* border check assert */ 1398 if ( ( !pBdle->u32BdleCviLen 1399 && (pBdle->cbUnderFifoW < hdaFifoWToSz(pState, 4))) 1400 || *pu32Avail < hdaFifoWToSz(pState, 4)) 1401 { 1402 /* buffer length is 0, to little data on marked as "under FIFOW" to send to backed.*/ 1403 Log(("hda:wa: exits CVI(iAvail:%d, cbUnderFifoW:%d, len:%d)\n", *pu32Avail, pBdle->u32BdleCviLen, pBdle->cbUnderFifoW)); 1327 1404 *fStop = true; 1405 return 0; 1406 } 1407 /* 1408 * Amounts of bytes depends on current position in buffer (u32BdleCviLen-u32BdleCviPos) 1409 */ 1410 if (pBdle->u32BdleCviLen) 1411 { 1412 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */ 1413 cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; 1414 cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 4) + 1 - pBdle->cbUnderFifoW); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */ 1415 cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* sanity check to avoid overriding sound backend buffer */ 1416 cb2Copy = RT_MIN(cb2Copy, u32LcblLimit); /* avoid LCBL overrun */ 1417 } 1418 if ( cb2Copy == 0 1419 && pBdle->cbUnderFifoW < hdaFifoWToSz(pState, 4)) 1420 { 1421 Log(("hda:wa: amount of bytes to copy is zero and (cbUnderFifoW:%d < %d)\n", pBdle->cbUnderFifoW, hdaFifoWToSz(pState, 4))); 1422 *fStop = true; 1423 return 0; 1424 } 1425 1426 /* 1427 * Copy from DMA to the corresponding hdaBuffer (if there exists some bytes from the previous not reported transfer we write to ''pBdle->cbUnderFifoW'' offset) 1428 */ 1429 if (cb2Copy) 1430 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 1431 /* 1432 * Write to audio backend. 1433 */ 1434 if (cb2Copy >= hdaFifoWToSz(pState, 4)) 1435 { 1436 cbBackendCopy = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 1437 Assert((cbBackendCopy)); 1438 /* Assertion!!! It was copied less than cbUnderFifoW 1439 * Probably we need to move the buffer, but it rather hard to imagine situation 1440 * why it may happen. 1441 */ 1442 Assert((cbBackendCopy == pBdle->cbUnderFifoW + cb2Copy)); /* we assume that we write whole buffer including not reported bytes */ 1443 if ( pBdle->cbUnderFifoW 1444 && pBdle->cbUnderFifoW <= cbBackendCopy) 1445 Log(("hda:wa: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1446 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1447 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1448 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32Avail >= cbBackendCopy)); /* sanity */ 1449 *pu32Avail -= cbBackendCopy; 1450 cbTransfered += cbBackendCopy; 1451 } 1452 else 1453 { 1454 Log(("hda:wa: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1455 pBdle->cbUnderFifoW += cb2Copy; 1456 pBdle->u32BdleCviPos += cb2Copy; 1457 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 4))); 1328 1458 break; 1329 1459 } 1330 temp -= copied; 1331 written += copied; 1332 pBdle->u32BdleCviPos += copied; 1333 } 1334 return written; 1460 Log(("hda:wa: CVI(pos:%d, len:%d, cbTransfered:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransfered)); 1461 1462 Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1))); 1463 if ( cbTransfered == (SDFIFOS(pState, 4) + 1) 1464 || pBdle->u32BdleCviLen == pBdle->u32BdleCviPos) 1465 break; 1466 } 1467 Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1))); 1468 Log(("hda:wa: cbTransfered: %d\n", cbTransfered)); 1469 return cbTransfered; 1335 1470 } 1336 1471 … … 1354 1489 uint32_t u32Lcbl; 1355 1490 uint32_t u32Fifos; 1491 uint32_t u32Fifow; 1356 1492 switch (src) 1357 1493 { … … 1360 1496 u8Strm = 4; 1361 1497 u32Ctl = SDCTL(pState, 4); 1362 u64BaseDMA = SDBDPL(pState, 4); 1363 u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32); 1498 u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4)); 1364 1499 pu32Lpib = &SDLPIB(pState, 4); 1365 1500 pu32Sts = &SDSTS(pState, 4); … … 1367 1502 pBdle = &pState->stOutBdle; 1368 1503 pBdle->u32BdleMaxCvi = SDLVI(pState, 4); 1504 u32Fifos = SDFIFOS(pState, 4); 1505 u32Fifow = hdaFifoWToSz(pState, 4); 1369 1506 break; 1370 1507 } … … 1376 1513 pu32Sts = &SDSTS(pState, 0); 1377 1514 u32Lcbl = SDLCBL(pState, 0); 1378 u64BaseDMA = SDBDPL(pState, 0); 1379 u64BaseDMA |= (((uint64_t)SDBDPU(pState, 0)) << 32); 1515 u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 0), SDBDPU(pState, 0)); 1380 1516 pBdle = &pState->stInBdle; 1381 1517 pBdle->u32BdleMaxCvi = SDLVI(pState, 0); 1518 u32Fifos = SDFIFOS(pState, 0); 1519 u32Fifow = hdaFifoWToSz(pState, 0); 1382 1520 break; 1383 1521 } … … 1394 1532 while( avail && !fStop) 1395 1533 { 1534 Assert((avail >= 0 && (u32Lcbl >= (*pu32Lpib)))); /* sanity */ 1535 uint32_t u32CblLimit = u32Lcbl - (*pu32Lpib); 1536 Log(("hda: CBL=%d, LPIB=%d\n", u32Lcbl, *pu32Lpib)); 1396 1537 switch (src) 1397 1538 { 1398 1539 case PO_INDEX: 1399 nBytes = hdaWriteAudio(pState, avail, &fStop);1540 nBytes = hdaWriteAudio(pState, (uint32_t *)&avail, &fStop, u32CblLimit); 1400 1541 break; 1401 1542 case PI_INDEX: 1402 nBytes = hdaReadAudio(pState, avail, &fStop);1543 nBytes = hdaReadAudio(pState, (uint32_t *)&avail, &fStop, u32CblLimit); 1403 1544 break; 1404 1545 default: … … 1407 1548 AssertMsgFailed(("Unsupported")); 1408 1549 } 1409 /* Update the buffer position and handle Cyclic Buffer Length (CBL) wraparound. */ 1410 *pu32Lpib += nBytes; 1411 avail -= nBytes; 1412 if (*pu32Lpib >= u32Lcbl) 1413 *pu32Lpib -= u32Lcbl; 1414 1415 /* Optionally write back the current DMA position. */ 1416 if (pState->u64DPBase & DPBASE_ENABLED) 1417 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), 1550 /* 1551 * if we're under FIFO Watermark it's expected that HDA doesn't fetch anything. 1552 * (ICH6 datasheet 18.2.38) 1553 */ 1554 Assert(nBytes <= (u32Fifos + 1)); 1555 if (!pBdle->cbUnderFifoW) 1556 { 1557 *pu32Lpib += nBytes; 1558 /* 1559 * Update the buffer position and handle Cyclic Buffer Length (CBL) wraparound. 1560 */ 1561 Assert((*pu32Lpib <= u32Lcbl)); 1562 1563 /* Optionally write back the current DMA position. */ 1564 if (pState->u64DPBase & DPBASE_ENABLED) 1565 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), 1418 1566 (pState->u64DPBase & DPBASE_ADDR_MASK) + u8Strm*8, pu32Lpib, sizeof(*pu32Lpib)); 1419 1567 1568 } 1420 1569 /* Process end of buffer condition. */ 1421 if (pBdle->u32BdleCviPos == pBdle->u32BdleCviLen) 1570 if ( pBdle->u32BdleCviPos == pBdle->u32BdleCviLen 1571 || *pu32Lpib == u32Lcbl) 1422 1572 { 1423 1573 if (pBdle->fBdleCviIoc) … … 1426 1576 hdaProcessInterrupt(pState); 1427 1577 } 1428 pBdle->u32BdleCviPos = 0; 1429 pBdle->u32BdleCvi++; 1430 if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1) 1578 if (*pu32Lpib == u32Lcbl) 1579 *pu32Lpib -= u32Lcbl; 1580 1581 if (pBdle->u32BdleCviPos == pBdle->u32BdleCviLen) 1431 1582 { 1432 pBdle->u32BdleCvi = 0; 1583 pBdle->u32BdleCviPos = 0; 1584 pBdle->u32BdleCvi++; 1585 if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1) 1586 { 1587 pBdle->u32BdleCvi = 0; 1588 } 1589 fetch_bd(pState, pBdle, u64BaseDMA); 1433 1590 } 1434 fStop = true; /* Give the guest a chance to refill (or empty) buffers. */ 1591 if (nBytes > (u32Fifow)) 1592 fStop = true; 1435 1593 } 1436 1594 } … … 1687 1845 SDFIFOS(&pThis->hda, 2) = HDA_SDINFIFO_120B; 1688 1846 SDFIFOS(&pThis->hda, 3) = HDA_SDINFIFO_120B; 1847 1689 1848 SDFIFOS(&pThis->hda, 4) = HDA_SDONFIFO_192B; 1690 1849 SDFIFOS(&pThis->hda, 5) = HDA_SDONFIFO_192B; 1691 1850 SDFIFOS(&pThis->hda, 6) = HDA_SDONFIFO_192B; 1692 1851 SDFIFOS(&pThis->hda, 7) = HDA_SDONFIFO_192B; 1852 1853 SDFIFOW(&pThis->hda, 0) = HDA_SDFIFOW_8B; 1854 SDFIFOW(&pThis->hda, 4) = HDA_SDFIFOW_32B; 1693 1855 1694 1856 /* emulateion of codec "wake up" HDA spec (5.5.1 and 6.5)*/
Note:
See TracChangeset
for help on using the changeset viewer.