VirtualBox

Changeset 87802 in vbox


Ignore:
Timestamp:
Feb 19, 2021 11:18:55 AM (4 years ago)
Author:
vboxsync
Message:

HDA/Codec: Codec now also can run in R0 to speed up interrupt handling and therefore lowering DPC latency on Windows guests [build fix]. ticketoem2ref:36

File:
1 edited

Legend:

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

    r87801 r87802  
    944944#endif /* unused */
    945945
     946#ifdef IN_RING0
     947
    946948/* B-- */
    947949static DECLCALLBACK(int) vrbProcGetAmplifier(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    990992}
    991993
    992 #ifdef IN_RING3
    993 
    994 /* 3-- */
    995 static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
    996 {
    997     *pResp = 0;
    998 
    999     PCODECNODE pNode      = &pThis->aNodes[CODEC_NID(cmd)];
    1000     AMPLIFIER *pAmplifier = NULL;
    1001     if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    1002         pAmplifier = &pNode->dac.B_params;
    1003     else if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
    1004         pAmplifier = &pNode->adcvol.B_params;
    1005     else if (hdaCodecIsAdcMuxNode(pThis, CODEC_NID(cmd)))
    1006         pAmplifier = &pNode->adcmux.B_params;
    1007     else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
    1008         pAmplifier = &pNode->pcbeep.B_params;
    1009     else if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1010         pAmplifier = &pNode->port.B_params;
    1011     else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    1012         pAmplifier = &pNode->adc.B_params;
    1013     else
    1014         LogRel2(("HDA: Warning: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n",
    1015                  cmd, CODEC_VERB_PAYLOAD16(cmd), CODEC_NID(cmd), CODEC_NID(cmd)));
    1016 
    1017     if (!pAmplifier)
    1018         return VINF_SUCCESS;
    1019 
    1020     bool fIsOut     = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
    1021     bool fIsIn      = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
    1022     bool fIsLeft    = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
    1023     bool fIsRight   = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
    1024     uint8_t u8Index = CODEC_SET_AMP_INDEX(cmd);
    1025 
    1026     if (   (!fIsLeft && !fIsRight)
    1027         || (!fIsOut && !fIsIn))
    1028         return VINF_SUCCESS;
    1029 
    1030     LogFunc(("[NID0x%02x] fIsOut=%RTbool, fIsIn=%RTbool, fIsLeft=%RTbool, fIsRight=%RTbool, Idx=%RU8\n",
    1031              CODEC_NID(cmd), fIsOut, fIsIn, fIsLeft, fIsRight, u8Index));
    1032 
    1033     if (fIsIn)
    1034     {
    1035         if (fIsLeft)
    1036             hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
    1037         if (fIsRight)
    1038             hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
    1039 
    1040     //    if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn)
    1041     //    {
    1042             hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
    1043     //    }
    1044     }
    1045     if (fIsOut)
    1046     {
    1047         if (fIsLeft)
    1048             hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
    1049         if (fIsRight)
    1050             hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
    1051 
    1052         if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    1053             hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
    1054     }
    1055 
    1056     return VINF_SUCCESS;
    1057 }
    1058 
    1059 #endif /* IN_RING3 */
    1060 
    1061994static DECLCALLBACK(int) vrbProcGetParameter(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1062995{
     
    16341567}
    16351568
    1636 #ifdef IN_RING3
    1637 
    1638 /* 706 */
    1639 static DECLCALLBACK(int) vrbProcR3SetStreamId(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
    1640 {
    1641     *pResp = 0;
    1642 
    1643     uint8_t uSD      = CODEC_F00_06_GET_STREAM_ID(cmd);
    1644     uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd);
    1645 
    1646     LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8\n",
    1647                  CODEC_NID(cmd), uSD, uChannel));
    1648 
    1649     ASSERT_GUEST_LOGREL_MSG_RETURN(uSD < HDA_MAX_STREAMS,
    1650                                    ("Setting stream ID #%RU8 is invalid\n", uSD), VERR_INVALID_PARAMETER);
    1651 
    1652     PDMAUDIODIR enmDir;
    1653     uint32_t *pu32Addr = NULL;
    1654     if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    1655     {
    1656         pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F06_param;
    1657         enmDir = PDMAUDIODIR_OUT;
    1658     }
    1659     else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    1660     {
    1661         pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F06_param;
    1662         enmDir = PDMAUDIODIR_IN;
    1663     }
    1664     else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    1665     {
    1666         pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    1667         enmDir = PDMAUDIODIR_OUT;
    1668     }
    1669     else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    1670     {
    1671         pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
    1672         enmDir = PDMAUDIODIR_IN;
    1673     }
    1674     else
    1675     {
    1676         enmDir = PDMAUDIODIR_UNKNOWN;
    1677         LogRel2(("HDA: Warning: Unhandled set stream ID command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
    1678     }
    1679 
    1680     /* Do we (re-)assign our input/output SDn (SDI/SDO) IDs? */
    1681     if (enmDir != PDMAUDIODIR_UNKNOWN)
    1682     {
    1683         pThis->aNodes[CODEC_NID(cmd)].node.uSD      = uSD;
    1684         pThis->aNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
    1685 
    1686         if (enmDir == PDMAUDIODIR_OUT)
    1687         {
    1688             /** @todo Check if non-interleaved streams need a different channel / SDn? */
    1689 
    1690             /* Propagate to the controller. */
    1691             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
    1692 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    1693             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
    1694             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
    1695 #endif
    1696         }
    1697         else if (enmDir == PDMAUDIODIR_IN)
    1698         {
    1699             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
    1700 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    1701             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
    1702 #endif
    1703         }
    1704     }
    1705 
    1706     if (pu32Addr)
    1707         hdaCodecSetRegisterU8(pu32Addr, cmd, 0);
    1708 
    1709     return VINF_SUCCESS;
    1710 }
    1711 
    1712 #endif /* IN_RING3 */
    1713 
    17141569/* A0 */
    17151570static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    19881843}
    19891844
    1990 #ifdef IN_RING3
    1991 
    1992 /**
    1993  * HDA codec verb map for ring-3.
    1994  */
    1995 static const CODECVERBR3 g_aCodecVerbsR3[] =
    1996 {
    1997    /* Verb        Verb mask            Callback                        Name
    1998     * ---------- --------------------- ----------------------------------------------------------
    1999     */
    2000    { 0x00070600, CODEC_VERB_8BIT_CMD , vrbProcR3SetStreamId          , "SetStreamId           " },
    2001    { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcR3SetAmplifier         , "SetAmplifier          " }
    2002 };
    2003 
    2004 #else /* IN_RING0 */
     1845#else /* IN_RING3 */
     1846
     1847/* 3-- */
     1848static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
     1849{
     1850    *pResp = 0;
     1851
     1852    PCODECNODE pNode      = &pThis->aNodes[CODEC_NID(cmd)];
     1853    AMPLIFIER *pAmplifier = NULL;
     1854    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     1855        pAmplifier = &pNode->dac.B_params;
     1856    else if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
     1857        pAmplifier = &pNode->adcvol.B_params;
     1858    else if (hdaCodecIsAdcMuxNode(pThis, CODEC_NID(cmd)))
     1859        pAmplifier = &pNode->adcmux.B_params;
     1860    else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
     1861        pAmplifier = &pNode->pcbeep.B_params;
     1862    else if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
     1863        pAmplifier = &pNode->port.B_params;
     1864    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
     1865        pAmplifier = &pNode->adc.B_params;
     1866    else
     1867        LogRel2(("HDA: Warning: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n",
     1868                 cmd, CODEC_VERB_PAYLOAD16(cmd), CODEC_NID(cmd), CODEC_NID(cmd)));
     1869
     1870    if (!pAmplifier)
     1871        return VINF_SUCCESS;
     1872
     1873    bool fIsOut     = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
     1874    bool fIsIn      = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
     1875    bool fIsLeft    = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
     1876    bool fIsRight   = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
     1877    uint8_t u8Index = CODEC_SET_AMP_INDEX(cmd);
     1878
     1879    if (   (!fIsLeft && !fIsRight)
     1880        || (!fIsOut && !fIsIn))
     1881        return VINF_SUCCESS;
     1882
     1883    LogFunc(("[NID0x%02x] fIsOut=%RTbool, fIsIn=%RTbool, fIsLeft=%RTbool, fIsRight=%RTbool, Idx=%RU8\n",
     1884             CODEC_NID(cmd), fIsOut, fIsIn, fIsLeft, fIsRight, u8Index));
     1885
     1886    if (fIsIn)
     1887    {
     1888        if (fIsLeft)
     1889            hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
     1890        if (fIsRight)
     1891            hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
     1892
     1893    //    if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn)
     1894    //    {
     1895            hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
     1896    //    }
     1897    }
     1898    if (fIsOut)
     1899    {
     1900        if (fIsLeft)
     1901            hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
     1902        if (fIsRight)
     1903            hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
     1904
     1905        if (CODEC_NID(cmd) == pThis->u8DacLineOut)
     1906            hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
     1907    }
     1908
     1909    return VINF_SUCCESS;
     1910}
     1911
     1912/* 706 */
     1913static DECLCALLBACK(int) vrbProcR3SetStreamId(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
     1914{
     1915    *pResp = 0;
     1916
     1917    uint8_t uSD      = CODEC_F00_06_GET_STREAM_ID(cmd);
     1918    uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd);
     1919
     1920    LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8\n",
     1921                 CODEC_NID(cmd), uSD, uChannel));
     1922
     1923    ASSERT_GUEST_LOGREL_MSG_RETURN(uSD < HDA_MAX_STREAMS,
     1924                                   ("Setting stream ID #%RU8 is invalid\n", uSD), VERR_INVALID_PARAMETER);
     1925
     1926    PDMAUDIODIR enmDir;
     1927    uint32_t *pu32Addr = NULL;
     1928    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     1929    {
     1930        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F06_param;
     1931        enmDir = PDMAUDIODIR_OUT;
     1932    }
     1933    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
     1934    {
     1935        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F06_param;
     1936        enmDir = PDMAUDIODIR_IN;
     1937    }
     1938    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
     1939    {
     1940        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
     1941        enmDir = PDMAUDIODIR_OUT;
     1942    }
     1943    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
     1944    {
     1945        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
     1946        enmDir = PDMAUDIODIR_IN;
     1947    }
     1948    else
     1949    {
     1950        enmDir = PDMAUDIODIR_UNKNOWN;
     1951        LogRel2(("HDA: Warning: Unhandled set stream ID command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     1952    }
     1953
     1954    /* Do we (re-)assign our input/output SDn (SDI/SDO) IDs? */
     1955    if (enmDir != PDMAUDIODIR_UNKNOWN)
     1956    {
     1957        pThis->aNodes[CODEC_NID(cmd)].node.uSD      = uSD;
     1958        pThis->aNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
     1959
     1960        if (enmDir == PDMAUDIODIR_OUT)
     1961        {
     1962            /** @todo Check if non-interleaved streams need a different channel / SDn? */
     1963
     1964            /* Propagate to the controller. */
     1965            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
     1966#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     1967            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
     1968            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
     1969#endif
     1970        }
     1971        else if (enmDir == PDMAUDIODIR_IN)
     1972        {
     1973            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
     1974#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     1975            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
     1976#endif
     1977        }
     1978    }
     1979
     1980    if (pu32Addr)
     1981        hdaCodecSetRegisterU8(pu32Addr, cmd, 0);
     1982
     1983    return VINF_SUCCESS;
     1984}
     1985
     1986#endif /* IN_RING0 */
     1987
     1988#ifdef IN_RING0
    20051989
    20061990/**
     
    20612045};
    20622046
    2063 #endif /* IN_RING3 */
     2047#else /* IN_RING3 */
     2048
     2049/**
     2050 * HDA codec verb map for ring-3.
     2051 */
     2052static const CODECVERBR3 g_aCodecVerbsR3[] =
     2053{
     2054   /* Verb        Verb mask            Callback                        Name
     2055    * ---------- --------------------- ----------------------------------------------------------
     2056    */
     2057   { 0x00070600, CODEC_VERB_8BIT_CMD , vrbProcR3SetStreamId          , "SetStreamId           " },
     2058   { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcR3SetAmplifier         , "SetAmplifier          " }
     2059};
     2060
     2061#endif /* IN_RING0 */
    20642062
    20652063#if defined(IN_RING3) && defined(DEBUG)
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