VirtualBox

Changeset 59439 in vbox


Ignore:
Timestamp:
Jan 22, 2016 2:57:11 PM (9 years ago)
Author:
vboxsync
Message:

Audio/HDA: Fixes for OS X guests.

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

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

    r59376 r59439  
    603603    uint8_t        Padding0[7];
    604604    /** DMA base address (SDnBDPU - SDnBDPL). */
    605     uint64_t       u64BaseDMA;
     605    uint64_t       u64BDLBase;
    606606    /** Cyclic Buffer Length (SDnCBL).
    607607     *  Represents the size of the ring buffer. */
     
    836836
    837837#ifdef IN_RING3
    838 static int hdaBDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry);
    839 static void hdaStreamUpdateLPIB(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t u32LPIB);
     838static int              hdaBDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry);
     839static DECLINLINE(void) hdaStreamUpdateBDLBase(PHDASTATE pThis, PHDASTREAM pStrmSt, uint64_t u64BDLBase);
     840static DECLINLINE(void) hdaStreamUpdateLPIB(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t u32LPIB);
    840841# ifdef LOG_ENABLED
    841 static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t cBDLE);
     842static void             hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t cBDLE);
    842843# endif
    843844#endif
     
    871872    { offset + 0x4,  0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB, hdaRegWriteU32   , HDA_REG_IDX_STRM(name, LPIB) , #name " Link Position In Buffer" }, \
    872873    /* Offset 0x88 (SD0) */ \
    873     { offset + 0x8,  0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32, hdaRegWriteU32    , HDA_REG_IDX_STRM(name, CBL)  , #name " Cyclic Buffer Length" }, \
     874    { offset + 0x8,  0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32, hdaRegWriteSDCBL  , HDA_REG_IDX_STRM(name, CBL)  , #name " Cyclic Buffer Length" }, \
    874875    /* Offset 0x8C (SD0) */ \
    875876    { offset + 0xC,  0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16, hdaRegWriteSDLVI  , HDA_REG_IDX_STRM(name, LVI)  , #name " Last Valid Index" }, \
     
    879880    { offset + 0x10, 0x00002, 0x000000FF, 0x00000000, hdaRegReadU16, hdaRegWriteSDFIFOS, HDA_REG_IDX_STRM(name, FIFOS), #name " FIFO Size" }, \
    880881    /* Offset 0x92 (SD0) */ \
    881     { offset + 0x12, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16, hdaRegWriteSDFMT  , HDA_REG_IDX_STRM(name, FMT)  , #name " Format" }, \
     882    { offset + 0x12, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16, hdaRegWriteSDFMT  , HDA_REG_IDX_STRM(name, FMT)  , #name " Stream Format" }, \
    882883    /* Reserved: 0x94 - 0x98. */ \
    883884    /* Offset 0x98 (SD0) */ \
     
    10321033    Assert(u32LPIB <= pStrmSt->u32CBL);
    10331034
    1034     LogFlowFunc(("uStrm=%RU8, LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n",
     1035    LogFlowFunc(("[SD%RU8]: LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n",
    10351036                 pStrmSt->u8Strm, u32LPIB, pThis->fDMAPosition));
    10361037
     
    10461047        AssertRC(rc2);
    10471048#ifdef DEBUG
    1048         hdaBDLEDumpAll(pThis, pStrmSt->u64BaseDMA, pStrmSt->State.uCurBDLE);
     1049        hdaBDLEDumpAll(pThis, pStrmSt->u64BDLBase, pStrmSt->State.uCurBDLE);
    10491050#endif
    10501051    }
     
    11381139    Assert(pStrmSt->State.uCurBDLE < pStrmSt->u16LVI + 1);
    11391140
    1140     int rc = hdaBDLEFetch(pThis, &pStrmSt->State.BDLE, pStrmSt->u64BaseDMA, pStrmSt->State.uCurBDLE);
     1141    int rc = hdaBDLEFetch(pThis, &pStrmSt->State.BDLE, pStrmSt->u64BDLBase, pStrmSt->State.uCurBDLE);
    11411142
    11421143#ifdef DEBUG
     
    11471148}
    11481149#endif
     1150
     1151DECLINLINE(PHDASTREAM) hdaStreamFromID(PHDASTATE pThis, uint8_t uStreamID)
     1152{
     1153    PHDASTREAM pStrmSt;
     1154
     1155    switch (uStreamID)
     1156    {
     1157        case 0: /** @todo Use dynamic indices, based on stream assignment. */
     1158        {
     1159            pStrmSt = &pThis->StrmStLineIn;
     1160            break;
     1161        }
     1162# ifdef VBOX_WITH_HDA_MIC_IN
     1163        case 2: /** @todo Use dynamic indices, based on stream assignment. */
     1164        {
     1165            pStrmSt = &pThis->StrmStMicIn;
     1166            break;
     1167        }
     1168# endif
     1169        case 4: /** @todo Use dynamic indices, based on stream assignment. */
     1170        {
     1171            pStrmSt = &pThis->StrmStOut;
     1172            break;
     1173        }
     1174
     1175        default:
     1176        {
     1177            pStrmSt = NULL;
     1178            LogFunc(("Warning: Stream with ID=%RU8 not handled\n", uStreamID));
     1179            break;
     1180        }
     1181    }
     1182
     1183    return pStrmSt;
     1184}
    11491185
    11501186/**
     
    14781514
    14791515    pStrmSt->u8Strm     = u8Strm;
    1480     pStrmSt->u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8Strm),
     1516    pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8Strm),
    14811517                                      HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8Strm));
    14821518    pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8Strm);
     
    14881524
    14891525    LogFlowFunc(("[SD%RU8]: DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n",
    1490                  pStrmSt->u8Strm, pStrmSt->u64BaseDMA, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));
     1526                 pStrmSt->u8Strm, pStrmSt->u64BDLBase, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));
    14911527
    14921528#ifdef DEBUG
     
    18521888static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    18531889{
    1854     const uint8_t  u8Strm  = HDA_SD_NUM_FROM_REG(pThis, CBL, iReg);
    1855           uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, u8Strm);
    1856 
    1857     LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32\n", u8Strm, u32LPIB, u32Value));
    1858 
    1859     return hdaRegWriteU32(pThis, iReg, u32Value);
     1890    int rc = hdaRegWriteU32(pThis, iReg, u32Value);
     1891    if (RT_SUCCESS(rc))
     1892    {
     1893        uint8_t u8Strm  = HDA_SD_NUM_FROM_REG(pThis, CBL, iReg);
     1894
     1895        PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
     1896        if (pStrmSt)
     1897        {
     1898            pStrmSt->u32CBL = u32Value;
     1899
     1900            /* Reset BDLE state. */
     1901            RT_ZERO(pStrmSt->State.BDLE);
     1902            pStrmSt->State.uCurBDLE = 0;
     1903        }
     1904
     1905        LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value));
     1906    }
     1907    else
     1908        AssertRCReturn(rc, VINF_SUCCESS);
     1909
     1910    return rc;
    18601911}
    18611912
     
    18691920    uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg);
    18701921
    1871     PHDASTREAM pStrmSt;
    1872     switch (u8Strm)
    1873     {
    1874         case 0: /** @todo Use dynamic indices, based on stream assignment. */
    1875         {
    1876             pStrmSt = &pThis->StrmStLineIn;
    1877             break;
    1878         }
    1879 # ifdef VBOX_WITH_HDA_MIC_IN
    1880         case 2: /** @todo Use dynamic indices, based on stream assignment. */
    1881         {
    1882             pStrmSt = &pThis->StrmStMicIn;
    1883             break;
    1884         }
    1885 # endif
    1886         case 4: /** @todo Use dynamic indices, based on stream assignment. */
    1887         {
    1888             pStrmSt = &pThis->StrmStOut;
    1889             break;
    1890         }
    1891 
    1892         default:
    1893         {
    1894             LogFunc(("Warning: Changing SDCTL on non-attached stream (iReg=0x%x)\n", iReg));
    1895             return hdaRegWriteU24(pThis, iReg, u32Value); /* Write 3 bytes. */
    1896         }
     1922    PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
     1923    if (!pStrmSt)
     1924    {
     1925        LogFunc(("Warning: Changing SDCTL on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg));
     1926        return hdaRegWriteU24(pThis, iReg, u32Value); /* Write 3 bytes. */
    18971927    }
    18981928
     
    19862016        return VINF_SUCCESS;
    19872017
    1988     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    1989     if (RT_FAILURE(rc))
     2018    int rc = hdaRegWriteU16(pThis, iReg, u32Value);
     2019    if (RT_SUCCESS(rc))
     2020    {
     2021        uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);
     2022
     2023        PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
     2024        if (pStrmSt)
     2025        {
     2026            pStrmSt->u16LVI = u32Value;
     2027
     2028            /* Reset BDLE state. */
     2029            RT_ZERO(pStrmSt->State.BDLE);
     2030            pStrmSt->State.uCurBDLE = 0;
     2031        }
     2032
     2033        LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value));
     2034    }
     2035    else
    19902036        AssertRCReturn(rc, VINF_SUCCESS);
     2037
    19912038    return rc;
    19922039}
     
    20712118
    20722119#ifdef IN_RING3
    2073 static int hdaSDFMTToStrmCfg(uint32_t u32SdFmt, PPDMAUDIOSTREAMCFG pCfg)
     2120static int hdaSDFMTToStrmCfg(uint32_t u32SDFMT, PPDMAUDIOSTREAMCFG pCfg)
    20742121{
    20752122    AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
     
    20792126    int rc = VINF_SUCCESS;
    20802127
    2081     uint32_t u32Hz     = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
     2128    uint32_t u32Hz     = (u32SDFMT & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
    20822129    uint32_t u32HzMult = 1;
    20832130    uint32_t u32HzDiv  = 1;
    20842131
    2085     switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT))
     2132    switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT))
    20862133    {
    20872134        case 0: u32HzMult = 1; break;
     
    20912138        default:
    20922139            LogFunc(("Unsupported multiplier %x\n",
    2093                      EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT)));
     2140                     EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT)));
    20942141            rc = VERR_NOT_SUPPORTED;
    20952142            break;
    20962143    }
    2097     switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT))
     2144    switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT))
    20982145    {
    20992146        case 0: u32HzDiv = 1; break;
     
    21072154        default:
    21082155            LogFunc(("Unsupported divisor %x\n",
    2109                      EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT)));
     2156                     EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT)));
    21102157            rc = VERR_NOT_SUPPORTED;
    21112158            break;
     
    21132160
    21142161    PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */
    2115     switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
     2162    switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
    21162163    {
    21172164        case 0:
     
    21352182        default:
    21362183            AssertMsgFailed(("Unsupported bits shift %x\n",
    2137                              EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)));
     2184                             EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)));
    21382185            rc = VERR_NOT_SUPPORTED;
    21392186            break;
     
    21432190    {
    21442191        pCfg->uHz           = u32Hz * u32HzMult / u32HzDiv;
    2145         pCfg->cChannels     = (u32SdFmt & 0xf) + 1;
     2192        pCfg->cChannels     = (u32SDFMT & 0xf) + 1;
    21462193        pCfg->enmFormat     = enmFmt;
    21472194        pCfg->enmEndianness = PDMAUDIOHOSTENDIANNESS;
     
    21662213    int rc = hdaSDFMTToStrmCfg(u32Value, &strmCfg);
    21672214    if (RT_FAILURE(rc))
    2168         return rc;
     2215        return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     2216
     2217    uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, FMT, iReg);
    21692218
    21702219    PHDADRIVER pDrv;
     
    21812230            break;
    21822231#  endif
     2232        case HDA_REG_SD4FMT:
     2233            RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     2234                rc = hdaCodecOpenStream(pThis->pCodec, PO_INDEX, &strmCfg);
     2235            break;
    21832236        default:
    2184             LogFunc(("Warning: Attempt to change format on register %RU32\n", iReg));
     2237            LogFunc(("Warning: Changing SDFMT on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg));
    21852238            break;
    21862239    }
     
    21962249}
    21972250
    2198 static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
     2251/* Note: Will be called for both, BDPL and BDPU, registers. */
     2252static DECLINLINE(int) hdaRegWriteSDBDPX(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t u8Strm)
    21992253{
    22002254    if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
    22012255        return VINF_SUCCESS;
    22022256
    2203     LogFlowFunc(("[SD%RU8]: DMA BDPL -> 0x%x\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
    2204 
    22052257    int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    2206     if (RT_FAILURE(rc))
     2258    if (RT_SUCCESS(rc))
     2259    {
     2260        PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
     2261        if (pStrmSt)
     2262        {
     2263            pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
     2264                                              HDA_STREAM_REG(pThis, BDPU, u8Strm));
     2265            /* Reset BDLE state. */
     2266            RT_ZERO(pStrmSt->State.BDLE);
     2267            pStrmSt->State.uCurBDLE = 0;
     2268        }
     2269    }
     2270    else
    22072271        AssertRCReturn(rc, VINF_SUCCESS);
     2272
    22082273    return rc;
    22092274}
    22102275
     2276static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
     2277{
     2278    return hdaRegWriteSDBDPX(pThis, iReg, u32Value, HDA_SD_NUM_FROM_REG(pThis, BDPL, iReg));
     2279}
     2280
    22112281static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    22122282{
    2213     if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
    2214         return VINF_SUCCESS;
    2215 
    2216     LogFlowFunc(("[SD%RU8]: DMA BDPU -> 0x%x\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
    2217 
    2218     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    2219     if (RT_FAILURE(rc))
    2220         AssertRCReturn(rc, VINF_SUCCESS);
    2221     return rc;
     2283    return hdaRegWriteSDBDPX(pThis, iReg, u32Value, HDA_SD_NUM_FROM_REG(pThis, BDPU, iReg));
    22222284}
    22232285
     
    31793241    /* Sanity checks. */
    31803242    Assert(pStrmSt->u8Strm <= 7); /** @todo Use a define for MAX_STREAMS! */
    3181     Assert(pStrmSt->u64BaseDMA);
     3243    Assert(pStrmSt->u64BDLBase);
    31823244    Assert(pStrmSt->u32CBL);
    31833245
     
    35723634    hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1);
    35733635
    3574     Assert(u64BaseDMA == pStrm->u64BaseDMA);
     3636    Assert(u64BaseDMA == pStrm->u64BDLBase);
    35753637    Assert(u16LVI     == pStrm->u16LVI);
    35763638    Assert(u32CBL     == pStrm->u32CBL);
     
    38043866                    break;
    38053867
    3806                 PHDASTREAM pStrm;
     3868                PHDASTREAM pStrm = hdaStreamFromID(pThis, uStreamID);
    38073869                HDASTREAM  StreamDummy;
    38083870
    3809                 switch (uStreamID)
     3871                if (!pStrm)
    38103872                {
    3811                     case 0: /** @todo Implement dynamic stream IDs. */
    3812                         pStrm = &pThis->StrmStLineIn;
    3813                         break;
    3814 #ifdef VBOX_WITH_HDA_MIC_IN
    3815                     case 2: /** @todo Implement dynamic stream IDs. */
    3816                         pStrm = &pThis->StrmStMicIn;
    3817                         break;
    3818 #endif
    3819                     case 4: /** @todo Implement dynamic stream IDs. */
    3820                         pStrm = &pThis->StrmStOut;
    3821                         break;
    3822 
    3823                     default:
    3824                         pStrm = &StreamDummy;
    3825 
    3826                         LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uStreamID));
    3827                         break;
     3873                    pStrm = &StreamDummy;
     3874                    LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uStreamID));
     3875                    break;
    38283876                }
    38293877
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h

    r59275 r59439  
    130130int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM);
    131131int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion);
    132 int hdaCodecOpenStream(PHDACODEC pThis, PDMAUDIORECSOURCE enmRecSource, PDMAUDIOSTREAMCFG *pAudioSettings);
     132int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg);
    133133
    134134#define HDA_SSM_VERSION   6
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