Changeset 37639 in vbox
- Timestamp:
- Jun 24, 2011 3:54:20 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r37636 r37639 577 577 { 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS , hdaRegWriteUnimplemented, "INTSTS" , "Interrupt Status" }, 578 578 { 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)? 580 580 { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadU32 , hdaRegWriteU32 , "SSYNC" , "Stream Synchronization" }, 581 581 { 0x00040, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteBase , "CORBLBASE" , "CORB Lower Base Address" }, … … 735 735 static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset) 736 736 { 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) 740 740 { 741 741 if ( u32Offset >= s_ichIntelHDRegMap[index].offset … … 1869 1869 if (index != -1) 1870 1870 { 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. */ 1871 1874 uint32_t mask = 0; 1872 1875 uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8; … … 1886 1889 } 1887 1890 *(uint32_t *)pv = 0xFF; 1888 Log(("hda: hole at % Xis accessed for read\n", u32Offset));1891 Log(("hda: hole at %x is accessed for read\n", u32Offset)); 1889 1892 return rc; 1890 1893 } … … 1905 1908 PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 1906 1909 { 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 && i ndex!= 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) 1913 1916 Log(("hda: access to registers except GCTL is blocked while reset\n")); 1914 1917 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) 1927 1943 { 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. */ 1932 1959 } 1960 uint32_t shift = (offReg - s_ichIntelHDRegMap[idxReg].offset) % sizeof(uint32_t) * 8; 1933 1961 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])); 1937 1967 return rc; 1938 1968 } 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)); 1940 1971 return rc; 1941 1972 } … … 2384 2415 #endif 2385 2416 2386 // **@todo r=michaln: If there are really no PCIDevSetXx for these, the meaning2417 /// @todo r=michaln: If there are really no PCIDevSetXx for these, the meaning 2387 2418 // of these values needs to be properly documented! 2388 2419 /* 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.