VirtualBox

Changeset 37639 in vbox


Ignore:
Timestamp:
Jun 24, 2011 3:54:20 PM (14 years ago)
Author:
vboxsync
Message:

DevIchIntelHDA: Don't write to the input buffer in MMIO write handlers. Extended todo.

File:
1 edited

Legend:

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

    r37636 r37639  
    577577    { 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS       , hdaRegWriteUnimplemented, "INTSTS"    , "Interrupt Status" },
    578578    { 0x00030, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadWALCLK       , hdaRegWriteUnimplemented, "WALCLK"    , "Wall Clock Counter" },
    579     //** @todo r=michaln: Doesn't the SSYNC register need to actually stop the stream(s)?
     579    /// @todo r=michaln: Doesn't the SSYNC register need to actually stop the stream(s)?
    580580    { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadU32          , hdaRegWriteU32          , "SSYNC"     , "Stream Synchronization" },
    581581    { 0x00040, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteBase         , "CORBLBASE" , "CORB Lower Base Address" },
     
    735735static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset)
    736736{
    737     int index = 0;
    738     //** @todo r=michaln: A linear search of an array with over 100 elements is very inefficient.
    739     for (;index < (int)(sizeof(s_ichIntelHDRegMap)/sizeof(s_ichIntelHDRegMap[0])); ++index)
     737    /// @todo r=michaln: A linear search of an array with over 100 elements is very inefficient.
     738    /** @todo r=bird: Do a binary search, the array is sorted. */
     739    for (int index = 0; index < (int)RT_ELEMENTS(s_ichIntelHDRegMap); ++index)
    740740    {
    741741        if (   u32Offset >= s_ichIntelHDRegMap[index].offset
     
    18691869    if (index != -1)
    18701870    {
     1871        /** @todo r=bird: Accesses crossing register boundraries aren't handled
     1872         *        right from what I can tell?  If they are, please explain
     1873         *        what the rules are. */
    18711874        uint32_t mask = 0;
    18721875        uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
     
    18861889    }
    18871890    *(uint32_t *)pv = 0xFF;
    1888     Log(("hda: hole at %X is accessed for read\n", u32Offset));
     1891    Log(("hda: hole at %x is accessed for read\n", u32Offset));
    18891892    return rc;
    18901893}
     
    19051908PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
    19061909{
    1907     int rc = VINF_SUCCESS;
    1908     PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    1909     uint32_t  u32Offset = GCPhysAddr - pThis->hda.addrMMReg;
    1910     int index = hdaLookup(&pThis->hda, u32Offset);
    1911 
    1912     if (pThis->hda.fInReset && index != ICH6_HDA_REG_GCTL)
     1910    PCIINTELHDLinkState    *pThis     = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
     1911    uint32_t                offReg    = GCPhysAddr - pThis->hda.addrMMReg;
     1912    int                     idxReg    = hdaLookup(&pThis->hda, offReg);
     1913    int                     rc        = VINF_SUCCESS;
     1914
     1915    if (pThis->hda.fInReset && idxReg != ICH6_HDA_REG_GCTL)
    19131916        Log(("hda: access to registers except GCTL is blocked while reset\n"));
    19141917
    1915     if (   index == -1
    1916            || cb > 4)
    1917         LogRel(("hda: Invalid write access @0x%x(of bytes:%d)\n", u32Offset, cb));
    1918 
    1919     if (index != -1)
    1920     {
    1921         /** @todo r=bird: What is all this masking and shifting about? And
    1922          *        WHY ON EARTH are you writing to the input data?!? */
    1923         uint32_t v = pThis->hda.au32Regs[index];
    1924         uint32_t mask = 0;
    1925         uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
    1926         switch(cb)
     1918    if (   idxReg == -1
     1919        || cb > 4)
     1920        LogRel(("hda: Invalid write access @0x%x(of bytes:%d)\n", offReg, cb));
     1921
     1922    if (idxReg != -1)
     1923    {
     1924        /** @todo r=bird: This looks like code for handling unalinged register
     1925         * accesses.  If it isn't then, add a comment explaing what you're
     1926         * trying to do here.  OTOH, if it is then it has the following
     1927         * issues:
     1928         *      -# You're calculating the wrong new value for the register.
     1929         *      -# You're not handling cross register accesses.  Imagine a
     1930         *       4-byte write starting at CORBCTL, or a 8-byte write.
     1931         *
     1932         * PS! consider dropping the 'offset' argument to pfnWrite/pfnRead as
     1933         * nobody seems to be using it and it just add complexity when reading
     1934         * the code.
     1935         *
     1936         * PPS. 'v' is not a very good variable name.
     1937         * PPPS. We don't do 3 byte writes, only 1, 2, 4 and 8.
     1938         */
     1939        uint32_t u32CurValue = pThis->hda.au32Regs[idxReg];
     1940        uint32_t u32NewValue;
     1941        uint32_t mask;
     1942        switch (cb)
    19271943        {
    1928             case 1: mask = 0xffffff00; break;
    1929             case 2: mask = 0xffff0000; break;
    1930             case 3: mask = 0xff000000; break;
    1931             case 4: mask = 0x00000000; break;
     1944            case 1:
     1945                u32NewValue = *(uint8_t const *)pv;
     1946                mask = 0xffffff00;
     1947                break;
     1948            case 2:
     1949                u32NewValue = *(uint16_t const *)pv;
     1950                mask = 0xffff0000;
     1951                break;
     1952            case 4:
     1953            case 8: /** @todo r=bird: Add a line about why 8-byte accesses are handled like 4-byte ones. */
     1954                u32NewValue = *(uint32_t const *)pv;
     1955                mask = 0;
     1956                break;
     1957            default:
     1958                AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* shall not happen. */
    19321959        }
     1960        uint32_t shift = (offReg - s_ichIntelHDRegMap[idxReg].offset) % sizeof(uint32_t) * 8;
    19331961        mask <<= shift;
    1934         *(uint32_t *)pv = ((v & mask) | (*(uint32_t *)pv & ~mask)) >> shift;
    1935         rc = s_ichIntelHDRegMap[index].pfnWrite(&pThis->hda, u32Offset, index, *(uint32_t *)pv);
    1936         Log(("hda: write %s:(%x) %x => %x\n", s_ichIntelHDRegMap[index].abbrev, *(uint32_t *)pv, v, pThis->hda.au32Regs[index]));
     1962        u32NewValue = ((u32CurValue & mask) | (u32NewValue & ~mask)) >> shift;
     1963
     1964        rc = s_ichIntelHDRegMap[idxReg].pfnWrite(&pThis->hda, offReg, idxReg, u32NewValue);
     1965        Log(("hda: write %s:(%x) %x => %x\n", s_ichIntelHDRegMap[idxReg].abbrev, u32NewValue,
     1966             u32CurValue, pThis->hda.au32Regs[idxReg]));
    19371967        return rc;
    19381968    }
    1939     Log(("hda: hole at %X is accessed for write\n", u32Offset));
     1969
     1970    Log(("hda: hole at %x is accessed for write\n", offReg));
    19401971    return rc;
    19411972}
     
    23842415#endif
    23852416
    2386     //** @todo r=michaln: If there are really no PCIDevSetXx for these, the meaning
     2417    /// @todo r=michaln: If there are really no PCIDevSetXx for these, the meaning
    23872418    // of these values needs to be properly documented!
    23882419    /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
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