VirtualBox

Changeset 44635 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Feb 11, 2013 3:17:19 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
83723
Message:

DevIchIntelHDA.cpp: Let IOM handle unaligned and odd sized write accesses.

File:
1 edited

Legend:

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

    r44634 r44635  
    19511951PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
    19521952{
    1953     PCIINTELHDLinkState    *pThis     = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    1954     uint32_t                offReg    = GCPhysAddr - pThis->hda.addrMMReg;
    1955     int                     idxReg    = hdaMMIORegLookup(&pThis->hda, offReg);
    1956     int                     rc        = VINF_SUCCESS;
     1953    PCIINTELHDLinkState    *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
     1954    uint32_t    offReg = GCPhysAddr - pThis->hda.addrMMReg;
     1955    int         idxReg = hdaMMIORegLookup(&pThis->hda, offReg);
     1956    int         rc;
     1957    Assert(!(offReg & 3)); Assert(cb == 4);
    19571958
    19581959    if (pThis->hda.fInReset && idxReg != ICH6_HDA_REG_GCTL)
    19591960        Log(("hda: access to registers except GCTL is blocked while reset\n"));
    19601961
    1961     if (   idxReg == -1
    1962         || cb > 4)
    1963         LogRel(("hda: Invalid write access @0x%x(of bytes:%d)\n", offReg, cb));
    1964 
    19651962    if (idxReg != -1)
    19661963    {
    1967         /** @todo r=bird: This looks like code for handling unaligned register
    1968          * accesses.  If it isn't, then add a comment explaining what you're
    1969          * trying to do here.  OTOH, if it is then it has the following
    1970          * issues:
    1971          *      -# You're calculating the wrong new value for the register.
    1972          *      -# You're not handling cross register accesses.  Imagine a
    1973          *       4-byte write starting at CORBCTL, or a 8-byte write.
    1974          *
    1975          * PS! consider dropping the 'offset' argument to pfnWrite/pfnRead as
    1976          * nobody seems to be using it and it just adds complexity when reading
    1977          * the code.
    1978          *
    1979          */
    1980         uint32_t u32CurValue = pThis->hda.au32Regs[idxReg];
    1981         uint32_t u32NewValue;
    1982         uint32_t mask;
    1983         switch (cb)
    1984         {
    1985             case 1:
    1986                 u32NewValue = *(uint8_t const *)pv;
    1987                 mask = 0xff;
    1988                 break;
    1989             case 2:
    1990                 u32NewValue = *(uint16_t const *)pv;
    1991                 mask = 0xffff;
    1992                 break;
    1993             case 4:
    1994             case 8:
    1995                 /* 18.2 of the ICH6 datasheet defines the valid access widths as byte, word, and double word */
    1996                 u32NewValue = *(uint32_t const *)pv;
    1997                 mask = 0xffffffff;
    1998                 cb = 4;
    1999                 break;
    2000             default:
    2001                 AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* shall not happen. */
    2002         }
    2003         /* cross-register access, see corresponding comment in hdaMMIORead */
    2004 #if 0
    2005         if (cb > g_aIchIntelHDRegMap[idxReg].size - (offReg - g_aIchIntelHDRegMap[idxReg].offset))
    2006         {
    2007             int off = cb - (g_aIchIntelHDRegMap[idxReg].size - (offReg - g_aIchIntelHDRegMap[idxReg].offset));
    2008             rc = hdaMMIOWrite(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off);
    2009             if (RT_FAILURE(rc))
    2010                 AssertRCReturn (rc, rc);
    2011         }
    2012 #endif
    2013         uint32_t shift = (g_aIchIntelHDRegMap[idxReg].offset - offReg) % sizeof(uint32_t) * 8;
    2014         mask <<= shift;
    2015         u32NewValue <<= shift;
    2016         u32NewValue &= mask;
    2017         u32NewValue |= (u32CurValue & ~mask);
    2018 
    20191964        rc = g_aIchIntelHDRegMap[idxReg].pfnWrite(&pThis->hda, offReg, idxReg, u32NewValue);
    20201965        Log(("hda: write %s:(%x) %x => %x\n", g_aIchIntelHDRegMap[idxReg].abbrev, u32NewValue,
    20211966             u32CurValue, pThis->hda.au32Regs[idxReg]));
    2022         return rc;
     1967    }
     1968    else
     1969    {
     1970        LogRel(("hda: Invalid write access @0x%x\n", offReg));
     1971        rc = VINF_SUCCESS;
    20231972    }
    20241973
     
    20431992    Assert(enmType == PCI_ADDRESS_SPACE_MEM);
    20441993    rc = PDMDevHlpMMIORegister(pPciDev->pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    2045                                IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     1994                               IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING,
    20461995                               hdaMMIOWrite, hdaMMIORead, "ICH6_HDA");
    20471996
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