VirtualBox

Changeset 69719 in vbox


Ignore:
Timestamp:
Nov 16, 2017 3:11:55 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119100
Message:

Audio/HDA: Forward ported / integrated r119000 + r119062 (Fixed CORB / RIRB buffer handling when issuing multiple commands at once; fixes device detection on some OSes (e.g. Haiku)).

Location:
trunk/src/VBox/Devices
Files:
4 edited

Legend:

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

    r69717 r69719  
    731731        if (RT_FAILURE(rc))
    732732            AssertRCReturn(rc, rc);
    733 # ifdef DEBUG_CMD_BUFFER
     733    }
     734    else
     735    {
     736        Assert((HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RDMAEN));
     737        rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), pThis->u64RIRBBase, pThis->pu64RirbBuf, pThis->cbRirbBuf);
     738        if (RT_FAILURE(rc))
     739            AssertRCReturn(rc, rc);
     740    }
     741
     742#ifdef DEBUG_CMD_BUFFER
     743        LogFunc(("fLocal=%RTbool\n", fLocal));
     744
    734745        uint8_t i = 0;
    735746        do
     
    740751            {
    741752                const char *pszPrefix;
    742                 if ((i + j) == HDA_REG(pThis, CORBRP));
     753                if ((i + j) == HDA_REG(pThis, CORBRP))
    743754                    pszPrefix = "[R]";
    744                 else if ((i + j) == HDA_REG(pThis, CORBWP));
     755                else if ((i + j) == HDA_REG(pThis, CORBWP))
    745756                    pszPrefix = "[W]";
    746757                else
    747758                    pszPrefix = "   "; /* three spaces */
    748                 LogFunc(("%s%08x", pszPrefix, pThis->pu32CorbBuf[i + j]));
     759                Log((" %s%08x", pszPrefix, pThis->pu32CorbBuf[i + j]));
    749760                j++;
    750761            } while (j < 8);
    751             LogFunc(("\n"));
     762            Log(("\n"));
    752763            i += 8;
    753764        } while(i != 0);
    754 # endif
    755     }
    756     else
    757     {
    758         Assert((HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RDMAEN));
    759         rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), pThis->u64RIRBBase, pThis->pu64RirbBuf, pThis->cbRirbBuf);
    760         if (RT_FAILURE(rc))
    761             AssertRCReturn(rc, rc);
    762 # ifdef DEBUG_CMD_BUFFER
    763         uint8_t i = 0;
     765
    764766        do {
    765767            LogFunc(("RIRB%02x: ", i));
     
    771773                else
    772774                    prefix = "   ";
    773                 LogFunc((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j]));
     775                Log((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j]));
    774776            } while (++j < 8);
    775             LogFunc(("\n"));
     777            Log(("\n"));
    776778            i += 8;
    777779        } while (i != 0);
    778 # endif
    779     }
     780#endif
    780781    return rc;
    781782}
     
    790791static int hdaCORBCmdProcess(PHDASTATE pThis)
    791792{
    792     int rc = hdaCmdSync(pThis, true);
    793     if (RT_FAILURE(rc))
    794         AssertRCReturn(rc, rc);
     793    int rc = hdaCmdSync(pThis, true /* Sync from guest */);
     794    AssertRCReturn(rc, rc);
    795795
    796796    uint8_t corbRp = HDA_REG(pThis, CORBRP);
     
    798798    uint8_t rirbWp = HDA_REG(pThis, RIRBWP);
    799799
    800     Assert((corbWp != corbRp));
    801     Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
     800    Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", corbRp, corbWp, rirbWp));
    802801
    803802    while (corbRp != corbWp)
    804803    {
    805         uint64_t uResp;
    806         uint32_t uCmd = pThis->pu32CorbBuf[++corbRp];
    807 
    808         int rc2 = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
    809         if (RT_FAILURE(rc2))
    810             LogFunc(("Codec lookup failed with rc=%Rrc\n", rc2));
    811 
    812         (rirbWp)++;
     804        corbRp = (corbRp + 1) % HDA_CORB_SIZE; /* Advance +1 as the first command(s) are at CORBWP + 1. */
     805
     806        uint64_t uResp = 0;
     807        uint32_t uCmd = pThis->pu32CorbBuf[corbRp];
     808
     809        rc = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
     810        if (RT_FAILURE(rc))
     811            LogFunc(("Codec lookup failed with rc=%Rrc\n", rc));
     812
     813        LogFunc(("verb:%08x -> %016lx\n", uCmd, uResp));
    813814
    814815        if (   (uResp & CODEC_RESPONSE_UNSOLICITED)
    815816            && !(HDA_REG(pThis, GCTL) & HDA_GCTL_UNSOL))
    816817        {
    817             LogFunc(("Unexpected unsolicited response\n"));
     818            LogFunc(("Unexpected unsolicited response.\n"));
    818819            HDA_REG(pThis, CORBRP) = corbRp;
     820
     821            /** @todo r=andy No CORB/RIRB syncing to guest required in that case? */
    819822            return rc;
    820823        }
    821824
     825        rirbWp = (rirbWp + 1) % HDA_RIRB_SIZE;
     826
    822827        pThis->pu64RirbBuf[rirbWp] = uResp;
    823828
    824         pThis->u8RespIntCnt++;
    825         if (pThis->u8RespIntCnt == RINTCNT_N(pThis))
     829        pThis->u16RespIntCnt++;
     830        if (pThis->u16RespIntCnt > HDA_MAX_RINTCNT) /* Make sure that the guest can't hang the host. */
     831        {
     832            LogRel(("HDA: Maximum response interrupt count (%d) reached, bailing out\n", HDA_MAX_RINTCNT));
     833            pThis->u16RespIntCnt = HDA_MAX_RINTCNT;
    826834            break;
     835        }
    827836    }
    828837
     
    830839    HDA_REG(pThis, RIRBWP) = rirbWp;
    831840
    832     rc = hdaCmdSync(pThis, false);
    833 
    834     Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n",
    835               HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
    836 
    837     if (HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RINTCTL) /* Response Interrupt Control (RINTCTL) enabled? */
    838     {
    839         if (pThis->u8RespIntCnt)
    840         {
    841             pThis->u8RespIntCnt = 0;
    842 
     841    rc = hdaCmdSync(pThis, false /* Sync to guest */);
     842    AssertRCReturn(rc, rc);
     843
     844    Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x, uRespIntCnt=%RU16\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt));
     845
     846    if (pThis->u16RespIntCnt)
     847    {
     848        if (HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RINTCTL) /* Response Interrupt Control (RINTCTL) enabled? */
     849        {
    843850            HDA_REG(pThis, RIRBSTS) |= HDA_RIRBSTS_RINTFL;
     851            HDA_REG(pThis, RINTCNT)  = RT_LO_U8(pThis->u16RespIntCnt);
    844852
    845853#ifndef DEBUG
     
    848856            rc = hdaProcessInterrupt(pThis, __FUNCTION__);
    849857#endif
    850         }
     858            pThis->u16RespIntCnt--;
     859        }
     860        else /* Not enabled -- just reset our internal counter. */
     861            pThis->u16RespIntCnt = 0;
    851862    }
    852863
     
    28302841    HDA_REG(pThis, CORBSIZE) = 0x42;                     /* see 6.2.1 */
    28312842    HDA_REG(pThis, RIRBSIZE) = 0x42;                     /* see 6.2.1 */
     2843    HDA_REG(pThis, CORBRP)   = 0x0;
     2844    HDA_REG(pThis, RIRBWP)   = 0x0;
     2845    HDA_REG(pThis, RINTCNT)  = 0x0;
    28322846
    28332847    /*
     
    28882902    else
    28892903        pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
     2904
     2905    /* Clear our internal response interrupt counter. */
     2906    pThis->u16RespIntCnt = 0;
    28902907
    28912908    for (uint8_t uSD = 0; uSD < HDA_MAX_STREAMS; ++uSD)
  • trunk/src/VBox/Devices/Audio/DevHDA.h

    r69119 r69719  
    204204#endif
    205205    /** Response Interrupt Count (RINTCNT). */
    206     uint8_t                            u8RespIntCnt;
     206    uint16_t                           u16RespIntCnt;
    207207    /** Current IRQ level. */
    208208    uint8_t                            u8IRQL;
    209209    /** Padding for alignment. */
    210     uint8_t                            au8Padding3[6];
     210    uint8_t                            au8Padding3[5];
    211211#ifdef DEBUG
    212212    HDASTATEDBGINFO                    Dbg;
  • trunk/src/VBox/Devices/Audio/DevHDACommon.h

    r69717 r69719  
    249249#define HDA_REG_RINTCNT             25          /* 0x5A */
    250250#define HDA_RMX_RINTCNT             23
    251 #define RINTCNT_N(pThis)            (HDA_REG(pThis, RINTCNT) & 0xff)
     251
     252/** Maximum number of Response Interrupts. */
     253#define HDA_MAX_RINTCNT             256
    252254
    253255#define HDA_REG_RIRBCTL             26          /* 0x5C */
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r69500 r69719  
    18991899#endif
    19001900    GEN_CHECK_OFF(HDASTATE, u64WalClk);
    1901     GEN_CHECK_OFF(HDASTATE, u8RespIntCnt);
     1901    GEN_CHECK_OFF(HDASTATE, u16RespIntCnt);
    19021902    GEN_CHECK_OFF(HDASTATE, u8IRQL);
    19031903
Note: See TracChangeset for help on using the changeset viewer.

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