VirtualBox

Changeset 67411 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 14, 2017 3:24:28 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116136
Message:

Audio/DevHDA: Forward ported / integrated stream init / reset handling.

File:
1 edited

Legend:

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

    r67410 r67411  
    974974 * @{
    975975 */
    976 static int       hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    977 static int       hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    978 static int       hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    979 static int       hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    980 static int       hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    981 static int       hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    982 static int       hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    983 static int       hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    984 static int       hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     976static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     977static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     978static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     979static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     980static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     981static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     982static int hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     983static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     984static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     985/** @} */
     986
     987/** @name {IOB}SDn utility functions.
     988 * @{
     989 */
     990#ifdef IN_RING3
     991static int hdaSDFMTToStrmCfg(uint32_t u32SDFMT, PPDMAUDIOSTREAMCFG pStrmCfg);
     992#endif
    985993/** @} */
    986994
     
    18501858}
    18511859
    1852 static int hdaStreamCreate(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD)
     1860static int hdaStreamCreate(PHDASTATE pThis, PHDASTREAM pStream)
    18531861{
    18541862    RT_NOREF(pThis);
    1855     AssertPtrReturn(pStream,             VERR_INVALID_POINTER);
    1856     AssertReturn(uSD <= HDA_MAX_STREAMS, VERR_INVALID_PARAMETER);
    1857 
     1863    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     1864
     1865    pStream->u8SD           = UINT8_MAX;
     1866    pStream->pMixSink       = NULL;
     1867
     1868    pStream->State.fInReset = false;
    18581869#ifdef HDA_USE_DMA_ACCESS_HANDLER
    18591870    RTListInit(&pStream->State.lstDMAHandlers);
    18601871#endif
    18611872
    1862     int rc = RTCritSectInit(&pStream->State.CritSect);
     1873    int rc = RTCircBufCreate(&pStream->State.pCircBuf, _64K); /** @todo Make this configurable. */
    18631874    if (RT_SUCCESS(rc))
    18641875    {
    1865         pStream->u8SD           = uSD;
    1866         pStream->pMixSink       = NULL;
    1867 
    1868         pStream->State.fInReset = false;
    1869     }
    1870 
    1871     if (RT_SUCCESS(rc))
    1872         rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */
    1873 
    1874     LogFlowFunc(("uSD=%RU8\n", uSD));
     1876        rc = hdaStreamPeriodCreate(&pStream->State.Period);
     1877        if (RT_SUCCESS(rc))
     1878            rc = RTCritSectInit(&pStream->State.CritSect);
     1879    }
     1880
     1881#ifdef DEBUG
     1882    int rc2 = RTCritSectInit(&pStream->Dbg.CritSect);
     1883    AssertRC(rc2);
     1884#endif
     1885
    18751886    return rc;
    18761887}
     
    19021913    }
    19031914
     1915    hdaStreamPeriodDestroy(&pStream->State.Period);
     1916
     1917#ifdef DEBUG
     1918    rc2 = RTCritSectDelete(&pStream->Dbg.CritSect);
     1919    AssertRC(rc2);
     1920#endif
     1921
    19041922    LogFlowFuncLeave();
    19051923}
    19061924
    1907 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStream, uint8_t u8SD)
     1925static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD)
    19081926{
    19091927    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    19101928    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    19111929
    1912     pStream->u8SD       = u8SD;
     1930    pStream->u8SD       = uSD;
    19131931    pStream->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStream->u8SD),
    19141932                                      HDA_STREAM_REG(pThis, BDPU, pStream->u8SD));
     
    19201938    pStream->State.uCurBDLE = 0;
    19211939
     1940    if (pStream->State.pCircBuf)
     1941        RTCircBufReset(pStream->State.pCircBuf);
     1942
     1943    /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */
     1944    hdaStreamUpdateLPIB(pThis, pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD));
     1945
     1946    int rc = hdaSDFMTToStrmCfg(HDA_STREAM_REG(pThis, FMT, uSD), &pStream->State.strmCfg);
     1947    if (RT_FAILURE(rc))
     1948        LogRel(("HDA: Warning: Format 0x%x for stream #%RU8 not supported\n", HDA_STREAM_REG(pThis, FMT, uSD), uSD));
     1949
     1950    /* Reset stream map. */
    19221951    hdaStreamMapReset(&pStream->State.Mapping);
    19231952
    1924     LogFlowFunc(("[SD%RU8]: DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n",
    1925                  pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS));
    1926 
    1927 # ifdef DEBUG
    1928     uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStream->u8SD),
    1929                                       HDA_STREAM_REG(pThis, BDPU, pStream->u8SD));
    1930     uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, pStream->u8SD);
    1931     uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, pStream->u8SD);
    1932 
    1933     LogFlowFunc(("\t-> DMA @ 0x%x, LVI=%RU16, CBL=%RU32\n", u64BaseDMA, u16LVI, u32CBL));
    1934 
    1935     hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1);
    1936 # endif
    1937 
    1938     return VINF_SUCCESS;
     1953    /* (Re-)init the stream's period. */
     1954    hdaStreamPeriodInit(&pStream->State.Period, pStream->u8SD, pStream->u16LVI, pStream->u32CBL, &pStream->State.strmCfg);
     1955
     1956    LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16, rc=%Rrc\n",
     1957             pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS, rc));
     1958
     1959    return rc;
    19391960}
    19401961
     
    19441965 * @param   pThis               HDA state.
    19451966 * @param   pStream             HDA stream to reset.
    1946  */
    1947 static void hdaStreamReset(PHDASTATE pThis, PHDASTREAM pStream)
     1967 * @param   uSD                 Stream descriptor (SD) number to use for this stream.
     1968 */
     1969static void hdaStreamReset(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD)
    19481970{
    19491971    AssertPtrReturnVoid(pThis);
    19501972    AssertPtrReturnVoid(pStream);
    1951 
    1952     const uint8_t uSD = pStream->u8SD;
     1973    AssertReturnVoid(uSD <= HDA_MAX_STREAMS);
    19531974
    19541975# ifdef VBOX_STRICT
     
    19601981
    19611982    /*
    1962      * First, reset the internal stream state.
     1983     * Set reset state.
    19631984     */
    1964     RT_ZERO(pStream->State.BDLE);
    1965     pStream->State.uCurBDLE = 0;
    1966 
    1967     if (pStream->State.pCircBuf)
    1968         RTCircBufReset(pStream->State.pCircBuf);
     1985    Assert(ASMAtomicReadBool(&pStream->State.fInReset) == false); /* No nested calls. */
     1986    ASMAtomicXchgBool(&pStream->State.fInReset, true);
    19691987
    19701988    /*
     
    19751993     * bits are reserved for stream number 18.2.33, resets SDnCTL except SRST bit. */
    19761994    HDA_STREAM_REG(pThis, CTL,   uSD) = 0x40000 | (HDA_STREAM_REG(pThis, CTL, uSD) & HDA_SDCTL_SRST);
    1977     /*
    1978      * ICH6 defines default values (120 bytes for input and 192 bytes for output descriptors) of FIFO size. 18.2.39.
    1979      * BUT: Windows guests seem to read the FIFOS but define a DMA region which does not fit to that FIFO size
    1980      *      (e.g. 1792 bytes DMA region vs. 192 bytes FIFOS).
    1981      *      This will lead to crackling and corrupted sound -- so define a 256 bytes FIOS for output streams here per default.
    1982      */
    1983     HDA_STREAM_REG(pThis, FIFOS, uSD) = hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN ? HDA_SDIFIFO_120B : HDA_SDOFIFO_256B;
     1995    /* ICH6 defines default values (120 bytes for input and 192 bytes for output descriptors) of FIFO size. 18.2.39. */
     1996    HDA_STREAM_REG(pThis, FIFOS, uSD) = hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN ? HDA_SDIFIFO_120B : HDA_SDOFIFO_192B;
    19841997    /* See 18.2.38: Always defaults to 0x4 (32 bytes). */
    19851998    HDA_STREAM_REG(pThis, FIFOW, uSD) = HDA_SDFIFOW_32B;
     
    19972010#endif
    19982011
     2012    /* (Re-)initialize the stream with current values. */
    19992013    int rc2 = hdaStreamInit(pThis, pStream, uSD);
    20002014    AssertRC(rc2);
     2015
     2016#ifdef DEBUG
     2017    pStream->Dbg.cReadsTotal      = 0;
     2018    pStream->Dbg.cbReadTotal      = 0;
     2019    pStream->Dbg.tsLastReadNs     = 0;
     2020    pStream->Dbg.cWritesTotal     = 0;
     2021    pStream->Dbg.cbWrittenTotal   = 0;
     2022    pStream->Dbg.cWritesHz        = 0;
     2023    pStream->Dbg.cbWrittenHz      = 0;
     2024    pStream->Dbg.tsWriteSlotBegin = 0;
     2025#endif
     2026
     2027    LogFunc(("[SD%RU8] Reset\n", uSD));
     2028
     2029    /* Exit reset mode. */
     2030    ASMAtomicXchgBool(&pStream->State.fInReset, false);
    20012031}
    20022032
     
    26752705        LogFunc(("[SD%RU8]: Reset enter\n", pStream->u8SD));
    26762706
    2677         /* Enter reset state. */
    2678         Assert(ASMAtomicReadBool(&pStream->State.fInReset) == false); /* No nested calls. */
    2679         ASMAtomicXchgBool(&pStream->State.fInReset, true);
    2680 
    26812707        hdaStreamLock(pStream);
    26822708
    2683         hdaStreamReset(pThis, pStream);
     2709        hdaStreamReset(pThis, pStream, pStream->u8SD);
    26842710
    26852711        hdaStreamUnlock(pStream);
     
    67636789    pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);
    67646790
    6765     for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     6791    for (uint8_t uSD = 0; uSD < HDA_MAX_STREAMS; ++uSD)
    67666792    {
    67676793        /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */
    6768         HDA_STREAM_REG(pThis, CTL, i) &= ~HDA_SDCTL_RUN;
    6769         hdaStreamReset(pThis, &pThis->aStreams[i]);
     6794        HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_SDCTL_RUN;
     6795        hdaStreamReset(pThis, &pThis->aStreams[uSD], uSD);
    67706796    }
    67716797
     
    72577283         * Create all hardware streams.
    72587284         */
    7259         for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     7285        for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i)
    72607286        {
    7261             rc = hdaStreamCreate(pThis, &pThis->aStreams[i], i /* uSD */);
     7287            rc = hdaStreamCreate(pThis, &pThis->aStreams[i]);
    72627288            AssertRC(rc);
    72637289        }
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