Changeset 82388 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Dec 4, 2019 5:19:25 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r82382 r82388 767 767 Log(("\n")); 768 768 i += 8; 769 } while (i != 0);769 } while (i != 0); 770 770 771 771 do … … 968 968 static VBOXSTRICTRC hdaRegWriteU32(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 969 969 { 970 uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx; 971 972 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 973 970 RT_NOREF(pDevIns); 971 972 uint32_t const iRegMem = g_aHdaRegMap[iReg].mem_idx; 974 973 pThis->au32Regs[iRegMem] = (u32Value & g_aHdaRegMap[iReg].writable) 975 974 | (pThis->au32Regs[iRegMem] & ~g_aHdaRegMap[iReg].writable); 976 DEVHDA_UNLOCK(pDevIns, pThis);977 975 return VINF_SUCCESS; 978 976 } … … 980 978 static VBOXSTRICTRC hdaRegWriteGCTL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 981 979 { 982 RT_NOREF_PV(iReg); 983 #ifdef IN_RING3 984 DEVHDA_LOCK(pDevIns, pThis); 985 #else 986 if (!(u32Value & HDA_GCTL_CRST)) 987 return VINF_IOM_R3_MMIO_WRITE; 988 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 989 #endif 980 RT_NOREF(pDevIns, iReg); 990 981 991 982 if (u32Value & HDA_GCTL_CRST) … … 1008 999 hdaR3GCTLReset(pThis); 1009 1000 #else 1010 AssertFailedReturnStmt(DEVHDA_UNLOCK(pDevIns, pThis), VINF_IOM_R3_MMIO_WRITE);1001 return VINF_IOM_R3_MMIO_WRITE; 1011 1002 #endif 1012 1003 } … … 1019 1010 } 1020 1011 1021 DEVHDA_UNLOCK(pDevIns, pThis);1022 1012 return VINF_SUCCESS; 1023 1013 } … … 1025 1015 static VBOXSTRICTRC hdaRegWriteSTATESTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1026 1016 { 1027 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1017 RT_NOREF(pDevIns); 1028 1018 1029 1019 uint32_t v = HDA_REG_IND(pThis, iReg); … … 1032 1022 HDA_REG(pThis, STATESTS) &= ~(v & nv); /* Write of 1 clears corresponding bit. */ 1033 1023 1034 DEVHDA_UNLOCK(pDevIns, pThis);1035 1024 return VINF_SUCCESS; 1036 1025 } … … 1096 1085 static VBOXSTRICTRC hdaRegReadWALCLK(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1097 1086 { 1098 #ifdef IN_RING3 1099 RT_NOREF(iReg); 1100 1087 #ifdef IN_RING3 /** @todo r=bird: No reason (except logging) for this to be ring-3 only! */ 1088 RT_NOREF(pDevIns, iReg); 1101 1089 DEVHDA_LOCK(pDevIns, pThis); 1102 1090 1103 *pu32Value = RT_LO_U32(ASMAtomicReadU64(&pThis->u64WalClk));1104 1105 Log3Func(("%RU32 (max @ %RU64)\n",*pu32Value, hdaR3WalClkGetMax(pThis))); 1106 1091 const uint64_t u64WalClkCur = ASMAtomicReadU64(&pThis->u64WalClk); 1092 *pu32Value = RT_LO_U32(u64WalClkCur); 1093 1094 Log3Func(("%RU32 (max @ %RU64)\n", *pu32Value, hdaR3WalClkGetMax(pThis))); 1107 1095 DEVHDA_UNLOCK(pDevIns, pThis); 1108 1096 return VINF_SUCCESS; … … 1115 1103 static VBOXSTRICTRC hdaRegWriteCORBRP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1116 1104 { 1117 RT_NOREF(iReg); 1118 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1119 1105 RT_NOREF(pDevIns, iReg); 1120 1106 if (u32Value & HDA_CORBRP_RST) 1121 1107 { … … 1124 1110 { 1125 1111 #ifdef IN_RING3 1126 Assert (pThis->pu32CorbBuf);1127 RT_BZERO( (void *)pThis->pu32CorbBuf, pThis->cbCorbBuf);1112 AssertPtr(pThis->pu32CorbBuf); 1113 RT_BZERO(pThis->pu32CorbBuf, pThis->cbCorbBuf); 1128 1114 #else 1129 DEVHDA_UNLOCK(pDevIns, pThis);1130 1115 return VINF_IOM_R3_MMIO_WRITE; 1131 1116 #endif … … 1139 1124 HDA_REG(pThis, CORBRP) &= ~HDA_CORBRP_RST; /* Only CORBRP_RST bit is writable. */ 1140 1125 1141 DEVHDA_UNLOCK(pDevIns, pThis);1142 1126 return VINF_SUCCESS; 1143 1127 } … … 1146 1130 { 1147 1131 #ifdef IN_RING3 1148 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1149 1150 1132 VBOXSTRICTRC rc = hdaRegWriteU8(pDevIns, pThis, iReg, u32Value); 1151 AssertRC (rc);1133 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 1152 1134 1153 1135 if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Start DMA engine. */ … … 1156 1138 LogFunc(("CORB DMA not running, skipping\n")); 1157 1139 1158 DEVHDA_UNLOCK(pDevIns, pThis);1159 1140 return rc; 1160 1141 #else … … 1167 1148 { 1168 1149 #ifdef IN_RING3 1169 RT_NOREF(iReg); 1170 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1171 1172 if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Ignore request if CORB DMA engine is (still) running. */ 1173 { 1150 RT_NOREF(pDevIns, iReg); 1151 1152 if (!(HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA)) /* Ignore request if CORB DMA engine is (still) running. */ 1153 { 1154 u32Value = (u32Value & HDA_CORBSIZE_SZ); 1155 1156 uint16_t cEntries; 1157 switch (u32Value) 1158 { 1159 case 0: /* 8 byte; 2 entries. */ 1160 cEntries = 2; 1161 break; 1162 case 1: /* 64 byte; 16 entries. */ 1163 cEntries = 16; 1164 break; 1165 case 2: /* 1 KB; 256 entries. */ 1166 cEntries = HDA_CORB_SIZE; /* default. */ 1167 break; 1168 default: 1169 LogRel(("HDA: Guest tried to set an invalid CORB size (0x%x), keeping default\n", u32Value)); 1170 u32Value = 2; 1171 cEntries = HDA_CORB_SIZE; /* Use default size. */ 1172 break; 1173 } 1174 1175 uint32_t cbCorbBuf = cEntries * HDA_CORB_ELEMENT_SIZE; 1176 Assert(cbCorbBuf <= HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Paranoia. */ 1177 1178 if (cbCorbBuf != pThis->cbCorbBuf) 1179 { 1180 RT_BZERO(pThis->pu32CorbBuf, HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Clear CORB when setting a new size. */ 1181 pThis->cbCorbBuf = cbCorbBuf; 1182 } 1183 1184 LogFunc(("CORB buffer size is now %RU32 bytes (%u entries)\n", pThis->cbCorbBuf, pThis->cbCorbBuf / HDA_CORB_ELEMENT_SIZE)); 1185 1186 HDA_REG(pThis, CORBSIZE) = u32Value; 1187 } 1188 else 1174 1189 LogFunc(("CORB DMA is (still) running, skipping\n")); 1175 1176 DEVHDA_UNLOCK(pDevIns, pThis);1177 return VINF_SUCCESS;1178 }1179 1180 u32Value = (u32Value & HDA_CORBSIZE_SZ);1181 1182 uint16_t cEntries = HDA_CORB_SIZE; /* Set default. */1183 1184 switch (u32Value)1185 {1186 case 0: /* 8 byte; 2 entries. */1187 cEntries = 2;1188 break;1189 1190 case 1: /* 64 byte; 16 entries. */1191 cEntries = 16;1192 break;1193 1194 case 2: /* 1 KB; 256 entries. */1195 /* Use default size. */1196 break;1197 1198 default:1199 LogRel(("HDA: Guest tried to set an invalid CORB size (0x%x), keeping default\n", u32Value));1200 u32Value = 2;1201 /* Use default size. */1202 break;1203 }1204 1205 uint32_t cbCorbBuf = cEntries * HDA_CORB_ELEMENT_SIZE;1206 Assert(cbCorbBuf <= HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Paranoia. */1207 1208 if (cbCorbBuf != pThis->cbCorbBuf)1209 {1210 RT_BZERO(pThis->pu32CorbBuf, HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE); /* Clear CORB when setting a new size. */1211 pThis->cbCorbBuf = cbCorbBuf;1212 }1213 1214 LogFunc(("CORB buffer size is now %RU32 bytes (%u entries)\n", pThis->cbCorbBuf, pThis->cbCorbBuf / HDA_CORB_ELEMENT_SIZE));1215 1216 HDA_REG(pThis, CORBSIZE) = u32Value;1217 1218 DEVHDA_UNLOCK(pDevIns, pThis);1219 1190 return VINF_SUCCESS; 1220 1191 #else … … 1226 1197 static VBOXSTRICTRC hdaRegWriteCORBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1227 1198 { 1228 RT_NOREF_PV(iReg); 1229 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1199 RT_NOREF(pDevIns, iReg); 1230 1200 1231 1201 uint32_t v = HDA_REG(pThis, CORBSTS); 1232 1202 HDA_REG(pThis, CORBSTS) &= ~(v & u32Value); 1233 1203 1234 DEVHDA_UNLOCK(pDevIns, pThis);1235 1204 return VINF_SUCCESS; 1236 1205 } … … 1239 1208 { 1240 1209 #ifdef IN_RING3 1241 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1242 1243 1210 VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1244 1211 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 1245 1212 1246 rc = hdaR3CORBCmdProcess(pThis); 1247 1248 DEVHDA_UNLOCK(pDevIns, pThis); 1249 return rc; 1213 return hdaR3CORBCmdProcess(pThis); 1250 1214 #else 1251 1215 RT_NOREF(pDevIns, pThis, iReg, u32Value); … … 1256 1220 static VBOXSTRICTRC hdaRegWriteSDCBL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1257 1221 { 1258 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1259 1260 VBOXSTRICTRC rc = hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 1261 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 1262 1263 DEVHDA_UNLOCK(pDevIns, pThis); 1264 return rc; 1222 return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 1265 1223 } 1266 1224 … … 1300 1258 * clock lock here! 1301 1259 */ 1260 DEVHDA_UNLOCK(pDevIns, pThis); 1302 1261 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE); 1303 1262 … … 1452 1411 } 1453 1412 1454 VBOXSTRICTRC rc2 = hdaRegWriteU24(pDevIns, pThis, iReg, u32Value); 1455 AssertRC(VBOXSTRICTRC_VAL(rc2)); 1456 1457 DEVHDA_UNLOCK_BOTH(pDevIns, pThis, pStream); 1458 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 1413 VBOXSTRICTRC rc = hdaRegWriteU24(pDevIns, pThis, iReg, u32Value); 1414 1415 PDMDevHlpTimerUnlockClock(pDevIns, pStream->hTimer); /* Caller will unlock pThis->CritSect. */ /** @todo r=bird: Move this up. */ 1416 return rc; 1459 1417 #else /* !IN_RING3 */ 1460 1418 RT_NOREF(pDevIns, pThis, iReg, u32Value); … … 1475 1433 * clock lock here! 1476 1434 */ 1435 DEVHDA_UNLOCK(pDevIns, pThis); 1477 1436 DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE); 1478 1437 … … 1568 1527 } 1569 1528 1529 PDMDevHlpTimerUnlockClock(pDevIns, pStream->hTimer); /* Caller will unlock pThis->CritSect. */ 1570 1530 hdaR3StreamUnlock(pStream); 1571 1572 DEVHDA_UNLOCK_BOTH(pDevIns, pThis, pStream);1573 1531 return VINF_SUCCESS; 1574 1532 #else /* !IN_RING3 */ … … 1580 1538 static VBOXSTRICTRC hdaRegWriteSDLVI(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1581 1539 { 1582 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1583 1584 1540 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg); 1585 1541 … … 1587 1543 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) 1588 1544 { 1589 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);1590 1591 1545 /* Try registering the DMA handlers. 1592 1546 * As we can't be sure in which order LVI + BDL base are set, try registering in both routines. */ 1547 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 1593 1548 if ( pStream 1594 1549 && hdaR3StreamRegisterDMAHandlers(pThis, pStream)) 1595 {1596 1550 LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD)); 1597 }1598 1551 } 1599 1552 #endif … … 1601 1554 ASSERT_GUEST_LOGREL_MSG(u32Value <= UINT8_MAX, /* Should be covered by the register write mask, but just to make sure. */ 1602 1555 ("LVI for stream #%RU8 must not be bigger than %RU8\n", uSD, UINT8_MAX - 1)); 1603 1604 VBOXSTRICTRC rc2 = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1605 AssertRC(VBOXSTRICTRC_VAL(rc2)); 1606 1607 DEVHDA_UNLOCK(pDevIns, pThis); 1608 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 1556 return hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1609 1557 } 1610 1558 1611 1559 static VBOXSTRICTRC hdaRegWriteSDFIFOW(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1612 1560 { 1613 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1614 1615 1561 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg); 1616 1562 1617 if (hdaGetDirFromSD(uSD) != PDMAUDIODIR_IN) /* FIFOW for input streams only. */ 1563 if (RT_LIKELY(hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN)) /* FIFOW for input streams only. */ 1564 { /* likely */ } 1565 else 1618 1566 { 1619 1567 #ifndef IN_RING0 1620 1568 LogRel(("HDA: Warning: Guest tried to write read-only FIFOW to output stream #%RU8, ignoring\n", uSD)); 1621 DEVHDA_UNLOCK(pDevIns, pThis);1622 1569 return VINF_SUCCESS; 1623 1570 #else 1624 DEVHDA_UNLOCK(pDevIns, pThis); 1625 return VINF_IOM_R3_MMIO_WRITE; 1571 return VINF_IOM_R3_MMIO_WRITE; /* (Go to ring-3 for release logging.) */ 1626 1572 #endif 1627 1573 } 1628 1574 1629 1575 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg)); 1630 if (!pStream) 1631 { 1632 DEVHDA_UNLOCK(pDevIns, pThis); 1633 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 1634 } 1635 1636 uint32_t u32FIFOW = 0; 1637 1576 if (pStream) 1577 { 1578 uint32_t u32FIFOW = 0; 1579 switch (u32Value) 1580 { 1581 case HDA_SDFIFOW_8B: 1582 case HDA_SDFIFOW_16B: 1583 case HDA_SDFIFOW_32B: 1584 u32FIFOW = u32Value; 1585 break; 1586 default: 1587 ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing unsupported FIFOW (0x%x) to stream #%RU8, defaulting to 32 bytes\n", 1588 u32Value, uSD)); 1589 u32FIFOW = HDA_SDFIFOW_32B; 1590 break; 1591 } 1592 1593 if (u32FIFOW) /** @todo r=bird: Logic error. it will never be zero, so why this check? */ 1594 { 1595 pStream->u16FIFOW = hdaSDFIFOWToBytes(u32FIFOW); 1596 LogFunc(("[SD%RU8] Updating FIFOW to %RU32 bytes\n", uSD, pStream->u16FIFOW)); 1597 return hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOW); 1598 } 1599 } 1600 return VINF_SUCCESS; 1601 } 1602 1603 /** 1604 * @note This method could be called for changing value on Output Streams only (ICH6 datasheet 18.2.39). 1605 */ 1606 static VBOXSTRICTRC hdaRegWriteSDFIFOS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1607 { 1608 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOS, iReg); 1609 1610 ASSERT_GUEST_LOGREL_MSG_RETURN(hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT, /* FIFOS for output streams only. */ 1611 ("Guest tried writing read-only FIFOS to input stream #%RU8, ignoring\n", uSD), 1612 VINF_SUCCESS); 1613 1614 uint32_t u32FIFOS; 1638 1615 switch (u32Value) 1639 {1640 case HDA_SDFIFOW_8B:1641 case HDA_SDFIFOW_16B:1642 case HDA_SDFIFOW_32B:1643 u32FIFOW = u32Value;1644 break;1645 default:1646 ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing unsupported FIFOW (0x%x) to stream #%RU8, defaulting to 32 bytes\n",1647 u32Value, uSD));1648 u32FIFOW = HDA_SDFIFOW_32B;1649 break;1650 }1651 1652 if (u32FIFOW)1653 {1654 pStream->u16FIFOW = hdaSDFIFOWToBytes(u32FIFOW);1655 LogFunc(("[SD%RU8] Updating FIFOW to %RU32 bytes\n", uSD, pStream->u16FIFOW));1656 1657 VBOXSTRICTRC rc2 = hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOW);1658 AssertRC(VBOXSTRICTRC_VAL(rc2));1659 }1660 1661 DEVHDA_UNLOCK(pDevIns, pThis);1662 return VINF_SUCCESS; /* Always return success to the MMIO handler. */1663 }1664 1665 /**1666 * @note This method could be called for changing value on Output Streams only (ICH6 datasheet 18.2.39).1667 */1668 static VBOXSTRICTRC hdaRegWriteSDFIFOS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)1669 {1670 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);1671 1672 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOS, iReg);1673 1674 if (hdaGetDirFromSD(uSD) != PDMAUDIODIR_OUT) /* FIFOS for output streams only. */1675 {1676 ASSERT_GUEST_LOGREL_MSG_FAILED(("Guest tried writing read-only FIFOS to input stream #%RU8, ignoring\n", uSD));1677 DEVHDA_UNLOCK(pDevIns, pThis);1678 return VINF_SUCCESS;1679 }1680 1681 uint32_t u32FIFOS;1682 1683 switch(u32Value)1684 1616 { 1685 1617 case HDA_SDOFIFO_16B: … … 1699 1631 } 1700 1632 1701 VBOXSTRICTRC rc2 = hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOS); 1702 AssertRC(VBOXSTRICTRC_VAL(rc2)); 1703 1704 DEVHDA_UNLOCK(pDevIns, pThis); 1705 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 1633 return hdaRegWriteU16(pDevIns, pThis, iReg, u32FIFOS); 1706 1634 } 1707 1635 … … 1984 1912 return rc; 1985 1913 } 1914 1986 1915 #endif /* IN_RING3 */ 1987 1916 1988 1917 static VBOXSTRICTRC hdaRegWriteSDFMT(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1989 1918 { 1990 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1991 1992 /* Write the wanted stream format into the register in any case. 1919 /* 1920 * Write the wanted stream format into the register in any case. 1993 1921 * 1994 1922 * This is important for e.g. MacOS guests, as those try to initialize streams which are not reported … … 1996 1924 * 1997 1925 * When ignoring those (invalid) formats, this leads to MacOS thinking that the device is malfunctioning 1998 * and therefore disabling the device completely. */1999 VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value);2000 AssertRC(VBOXSTRICTRC_VAL(rc));2001 2002 DEVHDA_UNLOCK(pDevIns, pThis); 2003 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ /** @todo r=bird: This is non-sense in this context, though due to the double locking not really a problem */ 2004 } 2005 2006 /* Note: Will be called for both, BDPL and BDPU, registers. */ 2007 DECLINLINE(int) hdaRegWriteSDBDPX(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t uSD) 2008 { 2009 #ifdef IN_RING3 2010 DEVHDA_LOCK(pDevIns, pThis);2011 2012 # ifdef HDA_USE_DMA_ACCESS_HANDLER1926 * and therefore disabling the device completely. 1927 */ 1928 return hdaRegWriteU16(pDevIns, pThis, iReg, u32Value); 1929 } 1930 1931 /** 1932 * Worker for writes to the BDPL and BDPU registers. 1933 */ 1934 DECLINLINE(VBOXSTRICTRC) hdaRegWriteSDBDPX(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t uSD) 1935 { 1936 #ifndef HDA_USE_DMA_ACCESS_HANDLER 1937 RT_NOREF(uSD); 1938 return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 1939 #else 1940 # ifdef IN_RING3 2013 1941 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) 2014 1942 { 2015 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);2016 2017 1943 /* Try registering the DMA handlers. 2018 1944 * As we can't be sure in which order LVI + BDL base are set, try registering in both routines. */ 1945 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 2019 1946 if ( pStream 2020 1947 && hdaR3StreamRegisterDMAHandlers(pThis, pStream)) 2021 {2022 1948 LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD)); 2023 2024 }1949 } 1950 return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 2025 1951 # else 2026 RT_NOREF(uSD);2027 # endif2028 2029 VBOXSTRICTRC rc2 = hdaRegWriteU32(pDevIns, pThis, iReg, u32Value);2030 AssertRC(VBOXSTRICTRC_VAL(rc2));2031 2032 DEVHDA_UNLOCK(pDevIns, pThis);2033 return VINF_SUCCESS; /* Always return success to the MMIO handler. */2034 #else /* !IN_RING3 */2035 1952 RT_NOREF(pDevIns, pThis, iReg, u32Value, uSD); 2036 1953 return VINF_IOM_R3_MMIO_WRITE; 2037 #endif /* !IN_RING3 */ 1954 # endif 1955 #endif 2038 1956 } 2039 1957 … … 2067 1985 static VBOXSTRICTRC hdaRegWriteIRS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2068 1986 { 2069 RT_NOREF_PV(iReg); 2070 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 1987 RT_NOREF(pDevIns, iReg); 2071 1988 2072 1989 /* … … 2082 1999 if (HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP)) 2083 2000 { 2084 DEVHDA_UNLOCK(pDevIns, pThis);2085 2086 2001 /* 2087 2002 * 3.4.3: Defines behavior of immediate Command status register. … … 2093 2008 HDA_REG(pThis, IRS) = HDA_IRS_ICB; /* busy */ 2094 2009 2095 uint64_t uResp; 2096 int rc2 = pThis->pCodec->pfnLookup(pThis->pCodec, 2097 HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp); 2010 uint64_t uResp = 0; 2011 int rc2 = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp); 2098 2012 if (RT_FAILURE(rc2)) 2099 2013 LogFunc(("Codec lookup failed with rc2=%Rrc\n", rc2)); … … 2104 2018 HDA_REG(pThis, IRS) &= ~HDA_IRS_ICB; /* busy is clear */ 2105 2019 2106 DEVHDA_UNLOCK(pDevIns, pThis);2107 2020 return VINF_SUCCESS; 2108 2021 #else /* !IN_RING3 */ 2109 DEVHDA_UNLOCK(pDevIns, pThis);2110 2022 return VINF_IOM_R3_MMIO_WRITE; 2111 2023 #endif /* !IN_RING3 */ … … 2116 2028 */ 2117 2029 HDA_REG(pThis, IRS) &= ~(u32Value & HDA_IRS_IRV); 2118 2119 DEVHDA_UNLOCK(pDevIns, pThis);2120 2030 return VINF_SUCCESS; 2121 2031 } … … 2123 2033 static VBOXSTRICTRC hdaRegWriteRIRBWP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2124 2034 { 2125 RT_NOREF(iReg); 2126 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 2035 RT_NOREF(pDevIns, iReg); 2127 2036 2128 2037 if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Ignore request if CORB DMA engine is (still) running. */ 2129 {2130 2038 LogFunc(("CORB DMA (still) running, skipping\n")); 2131 2132 DEVHDA_UNLOCK(pDevIns, pThis); 2133 return VINF_SUCCESS; 2134 } 2135 2136 if (u32Value & HDA_RIRBWP_RST) 2137 { 2138 /* Do a RIRB reset. */ 2139 if (pThis->cbRirbBuf) 2140 { 2141 Assert(pThis->pu64RirbBuf); 2142 RT_BZERO((void *)pThis->pu64RirbBuf, pThis->cbRirbBuf); 2143 } 2144 2145 LogRel2(("HDA: RIRB reset\n")); 2146 2147 HDA_REG(pThis, RIRBWP) = 0; 2148 } 2149 2150 /* The remaining bits are O, see 6.2.22. */ 2151 2152 DEVHDA_UNLOCK(pDevIns, pThis); 2039 else 2040 { 2041 if (u32Value & HDA_RIRBWP_RST) 2042 { 2043 /* Do a RIRB reset. */ 2044 if (pThis->cbRirbBuf) 2045 { 2046 Assert(pThis->pu64RirbBuf); 2047 RT_BZERO((void *)pThis->pu64RirbBuf, pThis->cbRirbBuf); 2048 } 2049 2050 LogRel2(("HDA: RIRB reset\n")); 2051 2052 HDA_REG(pThis, RIRBWP) = 0; 2053 } 2054 /* The remaining bits are O, see 6.2.22. */ 2055 } 2153 2056 return VINF_SUCCESS; 2154 2057 } … … 2156 2059 static VBOXSTRICTRC hdaRegWriteRINTCNT(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2157 2060 { 2158 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 2159 2061 RT_NOREF(pDevIns); 2160 2062 if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Ignore request if CORB DMA engine is (still) running. */ 2161 2063 { 2162 2064 LogFunc(("CORB DMA is (still) running, skipping\n")); 2163 2164 DEVHDA_UNLOCK(pDevIns, pThis);2165 2065 return VINF_SUCCESS; 2166 2066 } … … 2170 2070 2171 2071 LogFunc(("Response interrupt count is now %RU8\n", HDA_REG(pThis, RINTCNT) & 0xFF)); 2172 2173 DEVHDA_UNLOCK(pDevIns, pThis);2174 2072 return rc; 2175 2073 } … … 2177 2075 static VBOXSTRICTRC hdaRegWriteBase(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2178 2076 { 2179 uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx; 2180 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 2077 RT_NOREF(pDevIns); 2181 2078 2182 2079 VBOXSTRICTRC rc = hdaRegWriteU32(pDevIns, pThis, iReg, u32Value); 2183 2080 AssertRCSuccess(VBOXSTRICTRC_VAL(rc)); 2184 2081 2082 uint32_t const iRegMem = g_aHdaRegMap[iReg].mem_idx; 2185 2083 switch (iReg) 2186 2084 { … … 2191 2089 case HDA_REG_CORBUBASE: 2192 2090 pThis->u64CORBBase &= UINT64_C(0x00000000FFFFFFFF); 2193 pThis->u64CORBBase |= ( (uint64_t)pThis->au32Regs[iRegMem] << 32);2091 pThis->u64CORBBase |= (uint64_t)pThis->au32Regs[iRegMem] << 32; 2194 2092 break; 2195 2093 case HDA_REG_RIRBLBASE: … … 2199 2097 case HDA_REG_RIRBUBASE: 2200 2098 pThis->u64RIRBBase &= UINT64_C(0x00000000FFFFFFFF); 2201 pThis->u64RIRBBase |= ( (uint64_t)pThis->au32Regs[iRegMem] << 32);2099 pThis->u64RIRBBase |= (uint64_t)pThis->au32Regs[iRegMem] << 32; 2202 2100 break; 2203 2101 case HDA_REG_DPLBASE: 2204 {2205 2102 pThis->u64DPBase = pThis->au32Regs[iRegMem] & DPBASE_ADDR_MASK; 2206 2103 Assert(pThis->u64DPBase % 128 == 0); /* Must be 128-byte aligned. */ … … 2210 2107 LogRel(("HDA: %s DMA position buffer\n", pThis->fDMAPosition ? "Enabled" : "Disabled")); 2211 2108 break; 2212 }2213 2109 case HDA_REG_DPUBASE: 2214 2110 pThis->u64DPBase = RT_MAKE_U64(RT_LO_U32(pThis->u64DPBase) & DPBASE_ADDR_MASK, pThis->au32Regs[iRegMem]); … … 2221 2117 LogFunc(("CORB base:%llx RIRB base: %llx DP base: %llx\n", 2222 2118 pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase)); 2223 2224 DEVHDA_UNLOCK(pDevIns, pThis);2225 2119 return rc; 2226 2120 } … … 2228 2122 static VBOXSTRICTRC hdaRegWriteRIRBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2229 2123 { 2230 RT_NOREF_PV(iReg); 2231 DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE); 2124 RT_NOREF(pDevIns, iReg); 2232 2125 2233 2126 uint8_t v = HDA_REG(pThis, RIRBSTS); 2234 2127 HDA_REG(pThis, RIRBSTS) &= ~(v & u32Value); 2235 2128 2236 VBOXSTRICTRC rc = HDA_PROCESS_INTERRUPT(pDevIns, pThis); 2237 2238 DEVHDA_UNLOCK(pDevIns, pThis); 2239 return rc; 2129 return HDA_PROCESS_INTERRUPT(pDevIns, pThis); 2240 2130 } 2241 2131 … … 3260 3150 } 3261 3151 3262 /* Leave the lock before calling write function. */3263 /** @todo r=bird: Why do we need to do that?? There is no3264 * explanation why this is necessary here...3265 *3266 * More or less all write functions retake the lock, so why not let3267 * those who need to drop the lock or take additional locks release3268 * it? See, releasing a lock you already got always runs the risk3269 * of someone else grabbing it and forcing you to wait, better to3270 * do the two-three things a write handle needs to do than enter3271 * and exit the lock all the time. */3272 DEVHDA_UNLOCK(pDevIns, pThis);3273 3274 3152 #ifdef LOG_ENABLED 3275 3153 uint32_t const idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; … … 3279 3157 Log3Func(("Written value %#x to %s[%d byte]; %x => %x%s, rc=%d\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev, 3280 3158 g_aHdaRegMap[idxRegDsc].size, u32OldValue, pThis->au32Regs[idxRegMem], pszLog, VBOXSTRICTRC_VAL(rc))); 3159 3160 DEVHDA_UNLOCK(pDevIns, pThis); 3281 3161 RT_NOREF(pszLog); 3282 3162 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.