Changeset 39149 in vbox
- Timestamp:
- Oct 31, 2011 1:18:26 PM (13 years ago)
- Location:
- trunk/src/VBox/Devices/USB
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DevOHCI.cpp
r39146 r39149 4741 4741 static const OHCIOPREG g_aOpRegs[] = 4742 4742 { 4743 { "HcRevision", HcRevision_r, HcRevision_w},4744 { "HcControl", HcControl_r, HcControl_w},4745 { "HcCommandStatus", HcCommandStatus_r, HcCommandStatus_w},4746 { "HcInterruptStatus", HcInterruptStatus_r, HcInterruptStatus_w},4747 { "HcInterruptEnable", HcInterruptEnable_r, HcInterruptEnable_w},4748 { "HcInterruptDisable", HcInterruptDisable_r, HcInterruptDisable_w},4749 { "HcHCCA", HcHCCA_r, HcHCCA_w},4750 { "HcPeriodCurrentED", HcPeriodCurrentED_r, HcPeriodCurrentED_w},4751 { "HcControlHeadED", HcControlHeadED_r, HcControlHeadED_w},4752 { "HcControlCurrentED", HcControlCurrentED_r, HcControlCurrentED_w},4753 { "HcBulkHeadED", HcBulkHeadED_r, HcBulkHeadED_w},4754 { "HcBulkCurrentED", HcBulkCurrentED_r, HcBulkCurrentED_w},4755 { "HcDoneHead", HcDoneHead_r, HcDoneHead_w},4756 { "HcFmInterval", HcFmInterval_r, HcFmInterval_w},4757 { "HcFmRemaining", HcFmRemaining_r, HcFmRemaining_w},4758 { "HcFmNumber", HcFmNumber_r, HcFmNumber_w},4759 { "HcPeriodicStart", HcPeriodicStart_r, HcPeriodicStart_w},4760 { "HcLSThreshold", HcLSThreshold_r, HcLSThreshold_w},4761 { "HcRhDescriptorA", HcRhDescriptorA_r, HcRhDescriptorA_w},4762 { "HcRhDescriptorB", HcRhDescriptorB_r, HcRhDescriptorB_w},4763 { "HcRhStatus", HcRhStatus_r, HcRhStatus_w},4743 { "HcRevision", HcRevision_r, HcRevision_w }, /* 0 */ 4744 { "HcControl", HcControl_r, HcControl_w }, /* 1 */ 4745 { "HcCommandStatus", HcCommandStatus_r, HcCommandStatus_w }, /* 2 */ 4746 { "HcInterruptStatus", HcInterruptStatus_r, HcInterruptStatus_w }, /* 3 */ 4747 { "HcInterruptEnable", HcInterruptEnable_r, HcInterruptEnable_w }, /* 4 */ 4748 { "HcInterruptDisable", HcInterruptDisable_r, HcInterruptDisable_w }, /* 5 */ 4749 { "HcHCCA", HcHCCA_r, HcHCCA_w }, /* 6 */ 4750 { "HcPeriodCurrentED", HcPeriodCurrentED_r, HcPeriodCurrentED_w }, /* 7 */ 4751 { "HcControlHeadED", HcControlHeadED_r, HcControlHeadED_w }, /* 8 */ 4752 { "HcControlCurrentED", HcControlCurrentED_r, HcControlCurrentED_w }, /* 9 */ 4753 { "HcBulkHeadED", HcBulkHeadED_r, HcBulkHeadED_w }, /* 10 */ 4754 { "HcBulkCurrentED", HcBulkCurrentED_r, HcBulkCurrentED_w }, /* 11 */ 4755 { "HcDoneHead", HcDoneHead_r, HcDoneHead_w }, /* 12 */ 4756 { "HcFmInterval", HcFmInterval_r, HcFmInterval_w }, /* 13 */ 4757 { "HcFmRemaining", HcFmRemaining_r, HcFmRemaining_w }, /* 14 */ 4758 { "HcFmNumber", HcFmNumber_r, HcFmNumber_w }, /* 15 */ 4759 { "HcPeriodicStart", HcPeriodicStart_r, HcPeriodicStart_w }, /* 16 */ 4760 { "HcLSThreshold", HcLSThreshold_r, HcLSThreshold_w }, /* 17 */ 4761 { "HcRhDescriptorA", HcRhDescriptorA_r, HcRhDescriptorA_w }, /* 18 */ 4762 { "HcRhDescriptorB", HcRhDescriptorB_r, HcRhDescriptorB_w }, /* 19 */ 4763 { "HcRhStatus", HcRhStatus_r, HcRhStatus_w }, /* 20 */ 4764 4764 4765 4765 /* The number of port status register depends on the definition 4766 4766 * of OHCI_NDP macro 4767 4767 */ 4768 { "HcRhPortStatus[0]", HcRhPortStatus_r, HcRhPortStatus_w},4769 { "HcRhPortStatus[1]", HcRhPortStatus_r, HcRhPortStatus_w},4770 { "HcRhPortStatus[2]", HcRhPortStatus_r, HcRhPortStatus_w},4771 { "HcRhPortStatus[3]", HcRhPortStatus_r, HcRhPortStatus_w},4772 { "HcRhPortStatus[4]", HcRhPortStatus_r, HcRhPortStatus_w},4773 { "HcRhPortStatus[5]", HcRhPortStatus_r, HcRhPortStatus_w},4774 { "HcRhPortStatus[6]", HcRhPortStatus_r, HcRhPortStatus_w},4775 { "HcRhPortStatus[7]", HcRhPortStatus_r, HcRhPortStatus_w},4768 { "HcRhPortStatus[0]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 21 */ 4769 { "HcRhPortStatus[1]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 22 */ 4770 { "HcRhPortStatus[2]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 23 */ 4771 { "HcRhPortStatus[3]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 24 */ 4772 { "HcRhPortStatus[4]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 25 */ 4773 { "HcRhPortStatus[5]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 26 */ 4774 { "HcRhPortStatus[6]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 27 */ 4775 { "HcRhPortStatus[7]", HcRhPortStatus_r, HcRhPortStatus_w }, /* 28 */ 4776 4776 }; 4777 4777 -
trunk/src/VBox/Devices/USB/testcase/tstOhciRegisterAccess.cpp
r39142 r39149 38 38 static const char * const g_apszRegNms[] = 39 39 { 40 "HcRevision", 41 "HcControl", 42 "HcCommandStatus", 43 "HcInterruptStatus", 44 "HcInterruptEnable", 45 "HcInterruptDisable", 46 "HcHCCA", 47 "HcPeriodCurrentED", 48 "HcControlHeadED", 49 "HcControlCurrentED", 50 "HcBulkHeadED", 51 "HcBulkCurrentED", 52 "HcDoneHead", 53 "HcFmInterval", 54 55 "HcFmRemaining", 56 "HcFmNumber", 57 "HcPeriodicStart", 58 "HcLSThreshold", 59 "HcRhDescriptorA", 60 "HcRhDescriptorB", 61 "HcRhStatus", 40 /* 00 */ "HcRevision", 41 /* 01 */ "HcControl", 42 /* 02 */ "HcCommandStatus", 43 /* 03 */ "HcInterruptStatus", 44 /* 04 */ "HcInterruptEnable", 45 /* 05 */ "HcInterruptDisable", 46 /* 06 */ "HcHCCA", 47 /* 07 */ "HcPeriodCurrentED", 48 /* 08 */ "HcControlHeadED", 49 /* 09 */ "HcControlCurrentED", 50 /* 10 */ "HcBulkHeadED", 51 /* 11 */ "HcBulkCurrentED", 52 /* 12 */ "HcDoneHead", 53 /* 13 */ "HcFmInterval", 54 /* 14 */ "HcFmRemaining", 55 /* 15 */ "HcFmNumber", 56 /* 16 */ "HcPeriodicStart", 57 /* 17 */ "HcLSThreshold", 58 /* 18 */ "HcRhDescriptorA", 59 /* 19 */ "HcRhDescriptorB", 60 /* 20 */ "HcRhStatus", 62 61 /* Variable number of root hub ports: */ 63 "HcRhPortStatus[0]",64 "HcRhPortStatus[1]",65 "HcRhPortStatus[2]",66 "HcRhPortStatus[3]",67 "HcRhPortStatus[4]",68 "HcRhPortStatus[5]",69 "HcRhPortStatus[6]",70 "HcRhPortStatus[7]"62 /* 21 */ "HcRhPortStatus[0]", 63 /* 22 */ "HcRhPortStatus[1]", 64 /* 23 */ "HcRhPortStatus[2]", 65 /* 24 */ "HcRhPortStatus[3]", 66 /* 25 */ "HcRhPortStatus[4]", 67 /* 26 */ "HcRhPortStatus[5]", 68 /* 27 */ "HcRhPortStatus[6]", 69 /* 28 */ "HcRhPortStatus[7]" 71 70 }; 71 72 72 73 73 static bool TestOhciWrites(RTVPTRUNION uPtr) … … 80 80 } const s_aRegs[] = 81 81 { 82 { 13 /* HcFmInterval */, 0x58871120, 0 } 82 { 4 /* HcInterruptEnable */, 0x3fffff80, 0x3e555580 }, 83 { 5 /* HcInterruptDisable */, 0xffffffff, 0x59575351 }, 84 #if 0 /* deadly when missing bytes are taken as zero. */ 85 { 13 /* HcFmInterval */, 0x58871120, 0x01010101 }, 86 #endif 87 { 16 /* HcPeriodicStart */, 0x01020304, 0x02010403 }, 83 88 }; 84 89 … … 159 164 { 160 165 LogRel(("TestOhciWrites: Error! Register %s failed: %s; uInitialValue=%08RX32 uChangedValue=%08RX32 u32A=%08RX32\n", 166 g_apszRegNms[iReg], pszError, uInitialValue, uChangedValue, u32A)); 167 fSuccess = false; 168 } 169 } 170 171 return fSuccess; 172 } 173 174 175 static bool TestOhciReadOnly(RTVPTRUNION uPtr) 176 { 177 static struct 178 { 179 unsigned iReg; 180 uint32_t cValues; 181 uint32_t auValues[8]; 182 } const s_aRegs[] = 183 { 184 { 0 /* HcRevision */, 8, { 0, UINT32_MAX, 0x10100110, 0x200, 0x111, 0x11f, 0xf110, 0x0f10 } }, 185 { 12 /* HcDoneHead */, 3, { 0, UINT32_MAX, 0x55555555, 0, 0, 0, 0, 0 } }, 186 { 14 /* HcFmRemaining */, 3, { 0, UINT32_MAX, 0x55555555, 0, 0, 0, 0, 0 } }, 187 { 15 /* HcFmNumber */, 5, { 0, UINT32_MAX, 0x55555555, 0x7899, 0x00012222, 0, 0, 0 } }, 188 #if 0 /* HCD can write this */ 189 { 17 /* HcLSThreshold */, 5, { 0x627, 0x628, 0x629, 0x666, 0x599, 0, 0, 0 } } /* ??? */ 190 #endif 191 }; 192 193 bool fSuccess = true; 194 for (unsigned i = 0; i < RT_ELEMENTS(s_aRegs); i++) 195 { 196 uint32_t const iReg = s_aRegs[i].iReg; 197 RTVPTRUNION uPtrReg; 198 uPtrReg.pu32 = &uPtr.pu32[iReg]; 199 200 uint32_t uInitialValue = *uPtrReg.pu32; 201 LogRel(("TestOhciReadOnly: %p iReg=%2d %20s = %08RX32\n", uPtrReg.pv, iReg, g_apszRegNms[iReg], uInitialValue)); 202 203 bool fTryAgain = true; 204 const char *pszError = NULL; 205 uint32_t uChangedValue = 0; 206 uint32_t u32A = 0; 207 208 for (uint32_t iTry = 0; fTryAgain && iTry < 1024; iTry++) 209 { 210 pszError = NULL; 211 fTryAgain = false; 212 u32A = 0; 213 uChangedValue = 0; 214 215 RTCCUINTREG const fFlags = ASMIntDisableFlags(); 216 uInitialValue = *uPtrReg.pu32; 217 218 /* 219 * Try aligned dword, word and byte writes for now. 220 */ 221 for (unsigned iValue = 0; iValue < s_aRegs[i].cValues && !pszError && !fTryAgain; iValue++) 222 { 223 uChangedValue = s_aRegs[i].auValues[iValue]; 224 if (uInitialValue == uChangedValue) 225 continue; 226 227 /* dword */ 228 if ((fTryAgain = (*uPtrReg.pu32 != uInitialValue))) 229 break; 230 231 *uPtrReg.pu32 = uChangedValue; 232 u32A = *uPtrReg.pu32; 233 *uPtrReg.pu32 = uInitialValue; 234 if (u32A != uInitialValue) 235 pszError = "dword access"; 236 else 237 { 238 u32A = *uPtrReg.pu32; 239 if (u32A != uInitialValue) 240 pszError = "Restore error 1"; 241 } 242 243 /* word */ 244 for (unsigned iWord = 0; iWord < 2 && !pszError && !fTryAgain; iWord++) 245 { 246 if ((fTryAgain = (*uPtrReg.pu32 != uInitialValue))) 247 break; 248 uPtrReg.pu16[iWord] = (uint16_t)(uChangedValue >> iWord * 16); 249 u32A = *uPtrReg.pu32; 250 *uPtrReg.pu32 = uInitialValue; 251 if (u32A != uInitialValue) 252 pszError = iWord == 0 ? "aligned word 0 access" : "aligned word 1 access"; 253 else 254 { 255 u32A = *uPtrReg.pu32; 256 if (u32A != uInitialValue) 257 pszError = "Restore error 2"; 258 } 259 } 260 261 /* byte */ 262 for (unsigned iByte = 0; iByte < 4 && !pszError && !fTryAgain; iByte++) 263 { 264 if ((fTryAgain = (*uPtrReg.pu32 != uInitialValue))) 265 break; 266 uPtrReg.pu8[iByte] = (uint8_t)(uChangedValue >> iByte * 8); 267 u32A = *uPtrReg.pu32; 268 *uPtrReg.pu32 = uInitialValue; 269 if (u32A != uInitialValue) 270 { 271 static const char * const s_apsz[] = { "byte 0", "byte 1", "byte 2", "byte 3" }; 272 pszError = s_apsz[iByte]; 273 } 274 else 275 { 276 u32A = *uPtrReg.pu32; 277 if (u32A != uInitialValue) 278 pszError = "Restore error 3"; 279 } 280 } 281 } 282 283 ASMSetFlags(fFlags); 284 ASMNopPause(); 285 } 286 287 /* 288 * Complain on failure. 289 */ 290 if (fTryAgain) 291 LogRel(("TestOhciReadOnly: Warning! Register %s was never stable enough for testing! %08RX32 %08RX32 %08RX32\n", 292 g_apszRegNms[iReg], uInitialValue, u32A, uChangedValue, uInitialValue)); 293 else if (pszError) 294 { 295 LogRel(("TestOhciReadOnly: Error! Register %s failed: %s; uInitialValue=%08RX32 uChangedValue=%08RX32 u32A=%08RX32\n", 161 296 g_apszRegNms[iReg], pszError, uInitialValue, uChangedValue, u32A)); 162 297 fSuccess = false; … … 365 500 */ 366 501 bool fSuccess = TestOhciReads(uPtr); 502 if (fSuccess) 503 fSuccess = TestOhciReadOnly(uPtr); 367 504 if (fSuccess) 368 505 fSuccess = TestOhciWrites(uPtr);
Note:
See TracChangeset
for help on using the changeset viewer.