Changeset 99310 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 6, 2023 6:33:11 AM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 156698
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHda.cpp
r98103 r99310 784 784 785 785 #ifdef IN_RING3 786 787 786 /** 788 787 * Looks up a register covering the offset given by @a offReg. 789 788 * 790 789 * @returns Register index on success, -1 if not found. 791 * @param offReg The register offset. 792 */ 793 static int hdaR3RegLookupWithin(uint32_t offReg) 790 * @param offReg The register offset. 791 * @param pcbBefore Where to return the number of bytes in the matching 792 * register preceeding @a offReg. 793 */ 794 static int hdaR3RegLookupWithin(uint32_t offReg, uint32_t *pcbBefore) 794 795 { 795 796 /* 796 797 * Aliases. 798 * 799 * We ASSUME the aliases are for whole registers and that they have the 800 * same alignment (release-asserted in the constructor), so we don't need 801 * to calculate the within-register-offset twice here. 797 802 */ 798 803 if (offReg >= g_aHdaRegAliases[0].offReg) … … 800 805 for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegAliases); i++) 801 806 { 802 uint32_t off = offReg - g_aHdaRegAliases[i].offReg; 803 if (off < 4 && off < g_aHdaRegMap[g_aHdaRegAliases[i].idxAlias].cb) 804 return g_aHdaRegAliases[i].idxAlias; 807 uint32_t const off = offReg - g_aHdaRegAliases[i].offReg; 808 if (off < 4) /* No register is wider than 4 bytes (release-asserted in constructor). */ 809 { 810 const uint32_t idxAlias = g_aHdaRegAliases[i].idxAlias; 811 if (off < g_aHdaRegMap[idxAlias].cb) 812 { 813 Assert(off > 0); /* ASSUMES the caller already did a hdaRegLookup which failed. */ 814 Assert((g_aHdaRegAliases[i].offReg & 3) == (g_aHdaRegMap[idxAlias].off & 3)); 815 *pcbBefore = off; 816 return idxAlias; 817 } 818 } 805 819 } 806 820 Assert(g_aHdaRegMap[RT_ELEMENTS(g_aHdaRegMap) - 1].off < offReg); 821 *pcbBefore = 0; 807 822 return -1; 808 823 } … … 829 844 } 830 845 else 846 { 847 offReg -= g_aHdaRegMap[idxMiddle].off; 848 *pcbBefore = offReg; 849 Assert(offReg > 0); /* ASSUMES the caller already did a hdaRegLookup which failed. */ 850 Assert(g_aHdaRegMap[idxMiddle].cb <= 4); /* This is release-asserted in the constructor. */ 831 851 return idxMiddle; 852 } 832 853 } 833 854 … … 836 857 Assert(offReg - g_aHdaRegMap[i].off >= g_aHdaRegMap[i].cb); 837 858 # endif 859 *pcbBefore = 0; 838 860 return -1; 839 861 } 840 841 862 #endif /* IN_RING3 */ 842 863 … … 3411 3432 if (idxRegDsc < 0) 3412 3433 { 3413 idxRegDsc = hdaR3RegLookupWithin(off); 3434 uint32_t cbBefore; 3435 idxRegDsc = hdaR3RegLookupWithin(off, &cbBefore); 3414 3436 if (idxRegDsc != -1) 3415 3437 { 3416 uint32_t const cbBefore = (uint32_t)off - g_aHdaRegMap[idxRegDsc].off; 3417 Assert(cbBefore > 0 && cbBefore < 4); 3438 Assert(cbBefore > 0 && cbBefore < 4 /* no register is wider than 4 bytes, we check in the constructor */); 3418 3439 off -= cbBefore; 3419 3440 idxRegMem = g_aHdaRegMap[idxRegDsc].idxReg; … … 3472 3493 else 3473 3494 { 3495 /** @todo r=bird: This doesn't work for aliased registers, since the incremented 3496 * offset won't match as it's still the aliased one. Only scenario, though 3497 * would be misaligned accesses (2, 4 or 8 bytes), and the result would be that 3498 * only the first part will be written. Given that the aliases we have are lone 3499 * registers, that seems like they shouldn't have anything else around them, 3500 * this is probably the correct behaviour, though real hw may of course 3501 * disagree. Only look into it if we have a sane guest running into this. */ 3474 3502 idxRegDsc++; 3475 3503 if ( (unsigned)idxRegDsc >= RT_ELEMENTS(g_aHdaRegMap) … … 5220 5248 AssertReleaseMsg(pNextReg || ((pReg->off + pReg->cb) & 3) == 0, 5221 5249 ("[%#x] = {%#x LB %#x}\n", i, pReg->off, pReg->cb)); 5250 } 5251 for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegAliases); i++) 5252 { 5253 /* Valid alias index. */ 5254 uint32_t const idxAlias = g_aHdaRegAliases[i].idxAlias; 5255 AssertReleaseMsg(g_aHdaRegAliases[i].idxAlias < (int)RT_ELEMENTS(g_aHdaRegMap), ("[%#x] idxAlias=%#x\n", i, idxAlias)); 5256 /* Same register alignment. */ 5257 AssertReleaseMsg((g_aHdaRegAliases[i].offReg & 3) == (g_aHdaRegMap[idxAlias].off & 3), 5258 ("[%#x] idxAlias=%#x offReg=%#x vs off=%#x\n", 5259 i, idxAlias, g_aHdaRegAliases[i].offReg, g_aHdaRegMap[idxAlias].off)); 5260 /* Register is four or fewer bytes wide (already checked above). */ 5261 AssertReleaseMsg(g_aHdaRegMap[idxAlias].cb <= 4, ("[%#x] idxAlias=%#x cb=%d\n", i, idxAlias, g_aHdaRegMap[idxAlias].cb)); 5222 5262 } 5223 5263 Assert(strcmp(g_aHdaRegMap[HDA_REG_SSYNC].pszName, "SSYNC") == 0);
Note:
See TracChangeset
for help on using the changeset viewer.