VirtualBox

Changeset 82388 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Dec 4, 2019 5:19:25 PM (5 years ago)
Author:
vboxsync
Message:

DevHDA: Changed hdaWriteReg() to just keep the lock while calling the pfnWrite workers, all except for hdaRegWriteUnimpl will retake it. The hdaRegWriteSDCTL and hdaRegWriteSDSTS functions can drop it before they do DEVHDA_LOCK_BOTH_RETURN to grap both the virtual-sync clock lock and the HDA critsect (make no difference, just reduces the possiblibility for contention slightly). See r117932 for when this unnecessary relocking was introduced. bugref:9218

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevHDA.cpp

    r82382 r82388  
    767767            Log(("\n"));
    768768            i += 8;
    769         } while(i != 0);
     769        } while (i != 0);
    770770
    771771        do
     
    968968static VBOXSTRICTRC hdaRegWriteU32(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    969969{
    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;
    974973    pThis->au32Regs[iRegMem]  = (u32Value & g_aHdaRegMap[iReg].writable)
    975974                              | (pThis->au32Regs[iRegMem] & ~g_aHdaRegMap[iReg].writable);
    976     DEVHDA_UNLOCK(pDevIns, pThis);
    977975    return VINF_SUCCESS;
    978976}
     
    980978static VBOXSTRICTRC hdaRegWriteGCTL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    981979{
    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);
    990981
    991982    if (u32Value & HDA_GCTL_CRST)
     
    1008999        hdaR3GCTLReset(pThis);
    10091000#else
    1010         AssertFailedReturnStmt(DEVHDA_UNLOCK(pDevIns, pThis), VINF_IOM_R3_MMIO_WRITE);
     1001        return VINF_IOM_R3_MMIO_WRITE;
    10111002#endif
    10121003    }
     
    10191010    }
    10201011
    1021     DEVHDA_UNLOCK(pDevIns, pThis);
    10221012    return VINF_SUCCESS;
    10231013}
     
    10251015static VBOXSTRICTRC hdaRegWriteSTATESTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    10261016{
    1027     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     1017    RT_NOREF(pDevIns);
    10281018
    10291019    uint32_t v  = HDA_REG_IND(pThis, iReg);
     
    10321022    HDA_REG(pThis, STATESTS) &= ~(v & nv); /* Write of 1 clears corresponding bit. */
    10331023
    1034     DEVHDA_UNLOCK(pDevIns, pThis);
    10351024    return VINF_SUCCESS;
    10361025}
     
    10961085static VBOXSTRICTRC hdaRegReadWALCLK(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
    10971086{
    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);
    11011089    DEVHDA_LOCK(pDevIns, pThis);
    11021090
    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)));
    11071095    DEVHDA_UNLOCK(pDevIns, pThis);
    11081096    return VINF_SUCCESS;
     
    11151103static VBOXSTRICTRC hdaRegWriteCORBRP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    11161104{
    1117     RT_NOREF(iReg);
    1118     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    1119 
     1105    RT_NOREF(pDevIns, iReg);
    11201106    if (u32Value & HDA_CORBRP_RST)
    11211107    {
     
    11241110        {
    11251111#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);
    11281114#else
    1129             DEVHDA_UNLOCK(pDevIns, pThis);
    11301115            return VINF_IOM_R3_MMIO_WRITE;
    11311116#endif
     
    11391124        HDA_REG(pThis, CORBRP) &= ~HDA_CORBRP_RST;  /* Only CORBRP_RST bit is writable. */
    11401125
    1141     DEVHDA_UNLOCK(pDevIns, pThis);
    11421126    return VINF_SUCCESS;
    11431127}
     
    11461130{
    11471131#ifdef IN_RING3
    1148     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    1149 
    11501132    VBOXSTRICTRC rc = hdaRegWriteU8(pDevIns, pThis, iReg, u32Value);
    1151     AssertRC(rc);
     1133    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    11521134
    11531135    if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Start DMA engine. */
     
    11561138        LogFunc(("CORB DMA not running, skipping\n"));
    11571139
    1158     DEVHDA_UNLOCK(pDevIns, pThis);
    11591140    return rc;
    11601141#else
     
    11671148{
    11681149#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
    11741189        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);
    12191190    return VINF_SUCCESS;
    12201191#else
     
    12261197static VBOXSTRICTRC hdaRegWriteCORBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    12271198{
    1228     RT_NOREF_PV(iReg);
    1229     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     1199    RT_NOREF(pDevIns, iReg);
    12301200
    12311201    uint32_t v = HDA_REG(pThis, CORBSTS);
    12321202    HDA_REG(pThis, CORBSTS) &= ~(v & u32Value);
    12331203
    1234     DEVHDA_UNLOCK(pDevIns, pThis);
    12351204    return VINF_SUCCESS;
    12361205}
     
    12391208{
    12401209#ifdef IN_RING3
    1241     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    1242 
    12431210    VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value);
    12441211    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    12451212
    1246     rc = hdaR3CORBCmdProcess(pThis);
    1247 
    1248     DEVHDA_UNLOCK(pDevIns, pThis);
    1249     return rc;
     1213    return hdaR3CORBCmdProcess(pThis);
    12501214#else
    12511215    RT_NOREF(pDevIns, pThis, iReg, u32Value);
     
    12561220static VBOXSTRICTRC hdaRegWriteSDCBL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    12571221{
    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);
    12651223}
    12661224
     
    13001258     *               clock lock here!
    13011259     */
     1260    DEVHDA_UNLOCK(pDevIns, pThis);
    13021261    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
    13031262
     
    14521411    }
    14531412
    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;
    14591417#else  /* !IN_RING3 */
    14601418    RT_NOREF(pDevIns, pThis, iReg, u32Value);
     
    14751433     *               clock lock here!
    14761434     */
     1435    DEVHDA_UNLOCK(pDevIns, pThis);
    14771436    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
    14781437
     
    15681527    }
    15691528
     1529    PDMDevHlpTimerUnlockClock(pDevIns, pStream->hTimer); /* Caller will unlock pThis->CritSect. */
    15701530    hdaR3StreamUnlock(pStream);
    1571 
    1572     DEVHDA_UNLOCK_BOTH(pDevIns, pThis, pStream);
    15731531    return VINF_SUCCESS;
    15741532#else  /* !IN_RING3 */
     
    15801538static VBOXSTRICTRC hdaRegWriteSDLVI(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    15811539{
    1582     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    1583 
    15841540    const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);
    15851541
     
    15871543    if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
    15881544    {
    1589         PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);
    1590 
    15911545        /* Try registering the DMA handlers.
    15921546         * 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);
    15931548        if (   pStream
    15941549            && hdaR3StreamRegisterDMAHandlers(pThis, pStream))
    1595         {
    15961550            LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD));
    1597         }
    15981551    }
    15991552#endif
     
    16011554    ASSERT_GUEST_LOGREL_MSG(u32Value <= UINT8_MAX, /* Should be covered by the register write mask, but just to make sure. */
    16021555                            ("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);
    16091557}
    16101558
    16111559static VBOXSTRICTRC hdaRegWriteSDFIFOW(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    16121560{
    1613     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    1614 
    16151561    uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg);
    16161562
    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
    16181566    {
    16191567#ifndef IN_RING0
    16201568        LogRel(("HDA: Warning: Guest tried to write read-only FIFOW to output stream #%RU8, ignoring\n", uSD));
    1621         DEVHDA_UNLOCK(pDevIns, pThis);
    16221569        return VINF_SUCCESS;
    16231570#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.) */
    16261572#endif
    16271573    }
    16281574
    16291575    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 */
     1606static 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;
    16381615    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)
    16841616    {
    16851617        case HDA_SDOFIFO_16B:
     
    16991631    }
    17001632
    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);
    17061634}
    17071635
     
    19841912    return rc;
    19851913}
     1914
    19861915#endif /* IN_RING3 */
    19871916
    19881917static VBOXSTRICTRC hdaRegWriteSDFMT(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    19891918{
    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.
    19931921     *
    19941922     * This is important for e.g. MacOS guests, as those try to initialize streams which are not reported
     
    19961924     *
    19971925     * 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_HANDLER
     1926     * 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 */
     1934DECLINLINE(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
    20131941    if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
    20141942    {
    2015         PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);
    2016 
    20171943        /* Try registering the DMA handlers.
    20181944         * 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);
    20191946        if (   pStream
    20201947            && hdaR3StreamRegisterDMAHandlers(pThis, pStream))
    2021         {
    20221948            LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD));
    2023         }
    2024     }
     1949    }
     1950    return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value);
    20251951# else
    2026     RT_NOREF(uSD);
    2027 # endif
    2028 
    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 */
    20351952    RT_NOREF(pDevIns, pThis, iReg, u32Value, uSD);
    20361953    return VINF_IOM_R3_MMIO_WRITE;
    2037 #endif /* !IN_RING3 */
     1954# endif
     1955#endif
    20381956}
    20391957
     
    20671985static VBOXSTRICTRC hdaRegWriteIRS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    20681986{
    2069     RT_NOREF_PV(iReg);
    2070     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     1987    RT_NOREF(pDevIns, iReg);
    20711988
    20721989    /*
     
    20821999        if (HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP))
    20832000        {
    2084             DEVHDA_UNLOCK(pDevIns, pThis);
    2085 
    20862001            /*
    20872002             * 3.4.3: Defines behavior of immediate Command status register.
     
    20932008        HDA_REG(pThis, IRS) = HDA_IRS_ICB;  /* busy */
    20942009
    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);
    20982012        if (RT_FAILURE(rc2))
    20992013            LogFunc(("Codec lookup failed with rc2=%Rrc\n", rc2));
     
    21042018        HDA_REG(pThis, IRS) &= ~HDA_IRS_ICB;    /* busy is clear */
    21052019
    2106         DEVHDA_UNLOCK(pDevIns, pThis);
    21072020        return VINF_SUCCESS;
    21082021#else  /* !IN_RING3 */
    2109         DEVHDA_UNLOCK(pDevIns, pThis);
    21102022        return VINF_IOM_R3_MMIO_WRITE;
    21112023#endif /* !IN_RING3 */
     
    21162028     */
    21172029    HDA_REG(pThis, IRS) &= ~(u32Value & HDA_IRS_IRV);
    2118 
    2119     DEVHDA_UNLOCK(pDevIns, pThis);
    21202030    return VINF_SUCCESS;
    21212031}
     
    21232033static VBOXSTRICTRC hdaRegWriteRIRBWP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    21242034{
    2125     RT_NOREF(iReg);
    2126     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     2035    RT_NOREF(pDevIns, iReg);
    21272036
    21282037    if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Ignore request if CORB DMA engine is (still) running. */
    2129     {
    21302038        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    }
    21532056    return VINF_SUCCESS;
    21542057}
     
    21562059static VBOXSTRICTRC hdaRegWriteRINTCNT(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    21572060{
    2158     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    2159 
     2061    RT_NOREF(pDevIns);
    21602062    if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Ignore request if CORB DMA engine is (still) running. */
    21612063    {
    21622064        LogFunc(("CORB DMA is (still) running, skipping\n"));
    2163 
    2164         DEVHDA_UNLOCK(pDevIns, pThis);
    21652065        return VINF_SUCCESS;
    21662066    }
     
    21702070
    21712071    LogFunc(("Response interrupt count is now %RU8\n", HDA_REG(pThis, RINTCNT) & 0xFF));
    2172 
    2173     DEVHDA_UNLOCK(pDevIns, pThis);
    21742072    return rc;
    21752073}
     
    21772075static VBOXSTRICTRC hdaRegWriteBase(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    21782076{
    2179     uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx;
    2180     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     2077    RT_NOREF(pDevIns);
    21812078
    21822079    VBOXSTRICTRC rc = hdaRegWriteU32(pDevIns, pThis, iReg, u32Value);
    21832080    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    21842081
     2082    uint32_t const iRegMem = g_aHdaRegMap[iReg].mem_idx;
    21852083    switch (iReg)
    21862084    {
     
    21912089        case HDA_REG_CORBUBASE:
    21922090            pThis->u64CORBBase &= UINT64_C(0x00000000FFFFFFFF);
    2193             pThis->u64CORBBase |= ((uint64_t)pThis->au32Regs[iRegMem] << 32);
     2091            pThis->u64CORBBase |= (uint64_t)pThis->au32Regs[iRegMem] << 32;
    21942092            break;
    21952093        case HDA_REG_RIRBLBASE:
     
    21992097        case HDA_REG_RIRBUBASE:
    22002098            pThis->u64RIRBBase &= UINT64_C(0x00000000FFFFFFFF);
    2201             pThis->u64RIRBBase |= ((uint64_t)pThis->au32Regs[iRegMem] << 32);
     2099            pThis->u64RIRBBase |= (uint64_t)pThis->au32Regs[iRegMem] << 32;
    22022100            break;
    22032101        case HDA_REG_DPLBASE:
    2204         {
    22052102            pThis->u64DPBase = pThis->au32Regs[iRegMem] & DPBASE_ADDR_MASK;
    22062103            Assert(pThis->u64DPBase % 128 == 0); /* Must be 128-byte aligned. */
     
    22102107            LogRel(("HDA: %s DMA position buffer\n", pThis->fDMAPosition ? "Enabled" : "Disabled"));
    22112108            break;
    2212         }
    22132109        case HDA_REG_DPUBASE:
    22142110            pThis->u64DPBase = RT_MAKE_U64(RT_LO_U32(pThis->u64DPBase) & DPBASE_ADDR_MASK, pThis->au32Regs[iRegMem]);
     
    22212117    LogFunc(("CORB base:%llx RIRB base: %llx DP base: %llx\n",
    22222118             pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase));
    2223 
    2224     DEVHDA_UNLOCK(pDevIns, pThis);
    22252119    return rc;
    22262120}
     
    22282122static VBOXSTRICTRC hdaRegWriteRIRBSTS(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    22292123{
    2230     RT_NOREF_PV(iReg);
    2231     DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
     2124    RT_NOREF(pDevIns, iReg);
    22322125
    22332126    uint8_t v = HDA_REG(pThis, RIRBSTS);
    22342127    HDA_REG(pThis, RIRBSTS) &= ~(v & u32Value);
    22352128
    2236     VBOXSTRICTRC rc = HDA_PROCESS_INTERRUPT(pDevIns, pThis);
    2237 
    2238     DEVHDA_UNLOCK(pDevIns, pThis);
    2239     return rc;
     2129    return HDA_PROCESS_INTERRUPT(pDevIns, pThis);
    22402130}
    22412131
     
    32603150    }
    32613151
    3262     /* Leave the lock before calling write function. */
    3263     /** @todo r=bird: Why do we need to do that??  There is no
    3264      *        explanation why this is necessary here...
    3265      *
    3266      * More or less all write functions retake the lock, so why not let
    3267      * those who need to drop the lock or take additional locks release
    3268      * it? See, releasing a lock you already got always runs the risk
    3269      * of someone else grabbing it and forcing you to wait, better to
    3270      * do the two-three things a write handle needs to do than enter
    3271      * and exit the lock all the time. */
    3272     DEVHDA_UNLOCK(pDevIns, pThis);
    3273 
    32743152#ifdef LOG_ENABLED
    32753153    uint32_t const idxRegMem   = g_aHdaRegMap[idxRegDsc].mem_idx;
     
    32793157    Log3Func(("Written value %#x to %s[%d byte]; %x => %x%s, rc=%d\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,
    32803158              g_aHdaRegMap[idxRegDsc].size, u32OldValue, pThis->au32Regs[idxRegMem], pszLog, VBOXSTRICTRC_VAL(rc)));
     3159
     3160    DEVHDA_UNLOCK(pDevIns, pThis);
    32813161    RT_NOREF(pszLog);
    32823162    return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette