Changeset 39111 in vbox for trunk/src/VBox
- Timestamp:
- Oct 25, 2011 2:47:02 PM (13 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r39078 r39111 76 76 77 77 /** 78 * Deals with complicated MMIO writes. 79 * 80 * Complicatd means unaligned or non-dword/qword align accesses depending on 81 * the MMIO region's access mode flags. 82 * 83 * @returns Strict VBox status code. Any EM scheduling status code, 84 * VINF_IOM_HC_MMIO_WRITE, VINF_IOM_HC_MMIO_READ_WRITE or 85 * VINF_IOM_HC_MMIO_READ may be returned. 86 * 87 * @param pRange The range to write to. 88 * @param GCPhys The physical address to start writing. 89 * @param pvValue Where to store the value. 90 * @param cbValue The size of the value to write. 91 */ 92 static VBOXSTRICTRC iomMMIODoComplicatedWrite(PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void const *pvValue, unsigned cbValue) 93 { 94 AssertReturn( (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) != IOMMMIO_FLAGS_WRITE_PASSTHRU 95 || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) <= IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING, 96 VERR_INTERNAL_ERROR_5); 97 AssertReturn(cbValue != 0 && cbValue <= 16, VERR_INTERNAL_ERROR_4); 98 RTGCPHYS const GCPhysStart = GCPhys; NOREF(GCPhysStart); 99 bool const fReadMissing = (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) >= IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING; 100 101 /* 102 * Split and conquer. 103 */ 104 int rc = VINF_SUCCESS; 105 for (;;) 106 { 107 unsigned const offAccess = GCPhys & 3; 108 unsigned cbThisPart = 4 - offAccess; 109 if (cbThisPart > cbValue) 110 cbThisPart = cbValue; 111 112 /* 113 * Get the missing bits (if any). 114 */ 115 uint32_t u32MissingValue = 0; 116 if (fReadMissing && cbThisPart != 4) 117 { 118 int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 119 GCPhys & ~(RTGCPHYS)3, &u32MissingValue, sizeof(u32MissingValue)); 120 switch (rc2) 121 { 122 case VINF_SUCCESS: 123 break; 124 case VINF_IOM_MMIO_UNUSED_FF: 125 u32MissingValue = UINT32_C(0xffffffff); 126 break; 127 case VINF_IOM_MMIO_UNUSED_00: 128 u32MissingValue = 0; 129 break; 130 case VINF_IOM_HC_MMIO_READ: 131 case VINF_IOM_HC_MMIO_READ_WRITE: 132 case VINF_IOM_HC_MMIO_WRITE: 133 /** @todo What if we've split a transfer and already read 134 * something? Since reads can have sideeffects we could be 135 * kind of screwed here... */ 136 LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2)); 137 return rc2; 138 default: 139 if (RT_FAILURE(rc2)) 140 { 141 Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2)); 142 return rc2; 143 } 144 AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS); 145 if (rc == VINF_SUCCESS || rc2 < rc) 146 rc = rc2; 147 break; 148 } 149 } 150 151 /* 152 * Merge missing and given bits. 153 */ 154 uint32_t u32GivenMask; 155 uint32_t u32GivenValue; 156 switch (cbThisPart) 157 { 158 case 1: 159 u32GivenValue = *(uint8_t const *)pvValue; 160 u32GivenMask = UINT32_C(0x000000ff); 161 break; 162 case 2: 163 u32GivenValue = *(uint16_t const *)pvValue; 164 u32GivenMask = UINT32_C(0x0000ffff); 165 break; 166 case 3: 167 u32GivenValue = RT_MAKE_U32_FROM_U8(((uint8_t const *)pvValue)[0], ((uint8_t const *)pvValue)[1], 168 ((uint8_t const *)pvValue)[2], 0); 169 u32GivenMask = UINT32_C(0x00ffffff); 170 break; 171 case 4: 172 u32GivenValue = *(uint32_t const *)pvValue; 173 u32GivenMask = UINT32_C(0xffffffff); 174 break; 175 default: 176 AssertFailedReturn(VERR_INTERNAL_ERROR_3); 177 } 178 if (offAccess) 179 { 180 u32GivenValue <<= offAccess * 8; 181 u32GivenMask <<= offAccess * 8; 182 } 183 184 uint32_t u32Value = (u32MissingValue & ~u32GivenMask) 185 | (u32GivenValue & u32GivenMask); 186 187 /* 188 * Do DWORD write to the device. 189 */ 190 int rc2 = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 191 GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value)); 192 switch (rc2) 193 { 194 case VINF_SUCCESS: 195 break; 196 case VINF_IOM_HC_MMIO_READ: 197 case VINF_IOM_HC_MMIO_READ_WRITE: 198 case VINF_IOM_HC_MMIO_WRITE: 199 /** @todo What if we've split a transfer and already read 200 * something? Since reads can have sideeffects we could be 201 * kind of screwed here... */ 202 LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2)); 203 return rc2; 204 default: 205 if (RT_FAILURE(rc2)) 206 { 207 Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2)); 208 return rc2; 209 } 210 AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS); 211 if (rc == VINF_SUCCESS || rc2 < rc) 212 rc = rc2; 213 break; 214 } 215 216 /* 217 * Advance. 218 */ 219 cbValue -= cbThisPart; 220 if (!cbValue) 221 break; 222 GCPhys += cbThisPart; 223 pvValue = (uint8_t const *)pvValue + cbThisPart; 224 } 225 226 return rc; 227 } 228 229 230 231 232 /** 78 233 * Wrapper which does the write and updates range statistics when such are enabled. 79 234 * @warning RT_SUCCESS(rc=VINF_IOM_HC_MMIO_WRITE) is TRUE! … … 87 242 88 243 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a); 89 intrc;244 VBOXSTRICTRC rc; 90 245 if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback))) 91 rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 92 GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */ 246 { 247 if ( (cb == 4 && !(GCPhysFault & 3)) 248 || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_PASSTHRU 249 || (cb == 8 && !(GCPhysFault & 7)) ) 250 rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 251 GCPhysFault, (void *)pvData, cb); /** @todo fix const!! */ 252 else 253 rc = iomMMIODoComplicatedWrite(pRange, GCPhysFault, pvData, cb); 254 } 93 255 else 94 256 rc = VINF_SUCCESS; 95 257 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a); 96 258 STAM_COUNTER_INC(&pStats->Accesses); 259 return VBOXSTRICTRC_TODO(rc); 260 } 261 262 263 /** 264 * Deals with complicated MMIO reads. 265 * 266 * Complicatd means unaligned or non-dword/qword align accesses depending on 267 * the MMIO region's access mode flags. 268 * 269 * @returns Strict VBox status code. Any EM scheduling status code, 270 * VINF_IOM_HC_MMIO_READ, VINF_IOM_HC_MMIO_READ_WRITE or 271 * VINF_IOM_HC_MMIO_WRITE may be returned. 272 * 273 * @param pRange The range to read from. 274 * @param GCPhys The physical address to start reading. 275 * @param pvValue Where to store the value. 276 * @param cbValue The size of the value to read. 277 */ 278 static VBOXSTRICTRC iomMMIODoComplicatedRead(PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue) 279 { 280 AssertReturn( (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD 281 || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD_QWORD, 282 VERR_INTERNAL_ERROR_5); 283 AssertReturn(cbValue != 0 && cbValue <= 16, VERR_INTERNAL_ERROR_4); 284 RTGCPHYS const GCPhysStart = GCPhys; NOREF(GCPhysStart); 285 286 /* 287 * Split and conquer. 288 */ 289 int rc = VINF_SUCCESS; 290 for (;;) 291 { 292 /* 293 * Do DWORD read from the device. 294 */ 295 uint32_t u32Value; 296 int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 297 GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value)); 298 switch (rc2) 299 { 300 case VINF_SUCCESS: 301 break; 302 case VINF_IOM_MMIO_UNUSED_FF: 303 u32Value = UINT32_C(0xffffffff); 304 break; 305 case VINF_IOM_MMIO_UNUSED_00: 306 u32Value = 0; 307 break; 308 case VINF_IOM_HC_MMIO_READ: 309 case VINF_IOM_HC_MMIO_READ_WRITE: 310 case VINF_IOM_HC_MMIO_WRITE: 311 /** @todo What if we've split a transfer and already read 312 * something? Since reads can have sideeffects we could be 313 * kind of screwed here... */ 314 LogFlow(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2)); 315 return rc2; 316 default: 317 if (RT_FAILURE(rc2)) 318 { 319 Log(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2)); 320 return rc2; 321 } 322 AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS); 323 if (rc == VINF_SUCCESS || rc2 < rc) 324 rc = rc2; 325 break; 326 } 327 u32Value >>= (GCPhys & 3) * 8; 328 329 /* 330 * Write what we've read. 331 */ 332 unsigned cbThisPart = 4 - (GCPhys & 3); 333 if (cbThisPart > cbValue) 334 cbThisPart = cbValue; 335 336 switch (cbThisPart) 337 { 338 case 1: 339 *(uint8_t *)pvValue = (uint8_t)u32Value; 340 break; 341 case 2: 342 *(uint16_t *)pvValue = (uint16_t)u32Value; 343 break; 344 case 3: 345 ((uint8_t *)pvValue)[0] = RT_BYTE1(u32Value); 346 ((uint8_t *)pvValue)[1] = RT_BYTE2(u32Value); 347 ((uint8_t *)pvValue)[2] = RT_BYTE3(u32Value); 348 break; 349 case 4: 350 *(uint32_t *)pvValue = u32Value; 351 break; 352 } 353 354 /* 355 * Advance. 356 */ 357 cbValue -= cbThisPart; 358 if (!cbValue) 359 break; 360 GCPhys += cbThisPart; 361 pvValue = (uint8_t *)pvValue + cbThisPart; 362 } 363 97 364 return rc; 365 } 366 367 368 /** 369 * Implements VINF_IOM_MMIO_UNUSED_FF. 370 * 371 * @returns VINF_SUCCESS. 372 * @param pvValue Where to store the zeros. 373 * @param cbValue How many bytes to read. 374 */ 375 static int iomMMIODoReadFFs(void *pvValue, unsigned cbValue) 376 { 377 switch (cbValue) 378 { 379 case 1: *(uint8_t *)pvValue = UINT8_C(0xff); break; 380 case 2: *(uint16_t *)pvValue = UINT16_C(0xffff); break; 381 case 4: *(uint32_t *)pvValue = UINT32_C(0xffffffff); break; 382 case 8: *(uint64_t *)pvValue = UINT64_C(0xffffffffffffffff); break; 383 default: 384 { 385 uint8_t *pb = (uint8_t *)pvValue; 386 while (cbValue--) 387 *pb++ = UINT8_C(0xff); 388 break; 389 } 390 } 391 return VINF_SUCCESS; 392 } 393 394 395 /** 396 * Implements VINF_IOM_MMIO_UNUSED_00. 397 * 398 * @returns VINF_SUCCESS. 399 * @param pvValue Where to store the zeros. 400 * @param cbValue How many bytes to read. 401 */ 402 static int iomMMIODoRead00s(void *pvValue, unsigned cbValue) 403 { 404 switch (cbValue) 405 { 406 case 1: *(uint8_t *)pvValue = UINT8_C(0x00); break; 407 case 2: *(uint16_t *)pvValue = UINT16_C(0x0000); break; 408 case 4: *(uint32_t *)pvValue = UINT32_C(0x00000000); break; 409 case 8: *(uint64_t *)pvValue = UINT64_C(0x0000000000000000); break; 410 default: 411 { 412 uint8_t *pb = (uint8_t *)pvValue; 413 while (cbValue--) 414 *pb++ = UINT8_C(0x00); 415 break; 416 } 417 } 418 return VINF_SUCCESS; 98 419 } 99 420 … … 107 428 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, GCPhys, pRange); 108 429 Assert(pStats); 109 #endif110 111 430 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); 112 int rc; 431 #endif 432 433 VBOXSTRICTRC rc; 113 434 if (RT_LIKELY(pRange->CTX_SUFF(pfnReadCallback))) 114 rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pvValue, cbValue); 435 { 436 if ( (cbValue == 4 && !(GCPhys & 3)) 437 || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_PASSTHRU 438 || (cbValue == 8 && !(GCPhys & 7)) ) 439 rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pvValue, cbValue); 440 else 441 rc = iomMMIODoComplicatedRead(pRange, GCPhys, pvValue, cbValue); 442 } 115 443 else 116 444 rc = VINF_IOM_MMIO_UNUSED_FF; 117 445 if (rc != VINF_SUCCESS) 118 446 { 119 switch (rc) 120 { 121 case VINF_IOM_MMIO_UNUSED_FF: 122 switch (cbValue) 123 { 124 case 1: *(uint8_t *)pvValue = UINT8_C(0xff); break; 125 case 2: *(uint16_t *)pvValue = UINT16_C(0xffff); break; 126 case 4: *(uint32_t *)pvValue = UINT32_C(0xffffffff); break; 127 case 8: *(uint64_t *)pvValue = UINT64_C(0xffffffffffffffff); break; 128 default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break; 129 } 130 rc = VINF_SUCCESS; 131 break; 132 133 case VINF_IOM_MMIO_UNUSED_00: 134 switch (cbValue) 135 { 136 case 1: *(uint8_t *)pvValue = UINT8_C(0x00); break; 137 case 2: *(uint16_t *)pvValue = UINT16_C(0x0000); break; 138 case 4: *(uint32_t *)pvValue = UINT32_C(0x00000000); break; 139 case 8: *(uint64_t *)pvValue = UINT64_C(0x0000000000000000); break; 140 default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break; 141 } 142 rc = VINF_SUCCESS; 143 break; 447 switch (VBOXSTRICTRC_VAL(rc)) 448 { 449 case VINF_IOM_MMIO_UNUSED_FF: rc = iomMMIODoReadFFs(pvValue, cbValue); break; 450 case VINF_IOM_MMIO_UNUSED_00: rc = iomMMIODoRead00s(pvValue, cbValue); break; 144 451 } 145 452 } 146 453 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a); 147 454 STAM_COUNTER_INC(&pStats->Accesses); 148 return rc;455 return VBOXSTRICTRC_VAL(rc); 149 456 } 150 457 … … 1438 1745 { 1439 1746 /* Take the IOM lock before performing any MMIO. */ 1440 intrc = IOM_LOCK(pVM);1747 VBOXSTRICTRC rc = IOM_LOCK(pVM); 1441 1748 #ifndef IN_RING3 1442 1749 if (rc == VERR_SEM_BUSY) 1443 1750 return VINF_IOM_HC_MMIO_WRITE; 1444 1751 #endif 1445 AssertRC( rc);1752 AssertRC(VBOXSTRICTRC_VAL(rc)); 1446 1753 #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3) 1447 1754 IEMNotifyMMIORead(pVM, GCPhys, cbValue); … … 1491 1798 */ 1492 1799 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); 1493 rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, pu32Value, (unsigned)cbValue); 1800 if ( (cbValue == 4 && !(GCPhys & 3)) 1801 || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_PASSTHRU 1802 || (cbValue == 8 && !(GCPhys & 7)) ) 1803 rc = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), GCPhys, 1804 pu32Value, (unsigned)cbValue); 1805 else 1806 rc = iomMMIODoComplicatedRead(pRange, GCPhys, pu32Value, (unsigned)cbValue); 1494 1807 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a); 1495 switch ( rc)1808 switch (VBOXSTRICTRC_VAL(rc)) 1496 1809 { 1497 1810 case VINF_SUCCESS: … … 1506 1819 #endif 1507 1820 default: 1508 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc));1821 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1509 1822 iomMmioReleaseRange(pVM, pRange); 1510 1823 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); … … 1512 1825 1513 1826 case VINF_IOM_MMIO_UNUSED_00: 1514 switch (cbValue) 1515 { 1516 case 1: *(uint8_t *)pu32Value = UINT8_C(0x00); break; 1517 case 2: *(uint16_t *)pu32Value = UINT16_C(0x0000); break; 1518 case 4: *(uint32_t *)pu32Value = UINT32_C(0x00000000); break; 1519 case 8: *(uint64_t *)pu32Value = UINT64_C(0x0000000000000000); break; 1520 default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break; 1521 } 1522 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc)); 1827 iomMMIODoRead00s(pu32Value, cbValue); 1828 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1523 1829 iomMmioReleaseRange(pVM, pRange); 1524 1830 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); … … 1526 1832 1527 1833 case VINF_IOM_MMIO_UNUSED_FF: 1528 switch (cbValue) 1529 { 1530 case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break; 1531 case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break; 1532 case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break; 1533 case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break; 1534 default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break; 1535 } 1536 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, rc)); 1834 iomMMIODoReadFFs(pu32Value, cbValue); 1835 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1537 1836 iomMmioReleaseRange(pVM, pRange); 1538 1837 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); … … 1555 1854 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); /** @todo STAM_PROFILE_ADD_ZERO_PERIOD */ 1556 1855 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a); 1557 switch (cbValue) 1558 { 1559 case 1: *(uint8_t *)pu32Value = UINT8_C(0xff); break; 1560 case 2: *(uint16_t *)pu32Value = UINT16_C(0xffff); break; 1561 case 4: *(uint32_t *)pu32Value = UINT32_C(0xffffffff); break; 1562 case 8: *(uint64_t *)pu32Value = UINT64_C(0xffffffffffffffff); break; 1563 default: AssertReleaseMsgFailed(("cbValue=%d GCPhys=%RGp\n", cbValue, GCPhys)); break; 1564 } 1856 iomMMIODoReadFFs(pu32Value, cbValue); 1565 1857 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue)); 1566 1858 IOM_UNLOCK(pVM); … … 1582 1874 { 1583 1875 /* Take the IOM lock before performing any MMIO. */ 1584 intrc = IOM_LOCK(pVM);1876 VBOXSTRICTRC rc = IOM_LOCK(pVM); 1585 1877 #ifndef IN_RING3 1586 1878 if (rc == VERR_SEM_BUSY) 1587 1879 return VINF_IOM_HC_MMIO_WRITE; 1588 1880 #endif 1589 AssertRC( rc);1881 AssertRC(VBOXSTRICTRC_VAL(rc)); 1590 1882 #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3) 1591 1883 IEMNotifyMMIOWrite(pVM, GCPhys, u32Value, cbValue); … … 1635 1927 */ 1636 1928 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a); 1637 rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 1638 GCPhys, &u32Value, (unsigned)cbValue); 1929 if ( (cbValue == 4 && !(GCPhys & 3)) 1930 || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_PASSTHRU 1931 || (cbValue == 8 && !(GCPhys & 7)) ) 1932 rc = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser), 1933 GCPhys, &u32Value, (unsigned)cbValue); 1934 else 1935 rc = iomMMIODoComplicatedWrite(pRange, GCPhys, &u32Value, (unsigned)cbValue); 1639 1936 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a); 1640 1937 #ifndef IN_RING3 … … 1643 1940 STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3)); 1644 1941 #endif 1645 Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, rc));1942 Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1646 1943 iomMmioReleaseRange(pVM, pRange); 1647 1944 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); -
trunk/src/VBox/VMM/VMMR3/IOM.cpp
r39078 r39111 140 140 * @param pVM The VM to operate on. 141 141 */ 142 VMMR3 DECL(int) IOMR3Init(PVM pVM)142 VMMR3_INT_DECL(int) IOMR3Init(PVM pVM) 143 143 { 144 144 LogFlow(("IOMR3Init:\n")); … … 262 262 * @param pVM VM handle. 263 263 */ 264 VMMR3 DECL(void) IOMR3Reset(PVM pVM)264 VMMR3_INT_DECL(void) IOMR3Reset(PVM pVM) 265 265 { 266 266 iomR3FlushCache(pVM); … … 278 278 * @param offDelta Relocation delta relative to old location. 279 279 */ 280 VMMR3 DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta)280 VMMR3_INT_DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta) 281 281 { 282 282 LogFlow(("IOMR3Relocate: offDelta=%d\n", offDelta)); … … 376 376 * @param pVM The VM to operate on. 377 377 */ 378 VMMR3 DECL(int) IOMR3Term(PVM pVM)378 VMMR3_INT_DECL(int) IOMR3Term(PVM pVM) 379 379 { 380 380 /* … … 509 509 * @param pszDesc Pointer to description string. This must not be freed. 510 510 */ 511 VMMR3 DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser,512 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,513 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc)511 VMMR3_INT_DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser, 512 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback, 513 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc) 514 514 { 515 515 LogFlow(("IOMR3IOPortRegisterR3: pDevIns=%p PortStart=%#x cPorts=%#x pvUser=%RHv pfnOutCallback=%#x pfnInCallback=%#x pfnOutStrCallback=%#x pfnInStrCallback=%#x pszDesc=%s\n", … … 607 607 * @param pszDesc Pointer to description string. This must not be freed. 608 608 */ 609 VMMR3 DECL(int)IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTRCPTR pvUser,610 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback,611 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc)609 VMMR3_INT_DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTRCPTR pvUser, 610 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback, 611 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc) 612 612 { 613 613 LogFlow(("IOMR3IOPortRegisterRC: pDevIns=%p PortStart=%#x cPorts=%#x pvUser=%RRv pfnOutCallback=%RRv pfnInCallback=%RRv pfnOutStrCallback=%RRv pfnInStrCallback=%RRv pszDesc=%s\n", … … 721 721 * @param pszDesc Pointer to description string. This must not be freed. 722 722 */ 723 VMMR3 DECL(int)IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTR0PTR pvUser,724 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,725 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,726 const char *pszDesc)723 VMMR3_INT_DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTR0PTR pvUser, 724 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback, 725 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, 726 const char *pszDesc) 727 727 { 728 728 LogFlow(("IOMR3IOPortRegisterR0: pDevIns=%p PortStart=%#x cPorts=%#x pvUser=%RHv pfnOutCallback=%RHv pfnInCallback=%RHv pfnOutStrCallback=%RHv pfnInStrCallback=%RHv pszDesc=%s\n", … … 834 834 * all the checks you might expect it to do. 835 835 */ 836 VMMR3 DECL(int)IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts)836 VMMR3_INT_DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts) 837 837 { 838 838 LogFlow(("IOMR3IOPortDeregister: pDevIns=%p PortStart=%#x cPorts=%#x\n", pDevIns, PortStart, cPorts)); … … 1404 1404 */ 1405 1405 VMMR3_INT_DECL(int) 1406 IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINTcbRange, RTHCPTR pvUser,1406 IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser, 1407 1407 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, 1408 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc)1409 { 1410 LogFlow(("IOMR3MmioRegisterR3: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x pszDesc=%s\n",1411 pDevIns, GCPhysStart, cbRange, pvUser, pfnWriteCallback, pfnReadCallback, pfnFillCallback, pszDesc));1408 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, uint32_t fFlags, const char *pszDesc) 1409 { 1410 LogFlow(("IOMR3MmioRegisterR3: pDevIns=%p GCPhysStart=%RGp cbRange=%#x pvUser=%RHv pfnWriteCallback=%#x pfnReadCallback=%#x pfnFillCallback=%#x fFlags=%#x pszDesc=%s\n", 1411 pDevIns, GCPhysStart, cbRange, pvUser, pfnWriteCallback, pfnReadCallback, pfnFillCallback, fFlags, pszDesc)); 1412 1412 int rc; 1413 1413 … … 1415 1415 * Validate input. 1416 1416 */ 1417 if (GCPhysStart + (cbRange - 1) < GCPhysStart) 1418 { 1419 AssertMsgFailed(("Wrapped! %RGp %#x bytes\n", GCPhysStart, cbRange)); 1420 return VERR_IOM_INVALID_MMIO_RANGE; 1421 } 1417 AssertMsgReturn(GCPhysStart + (cbRange - 1) >= GCPhysStart,("Wrapped! %RGp %#x bytes\n", GCPhysStart, cbRange), 1418 VERR_IOM_INVALID_MMIO_RANGE); 1419 AssertMsgReturn( !(fFlags & ~IOMMMIO_FLAGS_VALID_MASK) 1420 || (fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_MODE 1421 || (fFlags & IOMMMIO_FLAGS_WRITE_MODE) > IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING, 1422 ("%#x\n", fFlags), 1423 VERR_INVALID_PARAMETER); 1422 1424 1423 1425 /* … … 1431 1433 AssertLogRelRCReturn(rc, rc); 1432 1434 } 1433 1434 /*1435 * For the 2nd+ instance, mangle the description string so it's unique.1436 * (PGM requires this.)1437 */1438 if (pDevIns->iInstance > 0) /** @todo Move to PDMDevHlp.cpp and use a string cache. */1439 {1440 pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_IOM, "%s [%u]", pszDesc, pDevIns->iInstance);1441 if (!pszDesc)1442 return VERR_NO_MEMORY;1443 }1444 1445 1435 1446 1436 /* … … 1458 1448 pRange->pszDesc = pszDesc; 1459 1449 1450 //pRange->pvUserR0 = NIL_RTR0PTR; 1451 //pRange->pDevInsR0 = NIL_RTR0PTR; 1452 //pRange->pfnReadCallbackR0 = NIL_RTR0PTR; 1453 //pRange->pfnWriteCallbackR0 = NIL_RTR0PTR; 1454 //pRange->pfnFillCallbackR0 = NIL_RTR0PTR; 1455 1456 //pRange->pvUserRC = NIL_RTRCPTR; 1457 //pRange->pDevInsRC = NIL_RTRCPTR; 1458 //pRange->pfnReadCallbackRC = NIL_RTRCPTR; 1459 //pRange->pfnWriteCallbackRC = NIL_RTRCPTR; 1460 //pRange->pfnFillCallbackRC = NIL_RTRCPTR; 1461 1462 pRange->fFlags = fFlags; 1463 1460 1464 pRange->pvUserR3 = pvUser; 1461 1465 pRange->pDevInsR3 = pDevIns; … … 1463 1467 pRange->pfnWriteCallbackR3 = pfnWriteCallback; 1464 1468 pRange->pfnFillCallbackR3 = pfnFillCallback; 1465 1466 //pRange->pvUserR0 = NIL_RTR0PTR;1467 //pRange->pDevInsR0 = NIL_RTR0PTR;1468 //pRange->pfnReadCallbackR0 = NIL_RTR0PTR;1469 //pRange->pfnWriteCallbackR0 = NIL_RTR0PTR;1470 //pRange->pfnFillCallbackR0 = NIL_RTR0PTR;1471 1472 //pRange->pvUserRC = NIL_RTRCPTR;1473 //pRange->pDevInsRC = NIL_RTRCPTR;1474 //pRange->pfnReadCallbackRC = NIL_RTRCPTR;1475 //pRange->pfnWriteCallbackRC = NIL_RTRCPTR;1476 //pRange->pfnFillCallbackRC = NIL_RTRCPTR;1477 1469 1478 1470 /* … … 1529 1521 */ 1530 1522 VMMR3_INT_DECL(int) 1531 IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINTcbRange, RTGCPTR pvUser,1523 IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTGCPTR pvUser, 1532 1524 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, 1533 1525 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback) … … 1585 1577 */ 1586 1578 VMMR3_INT_DECL(int) 1587 IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINTcbRange, RTR0PTR pvUser,1579 IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser, 1588 1580 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, 1589 1581 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, … … 1638 1630 * all the checks you might expect it to do. 1639 1631 */ 1640 VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINTcbRange)1632 VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange) 1641 1633 { 1642 1634 LogFlow(("IOMR3MmioDeregister: pDevIns=%p GCPhysStart=%RGp cbRange=%#x\n", pDevIns, GCPhysStart, cbRange)); -
trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
r39078 r39111 262 262 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, 263 263 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, 264 const char *pszDesc) 265 { 266 PDMDEV_ASSERT_DEVINS(pDevIns); 267 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3); 268 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n", 269 pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc)); 270 271 /** @todo IOMR3MMIORegisterR3 mangles the description, move it here. */ 272 int rc = IOMR3MmioRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc); 264 uint32_t fFlags, const char *pszDesc) 265 { 266 PDMDEV_ASSERT_DEVINS(pDevIns); 267 PVM pVM = pDevIns->Internal.s.pVMR3; 268 VM_ASSERT_EMT(pVM); 269 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p fFlags=%#x pszDesc=%p:{%s}\n", 270 pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, fFlags, pszDesc)); 271 272 if (pDevIns->iInstance > 0) 273 { 274 char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance); 275 if (pszDesc2) 276 pszDesc = pszDesc2; 277 } 278 279 int rc = IOMR3MmioRegisterR3(pVM, pDevIns, GCPhysStart, cbRange, pvUser, 280 pfnWrite, pfnRead, pfnFill, fFlags, pszDesc); 273 281 274 282 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc)); -
trunk/src/VBox/VMM/include/IOMInternal.h
r37467 r39111 51 51 uint32_t volatile cRefs; 52 52 53 /** Pointer to user argument - R0. */ 54 RTR0PTR pvUserR0; 55 /** Pointer to device instance - R0. */ 56 PPDMDEVINSR0 pDevInsR0; 57 /** Pointer to write callback function - R0. */ 58 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0; 59 /** Pointer to read callback function - R0. */ 60 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0; 61 /** Pointer to fill (memset) callback function - R0. */ 62 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0; 63 64 /** Flags, see IOMMMIO_FLAGS_XXX. */ /* (Placed here for alignment reasons.) */ 65 uint32_t fFlags; 66 67 /** Pointer to user argument - RC. */ 68 RTRCPTR pvUserRC; 69 /** Pointer to device instance - RC. */ 70 PPDMDEVINSRC pDevInsRC; 71 /** Pointer to write callback function - RC. */ 72 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC; 73 /** Pointer to read callback function - RC. */ 74 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC; 75 /** Pointer to fill (memset) callback function - RC. */ 76 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC; 77 53 78 /** Pointer to user argument - R3. */ 54 79 RTR3PTR pvUserR3; … … 61 86 /** Pointer to fill (memset) callback function - R3. */ 62 87 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3; 63 64 /** Pointer to user argument - R0. */65 RTR0PTR pvUserR0;66 /** Pointer to device instance - R0. */67 PPDMDEVINSR0 pDevInsR0;68 /** Pointer to write callback function - R0. */69 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0;70 /** Pointer to read callback function - R0. */71 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0;72 /** Pointer to fill (memset) callback function - R0. */73 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0;74 75 /** Pointer to user argument - RC. */76 RTRCPTR pvUserRC;77 /** Pointer to device instance - RC. */78 PPDMDEVINSRC pDevInsRC;79 /** Pointer to write callback function - RC. */80 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC;81 /** Pointer to read callback function - RC. */82 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC;83 /** Pointer to fill (memset) callback function - RC. */84 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC;85 /** Alignment padding. */86 RTRCPTR RCPtrAlignment;87 88 88 89 /** Description / Name. For easing debugging. */ -
trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp
r38956 r39111 190 190 GEN_CHECK_OFF(IOMMMIORANGE, GCPhys); 191 191 GEN_CHECK_OFF(IOMMMIORANGE, cb); 192 GEN_CHECK_OFF(IOMMMIORANGE, cRefs); 193 GEN_CHECK_OFF(IOMMMIORANGE, fFlags); 192 194 GEN_CHECK_OFF(IOMMMIORANGE, pszDesc); 193 195 GEN_CHECK_OFF(IOMMMIORANGE, pvUserR3);
Note:
See TracChangeset
for help on using the changeset viewer.