Changeset 34225 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Nov 22, 2010 3:26:53 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 67970
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r34156 r34225 1031 1031 int rc = VINF_SUCCESS; 1032 1032 uint64_t u64BaseDMA = 0; 1033 uint8_t u8Strm = 0; 1034 PHDABDLEDESC pBdle = NULL; 1035 uint32_t *pu32Lpib = 0; 1033 1036 if(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)) 1034 1037 { … … 1040 1043 else if (HDA_IS_STREAM_IN_RESET(pState, offset)) 1041 1044 { 1042 PHDABDLEDESC pBdle = NULL;1043 uint32_t *pu32Lpib = NULL;1044 uint8_t u8Strm = 0;1045 1045 Log(("hda: guest has initiated exit of stream reset\n")); 1046 1046 pState->u8StreamsInReset &= ~HDA_STREAM_BITMASK(offset); 1047 1047 HDA_REG_IND(pState, index) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST); 1048 switch (index)1049 {1050 case ICH6_HDA_REG_SD0CTL:1051 pBdle = &pState->stInBdle;1052 pu32Lpib = &SDLPIB(pState, 0);1053 AUD_set_active_in(ISD0FMT_TO_AUDIO_SELECTOR(pState), 0);1054 u8Strm = 0;1055 break;1056 case ICH6_HDA_REG_SD4CTL:1057 u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4));1058 fOn = fOn && u64BaseDMA;1059 AUD_set_active_out(OSD0FMT_TO_AUDIO_SELECTOR(pState), 0);1060 pBdle = &pState->stOutBdle;1061 pu32Lpib = &SDLPIB(pState, 4);1062 u8Strm = 4;1063 break;1064 default:1065 Log(("Attempt to reset DMA state on unattached SDI(%s), ignored\n", s_ichIntelHDRegMap[index].abbrev));1066 }1067 if ( pBdle1068 && pu32Lpib)1069 {1070 memset(pBdle, 0, sizeof(HDABDLEDESC));1071 *pu32Lpib = 0;1072 hdaUpdatePosBuf(pState, u8Strm, 0);1073 }1074 1048 } 1075 1049 /* … … 1079 1053 { 1080 1054 case ICH6_HDA_REG_SD0CTL: 1081 if (fOn) 1082 AUD_set_active_in(ISD0FMT_TO_AUDIO_SELECTOR(pState), 1); 1055 u8Strm = 0; 1056 pBdle = &pState->stInBdle; 1057 pu32Lpib = &SDLPIB(pState, 0); 1058 AUD_set_active_in(ISD0FMT_TO_AUDIO_SELECTOR(pState), fOn); 1083 1059 Log(("hda: DMA SD0CTL switched %s\n", fOn ? "on" : " off")); 1084 1060 break; 1085 1061 case ICH6_HDA_REG_SD4CTL: 1086 if (fOn) 1087 SDSTS(pState, 4) &= ~(1<<5); 1062 u8Strm = 4; 1063 pBdle = &pState->stOutBdle; 1064 1065 pu32Lpib = &SDLPIB(pState, 4); 1088 1066 u64BaseDMA = RT_MAKE_U64(SDBDPL(pState, 4), SDBDPU(pState, 4)); 1089 1067 fOn = fOn && u64BaseDMA; 1090 1068 if (fOn) 1091 AUD_set_active_out(OSD0FMT_TO_AUDIO_SELECTOR(pState), 1); 1069 SDSTS(pState, 4) &= ~(1<<5); 1070 AUD_set_active_out(OSD0FMT_TO_AUDIO_SELECTOR(pState), fOn); 1092 1071 Log(("hda: DMA SD4CTL switched %s\n", fOn ? "on" : " off")); 1093 1072 break; … … 1095 1074 Log(("Attempt to modify DMA state on unattached SDI(%s), ignored\n", s_ichIntelHDRegMap[index].abbrev)); 1096 1075 break; 1076 } 1077 if ( !fOn 1078 && pBdle 1079 && pu32Lpib) 1080 { 1081 memset(pBdle, 0, sizeof(HDABDLEDESC)); 1082 *pu32Lpib = 0; 1083 hdaUpdatePosBuf(pState, u8Strm, 0); 1097 1084 } 1098 1085 rc = hdaRegWriteU24(pState, offset, index, u32Value); … … 1421 1408 PHDABDLEDESC pBdle = &pState->stOutBdle; 1422 1409 uint32_t cbTransfered = 0; 1410 uint32_t cb2Copy = 0; /* local byte counter (on local buffer) */ 1411 uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */ 1412 1413 Log(("hda:wa: CVI(cvi:%d, pos:%d, len:%d)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1414 1423 1415 /* 1424 * We're coping data from DMA using chuks of size FIFOS(pState, 4) + 11416 * Amounts of bytes depends on current position in buffer (u32BdleCviLen-u32BdleCviPos) 1425 1417 */ 1426 while( *pu32Avail 1427 && pBdle->u32BdleCviPos < pBdle->u32BdleCviLen) 1428 { 1429 uint32_t cb2Copy = 0; /* local byte counter (on local buffer) */ 1430 uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */ 1431 Log(("hda:wa: CVI(cvi:%d, pos:%d, len:%d)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1432 /* border check assert */ 1433 if ( ( !pBdle->u32BdleCviLen 1434 && (pBdle->cbUnderFifoW < hdaFifoWToSz(pState, 4))) 1435 || *pu32Avail < hdaFifoWToSz(pState, 4)) 1436 { 1437 /* buffer length is 0, to little data on marked as "under FIFOW" to send to backed.*/ 1438 Log(("hda:wa: exits CVI(iAvail:%d, cbUnderFifoW:%d, cvi:%d, len:%d)\n", *pu32Avail, pBdle->u32BdleCviLen, pBdle->u32BdleCvi, pBdle->cbUnderFifoW)); 1439 *fStop = true; 1440 return 0; 1441 } 1418 if (pBdle->u32BdleCviLen) 1419 { 1420 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */ 1421 cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; /* align copy buffer to size of trailing space in BDLE buffer */ 1422 cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 4) + 1); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */ 1423 cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* align copying buffer size up to size of back end buffer */ 1424 cb2Copy = RT_MIN(cb2Copy, u32CblLimit); /* avoid LCBL overrun */ 1425 } 1426 if (cb2Copy <= pBdle->cbUnderFifoW) 1427 { 1428 Log(("hda:wa: amount of unreported bytes is less than room may be transfered (cbUnderFifoW:%d < %d)\n", pBdle->cbUnderFifoW, cb2Copy)); 1429 *fStop = true; 1430 goto done; 1431 } 1432 cb2Copy -= pBdle->cbUnderFifoW; /* force reserve "Unreported bits" */ 1433 1434 /* 1435 * Copy from DMA to the corresponding hdaBuffer (if there exists some bytes from the previous not reported transfer we write to ''pBdle->cbUnderFifoW'' offset) 1436 */ 1437 if (cb2Copy) 1438 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 1439 /* 1440 * Write to audio backend. 1441 */ 1442 if (cb2Copy + pBdle->cbUnderFifoW >= hdaFifoWToSz(pState, 4)) 1443 { 1442 1444 /* 1443 * Amounts of bytes depends on current position in buffer (u32BdleCviLen-u32BdleCviPos)1445 * We feed backend with new portion of fetched samples including not reported. 1444 1446 */ 1445 if (pBdle->u32BdleCviLen) 1446 { 1447 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */ 1448 cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; /* align copy buffer to size of trailing space in BDLE buffer */ 1449 cb2Copy = RT_MIN(cb2Copy, SDFIFOS(pState, 4) + 1); /* we may increase the counter in range of [0, FIFOS(pState, 4) + 1] */ 1450 cb2Copy = RT_MIN(cb2Copy, *pu32Avail); /* align copying buffer size up to size of back end buffer */ 1451 cb2Copy = RT_MIN(cb2Copy, u32CblLimit); /* avoid LCBL overrun */ 1452 } 1453 if (cb2Copy < pBdle->cbUnderFifoW) 1454 { 1455 Log(("hda:wa: amount of unreported bytes is less than room may be transfered (cbUnderFifoW:%d < %d)\n", pBdle->cbUnderFifoW, cb2Copy)); 1456 *fStop = true; 1457 break; 1458 } 1459 cb2Copy -= pBdle->cbUnderFifoW; /* force reserve "Unreported bits" */ 1460 1461 /* 1462 * Copy from DMA to the corresponding hdaBuffer (if there exists some bytes from the previous not reported transfer we write to ''pBdle->cbUnderFifoW'' offset) 1447 cbBackendCopy = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 1448 Assert((cbBackendCopy)); 1449 /* Assertion!!! It was copied less than cbUnderFifoW 1450 * Probably we need to move the buffer, but it rather hard to imagine situation 1451 * why it may happen. 1463 1452 */ 1464 if (cb2Copy) 1465 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 1466 /* 1467 * Write to audio backend. 1468 */ 1469 if (cb2Copy + pBdle->cbUnderFifoW >= hdaFifoWToSz(pState, 4)) 1470 { 1471 /* 1472 * We feed backend with new portion of fetched samples including not reported. 1473 */ 1474 cbBackendCopy = AUD_write (OSD0FMT_TO_AUDIO_SELECTOR(pState), pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 1475 Assert((cbBackendCopy)); 1476 /* Assertion!!! It was copied less than cbUnderFifoW 1477 * Probably we need to move the buffer, but it rather hard to imagine situation 1478 * why it may happen. 1479 */ 1480 Assert((cbBackendCopy == pBdle->cbUnderFifoW + cb2Copy)); /* we assume that we write whole buffer including not reported bytes */ 1481 if ( pBdle->cbUnderFifoW 1482 && pBdle->cbUnderFifoW <= cbBackendCopy) 1483 Log(("hda:wa: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1484 1485 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1486 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1487 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32Avail >= cbBackendCopy)); /* sanity */ 1488 Assert((!pBdle->cbUnderFifoW)); /* Assert!!! Assumption failed */ 1489 *pu32Avail -= cbBackendCopy; 1490 cbTransfered += cbBackendCopy; 1491 } 1492 else 1493 { 1494 Log(("hda:wa: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1495 pBdle->cbUnderFifoW += cb2Copy; 1496 pBdle->u32BdleCviPos += cb2Copy; 1497 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 4))); 1498 *fStop = true; 1499 break; 1500 } 1501 Log(("hda:wa: CVI(pos:%d, len:%d, cbTransfered:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransfered)); 1502 1503 Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1))); 1504 if ( cbTransfered == (SDFIFOS(pState, 4) + 1) 1505 || pBdle->u32BdleCviLen == pBdle->u32BdleCviPos) 1506 break; 1507 } 1453 Assert((cbBackendCopy == pBdle->cbUnderFifoW + cb2Copy)); /* we assume that we write whole buffer including not reported bytes */ 1454 if ( pBdle->cbUnderFifoW 1455 && pBdle->cbUnderFifoW <= cbBackendCopy) 1456 Log(("hda:wa: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1457 1458 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbBackendCopy); 1459 pBdle->u32BdleCviPos += RT_MIN(cb2Copy, cbBackendCopy); 1460 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32Avail >= cbBackendCopy)); /* sanity */ 1461 Assert((!pBdle->cbUnderFifoW)); /* Assert!!! Assumption failed */ 1462 *pu32Avail -= cbBackendCopy; 1463 cbTransfered += cbBackendCopy; 1464 } 1465 else 1466 { 1467 Log(("hda:wa: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1468 pBdle->cbUnderFifoW += cb2Copy; 1469 pBdle->u32BdleCviPos += cb2Copy; 1470 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pState, 4))); 1471 goto done; 1472 } 1473 1474 done: 1508 1475 Assert((cbTransfered <= (SDFIFOS(pState, 4) + 1))); 1509 Log(("hda:wa: cbTransfered: %d\n", cbTransfered));1476 Log(("hda:wa: CVI(pos:%d, len:%d, cbTransfered:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransfered)); 1510 1477 return cbTransfered; 1511 1478 } … … 1614 1581 && pBdle->fBdleCviIoc) 1615 1582 { 1583 *pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 1616 1584 *pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 1617 1585 hdaProcessInterrupt(pState); 1618 *pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);1619 1586 } 1620 1587 if (*pu32Lpib == u32Cbl) … … 1629 1596 pBdle->u32BdleCvi = 0; 1630 1597 1631 fetch_bd(pState, pBdle, u64BaseDMA);1632 1598 } 1633 if (nBytes > (u32Fifow)) 1634 fStop = true; 1599 fStop = true; 1635 1600 } 1636 1601 }
Note:
See TracChangeset
for help on using the changeset viewer.