VirtualBox

Changeset 37654 in vbox for trunk


Ignore:
Timestamp:
Jun 28, 2011 6:02:23 AM (13 years ago)
Author:
vboxsync
Message:

Audio/HDA: some todos.

File:
1 edited

Legend:

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

    r37642 r37654  
    5454
    5555PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    56 PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
     56PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
    5757static DECLCALLBACK(void)  hdaReset (PPDMDEVINS pDevIns);
    5858
     
    535535
    536536static inline void hdaInitTransferDescriptor(PINTELHDLinkState pState, PHDABDLEDESC pBdle, uint8_t u8Strm, PHDASTREAMTRANSFERDESC pStreamDesc);
    537 static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset);
     537static int hdaMMIORegLookup(INTELHDLinkState* pState, uint32_t u32Offset);
    538538static void hdaFetchBdle(INTELHDLinkState *pState, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc);
    539539#ifdef LOG_ENABLED
     
    733733}
    734734
    735 static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset)
     735static int hdaMMIORegLookup(INTELHDLinkState* pState, uint32_t u32Offset)
    736736{
    737737    int idxMiddle;
    738738    int idxHigh = RT_ELEMENTS(s_ichIntelHDRegMap);
    739739    int idxLow = 0;
    740     while (1)
    741     {
    742             if (idxHigh < idxLow)
    743                 break;
    744             idxMiddle = idxLow + (idxHigh - idxLow)/2;
    745             if (u32Offset < s_ichIntelHDRegMap[idxMiddle].offset)
    746             {
    747                 idxHigh = idxMiddle - 1;
    748                 continue;
    749             }
    750             if (u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
    751             {
    752                 idxLow = idxMiddle + 1;
    753                 continue;
    754             }
    755             if (u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset
    756                 && u32Offset < s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
    757                 return idxMiddle;
    758     }
    759740    /* Aliases HDA spec 3.3.45 */
    760741    switch(u32Offset)
     
    776757        case 0x2164:
    777758            return HDA_REG_IND_NAME(SD7LPIB);
     759    }
     760    while (1)
     761    {
     762#ifdef DEBUG_vvl
     763            Assert((   idxHigh >= 0
     764                    && idxLow >= 0));
     765#endif
     766            if (   idxHigh < idxLow
     767                || idxHigh < 0)
     768                break;
     769            idxMiddle = idxLow + (idxHigh - idxLow)/2;
     770            if (u32Offset < s_ichIntelHDRegMap[idxMiddle].offset)
     771            {
     772                idxHigh = idxMiddle - 1;
     773                continue;
     774            }
     775            if (u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
     776            {
     777                idxLow = idxMiddle + 1;
     778                continue;
     779            }
     780            if (   u32Offset >= s_ichIntelHDRegMap[idxMiddle].offset
     781                && u32Offset < s_ichIntelHDRegMap[idxMiddle].offset + s_ichIntelHDRegMap[idxMiddle].size)
     782                return idxMiddle;
    778783    }
    779784    return -1;
     
    18701875    int rc = VINF_SUCCESS;
    18711876    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    1872     uint32_t  u32Offset = GCPhysAddr - pThis->hda.addrMMReg;
    1873     int index = hdaLookup(&pThis->hda, u32Offset);
    1874     if (pThis->hda.fInReset && index != ICH6_HDA_REG_GCTL)
     1877    uint32_t offReg = GCPhysAddr - pThis->hda.addrMMReg;
     1878    int idxReg = hdaMMIORegLookup(&pThis->hda, offReg);
     1879    if (pThis->hda.fInReset && idxReg != ICH6_HDA_REG_GCTL)
    18751880        Log(("hda: access to registers except GCTL is blocked while reset\n"));
    18761881
    1877     if (   index == -1
    1878            || cb > 4)
    1879         LogRel(("hda: Invalid read access @0x%x(of bytes:%d)\n", u32Offset, cb));
    1880 
    1881     if (index != -1)
     1882    if (idxReg == -1)
     1883        LogRel(("hda: Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));
     1884
     1885    if (idxReg != -1)
    18821886    {
    18831887        /** @todo r=bird: Accesses crossing register boundraries aren't handled
     
    18851889         *        what the rules are. */
    18861890        uint32_t mask = 0;
    1887         uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
    1888         uint32_t v = 0;
     1891        uint32_t shift = (s_ichIntelHDRegMap[idxReg].offset - offReg) % sizeof(uint32_t) * 8;
     1892        uint32_t u32Value = 0;
    18891893        switch(cb)
    18901894        {
    18911895            case 1: mask = 0x000000ff; break;
    18921896            case 2: mask = 0x0000ffff; break;
    1893             case 3: mask = 0x00ffffff; break;
    1894             case 4: mask = 0xffffffff; break;
     1897            case 4:
     1898            /* 18.2 of ICH6 datasheet defines wideness of the accesses byte, word and double word */
     1899            case 8:
     1900                mask = 0xffffffff;
     1901                cb = 4;
     1902                break;
    18951903        }
     1904#if 0
     1905        /* cross register access. Mac guest hit this assert doing assumption 4 byte access to 3 byte registers e.g. {I,O}SDnCTL
     1906         */
     1907        //Assert((cb <= s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset)));
     1908        if (cb > s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset))
     1909        {
     1910            int off = cb - (s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset));
     1911            rc = hdaMMIORead(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off);
     1912            if (RT_FAILURE(rc))
     1913                AssertRCReturn (rc, rc);
     1914        }
     1915        //Assert(((offReg - s_ichIntelHDRegMap[idxReg].offset) == 0));
     1916#endif
    18961917        mask <<= shift;
    1897         rc = s_ichIntelHDRegMap[index].pfnRead(&pThis->hda, u32Offset, index, &v);
    1898         *(uint32_t *)pv = (v & mask) >> shift;
    1899         Log(("hda: read %s[%x/%x]\n", s_ichIntelHDRegMap[index].abbrev, v, *(uint32_t *)pv));
     1918        rc = s_ichIntelHDRegMap[idxReg].pfnRead(&pThis->hda, offReg, idxReg, &u32Value);
     1919        *(uint32_t *)pv |= (u32Value & mask);
     1920        Log(("hda: read %s[%x/%x]\n", s_ichIntelHDRegMap[idxReg].abbrev, u32Value, *(uint32_t *)pv));
    19001921        return rc;
    19011922    }
    19021923    *(uint32_t *)pv = 0xFF;
    1903     Log(("hda: hole at %x is accessed for read\n", u32Offset));
     1924    Log(("hda: hole at %x is accessed for read\n", offReg));
    19041925    return rc;
    19051926}
     
    19221943    PCIINTELHDLinkState    *pThis     = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    19231944    uint32_t                offReg    = GCPhysAddr - pThis->hda.addrMMReg;
    1924     int                     idxReg    = hdaLookup(&pThis->hda, offReg);
     1945    int                     idxReg    = hdaMMIORegLookup(&pThis->hda, offReg);
    19251946    int                     rc        = VINF_SUCCESS;
    19261947
     
    19461967         * the code.
    19471968         *
    1948          * PPS. 'v' is not a very good variable name.
    1949          * PPPS. We don't do 3 byte writes, only 1, 2, 4 and 8.
    19501969         */
    19511970        uint32_t u32CurValue = pThis->hda.au32Regs[idxReg];
     
    19561975            case 1:
    19571976                u32NewValue = *(uint8_t const *)pv;
    1958                 mask = 0xffffff00;
     1977                mask = 0xff;
    19591978                break;
    19601979            case 2:
    19611980                u32NewValue = *(uint16_t const *)pv;
    1962                 mask = 0xffff0000;
     1981                mask = 0xffff;
    19631982                break;
    19641983            case 4:
    1965             case 8: /** @todo r=bird: Add a line about why 8-byte accesses are handled like 4-byte ones. */
     1984            case 8:
     1985                /* 18.2 of ICH6 datasheet defines wideness of the accesses byte, word and double word */
    19661986                u32NewValue = *(uint32_t const *)pv;
    1967                 mask = 0;
     1987                mask = 0xffffffff;
     1988                cb = 4;
    19681989                break;
    19691990            default:
    19701991                AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* shall not happen. */
    19711992        }
    1972         uint32_t shift = (offReg - s_ichIntelHDRegMap[idxReg].offset) % sizeof(uint32_t) * 8;
     1993        /* cross register access, see corresponding comment in hdaMMIORead */
     1994#if 0
     1995        if (cb > s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset))
     1996        {
     1997            int off = cb - (s_ichIntelHDRegMap[idxReg].size - (offReg - s_ichIntelHDRegMap[idxReg].offset));
     1998            rc = hdaMMIOWrite(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off);
     1999            if (RT_FAILURE(rc))
     2000                AssertRCReturn (rc, rc);
     2001        }
     2002#endif
     2003        uint32_t shift = (s_ichIntelHDRegMap[idxReg].offset - offReg) % sizeof(uint32_t) * 8;
    19732004        mask <<= shift;
    1974         u32NewValue = ((u32CurValue & mask) | (u32NewValue & ~mask)) >> shift;
     2005        u32NewValue <<= shift;
     2006        u32NewValue &= mask;
     2007        u32NewValue |= (u32CurValue & ~mask);
    19752008
    19762009        rc = s_ichIntelHDRegMap[idxReg].pfnWrite(&pThis->hda, offReg, idxReg, u32NewValue);
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