- Timestamp:
- Mar 23, 2021 10:54:19 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143460
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r88225 r88257 45 45 * used as it asserts for correctness when compiling on certain compilers). */ 46 46 #define VTD_HI_U32(a) (uint32_t)((a) >> 32) 47 48 /** @def VTD_ASSERT_MMIO_ACCESS 49 * Asserts MMIO access' offset and size are valid or returns appropriate error 50 * code suitable for returning from MMIO access handlers. */ 51 #define VTD_ASSERT_MMIO_ACCESS_RET(a_off, a_cb) \ 52 do { \ 53 AssertReturn(!(off & 3), VINF_IOM_MMIO_UNUSED_FF); \ 54 AssertReturn(cb == 4 || cb == 8, VINF_IOM_MMIO_UNUSED_FF); \ 55 } while (0); 56 57 /** @def VTD_IS_MMIO_OFF_VALID 58 * Returns @c true if the MMIO offset is valid, or @c false otherwise. */ 59 #define VTD_IS_MMIO_OFF_VALID(a_off) ( (a_off) < VTD_MMIO_GROUP_0_OFF_END \ 60 || (a_off) - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE) 61 62 /** The number of fault recording registers our implementation supports. 63 * Normal guest operation shouldn't trigger faults anyway, so we only support the 64 * minimum number of registers (which is 1). 65 * 66 * See Intel VT-d spec. 10.4.2 "Capability Register" (CAP_REG::NFR). */ 67 #define VTD_FRCD_REG_COUNT UINT32_C(1) 68 69 /** Offset of first register in group 0. */ 70 #define VTD_MMIO_GROUP_0_OFF_FIRST VTD_MMIO_OFF_VER_REG 71 /** Offset of last register in group 0 (inclusive). */ 72 #define VTD_MMIO_GROUP_0_OFF_LAST VTD_MMIO_OFF_MTRR_PHYSMASK9_REG 73 /** Last valid offset in group 0 (exclusive). */ 74 #define VTD_MMIO_GROUP_0_OFF_END (VTD_MMIO_GROUP_0_OFF_LAST + 8 /* sizeof MTRR_PHYSMASK9_REG */) 75 /** Size of the group 0 (in bytes). */ 76 #define VTD_MMIO_GROUP_0_SIZE (VTD_MMIO_GROUP_0_OFF_END - VTD_MMIO_GROUP_0_OFF_FIRST) 77 78 #define VTD_MMIO_OFF_IVA_REG 0xe40 /**< Implementation-specific MMIO offset of IVA_REG. */ 79 #define VTD_MMIO_OFF_IOTLB_REG 0xe48 /**< Implementation-specific MMIO offset of IOTLB_REG. */ 80 #define VTD_MMIO_OFF_FRCD_LO_REG 0xe60 /**< Implementation-specific MMIO offset of FRCD_LO_REG. */ 81 #define VTD_MMIO_OFF_FRCD_HI_REG 0xe68 /**< Implementation-specific MMIO offset of FRCD_HI_REG. */ 82 AssertCompile(!(VTD_MMIO_OFF_FRCD_LO_REG & 0xf)); 83 84 /** Offset of first register in group 1. */ 85 #define VTD_MMIO_GROUP_1_OFF_FIRST VTD_MMIO_OFF_VCCAP_REG 86 /** Offset of last register in group 1 (inclusive). */ 87 #define VTD_MMIO_GROUP_1_OFF_LAST VTD_MMIO_OFF_FRCD_LO_REG + 8 * VTD_FRCD_REG_COUNT 88 /** Last valid offset in group 1 (exclusive). */ 89 #define VTD_MMIO_GROUP_1_OFF_END (VTD_MMIO_GROUP_1_OFF_LAST + 8 /* sizeof FRCD_HI_REG */) 90 /** Size of the group 1 (in bytes). */ 91 #define VTD_MMIO_GROUP_1_SIZE (VTD_MMIO_GROUP_1_OFF_END - VTD_MMIO_GROUP_1_OFF_FIRST) 47 92 48 93 /** Release log prefix string. */ … … 318 363 static const uint32_t g_au32RwMasks1[] = 319 364 { 320 /* Offset Register Low High */ 321 /* 0xe00 VCCAP_REG */ VTD_LO_U32(VTD_VCCAP_REG_RW_MASK), VTD_HI_U32(VTD_VCCAP_REG_RW_MASK), 322 /* 0xe08 Reserved */ 0, 0, 323 /* 0xe10 VCMD_REG */ 0, 0, /* RO as we don't support VCS. */ 324 /* 0xe18 Reserved */ 0, 0, 325 /* 0xe20 VCRSP_REG */ 0, 0, /* RO as we don't support VCS. */ 365 /* Offset Register Low High */ 366 /* 0xe00 VCCAP_REG */ VTD_LO_U32(VTD_VCCAP_REG_RW_MASK), VTD_HI_U32(VTD_VCCAP_REG_RW_MASK), 367 /* 0xe08 Reserved */ 0, 0, 368 /* 0xe10 VCMD_REG */ 0, 0, /* RO as we don't support VCS. */ 369 /* 0xe18 VCMDRSVD_REG */ 0, 0, 370 /* 0xe20 VCRSP_REG */ 0, 0, /* RO as we don't support VCS. */ 371 /* 0xe28 VCRSPRSVD_REG */ 0, 0, 372 /* 0xe30 Reserved */ 0, 0, 373 /* 0xe38 Reserved */ 0, 0, 374 /* 0xe40 IVA_REG */ VTD_LO_U32(VTD_IVA_REG_RW_MASK), VTD_HI_U32(VTD_IVA_REG_RW_MASK), 375 /* 0xe48 IOTLB_REG */ VTD_LO_U32(VTD_IOTLB_REG_RW_MASK), VTD_HI_U32(VTD_IOTLB_REG_RW_MASK), 376 /* 0xe50 Reserved */ 0, 0, 377 /* 0xe58 Reserved */ 0, 0, 378 /* 0xe60 FRCD_REG_LO */ VTD_LO_U32(VTD_FRCD_REG_LO_RW_MASK), VTD_HI_U32(VTD_FRCD_REG_LO_RW_MASK), 379 /* 0xe68 FRCD_REG_HI */ VTD_LO_U32(VTD_FRCD_REG_HI_RW_MASK), VTD_HI_U32(VTD_FRCD_REG_HI_RW_MASK), 326 380 }; 327 381 AssertCompile(sizeof(g_au32RwMasks1) == VTD_MMIO_GROUP_1_SIZE); 382 AssertCompile((VTD_MMIO_OFF_FRCD_LO_REG - VTD_MMIO_GROUP_1_OFF_FIRST) + VTD_FRCD_REG_COUNT * 2 * sizeof(uint64_t) ); 328 383 329 384 /** … … 332 387 static const uint32_t g_au32Rw1cMasks1[] = 333 388 { 334 /* Offset Register Low High */ 335 /* 0xe00 VCCAP_REG */ 0, 0, 336 /* 0xe08 Reserved */ 0, 0, 337 /* 0xe10 VCMD_REG */ 0, 0, 338 /* 0xe18 Reserved */ 0, 0, 339 /* 0xe20 VCRSP_REG */ 0, 0, 389 /* Offset Register Low High */ 390 /* 0xe00 VCCAP_REG */ 0, 0, 391 /* 0xe08 Reserved */ 0, 0, 392 /* 0xe10 VCMD_REG */ 0, 0, 393 /* 0xe18 VCMDRSVD_REG */ 0, 0, 394 /* 0xe20 VCRSP_REG */ 0, 0, 395 /* 0xe28 VCRSPRSVD_REG */ 0, 0, 396 /* 0xe30 Reserved */ 0, 0, 397 /* 0xe38 Reserved */ 0, 0, 398 /* 0xe40 IVA_REG */ 0, 0, 399 /* 0xe48 IOTLB_REG */ 0, 0, 400 /* 0xe50 Reserved */ 0, 0, 401 /* 0xe58 Reserved */ 0, 0, 402 /* 0xe60 FRCD_REG_LO */ VTD_LO_U32(VTD_FRCD_REG_LO_RW1C_MASK), VTD_HI_U32(VTD_FRCD_REG_LO_RW1C_MASK), 403 /* 0xe68 FRCD_REG_HI */ VTD_LO_U32(VTD_FRCD_REG_HI_RW1C_MASK), VTD_HI_U32(VTD_FRCD_REG_HI_RW1C_MASK), 340 404 }; 341 405 AssertCompile(sizeof(g_au32Rw1cMasks1) == VTD_MMIO_GROUP_1_SIZE); … … 356 420 * @param pThis The shared IOMMU device state. 357 421 * @param offReg The MMIO offset of the register. 358 * @param cbReg The size of the access being made (for bounds check).422 * @param cbReg The size of the access being made. 359 423 * @param pIdxGroup Where to store the index of the register group the register 360 424 * belongs to. … … 362 426 DECLINLINE(uint8_t *) iommuIntelRegGetGroup(PIOMMU pThis, uint16_t offReg, uint8_t cbReg, uint8_t *pIdxGroup) 363 427 { 428 uint16_t const offLast = offReg + cbReg - 1; 429 364 430 AssertCompile(VTD_MMIO_GROUP_0_OFF_FIRST == 0); 365 AssertMsg( off Reg + cbReg <=VTD_MMIO_GROUP_0_OFF_END366 || (offReg >= VTD_MMIO_GROUP_1_OFF_FIRST && offReg + cbReg <= VTD_MMIO_GROUP_1_OFF_END), ("%#x\n", offReg));431 AssertMsg( offLast < VTD_MMIO_GROUP_0_OFF_END 432 || offLast - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE, ("off=%#x cb=%u\n", offReg, cbReg)); 367 433 NOREF(cbReg); 368 434 369 435 uint8_t *apbRegs[] = { &pThis->abRegs0[0], &pThis->abRegs1[0] }; 370 *pIdxGroup = !(off Reg< VTD_MMIO_GROUP_0_OFF_END);436 *pIdxGroup = !(offLast < VTD_MMIO_GROUP_0_OFF_END); 371 437 return apbRegs[*pIdxGroup]; 372 438 } … … 600 666 static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 601 667 { 602 RT_NOREF5(pDevIns, pvUser, off, pv, cb);603 return VERR_NOT_IMPLEMENTED;604 }605 606 607 /**608 * @callback_method_impl{FNIOMMMIONEWREAD}609 */610 static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)611 {612 668 RT_NOREF1(pvUser); 613 614 AssertReturn(!(off & 3), VINF_IOM_MMIO_UNUSED_FF); 615 AssertReturn(cb == 4 || cb == 8, VINF_IOM_MMIO_UNUSED_FF); 669 VTD_ASSERT_MMIO_ACCESS_RET(off, cb); 616 670 617 671 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 618 672 uint16_t const offReg = off; 619 673 uint16_t const offLast = offReg + cb - 1; 620 if ( offLast < VTD_MMIO_GROUP_0_OFF_END 621 || offLast - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE) 674 if (VTD_IS_MMIO_OFF_VALID(offLast)) 675 { 676 switch (off) 677 { 678 default: 679 { 680 if (cb == 8) 681 iommuIntelRegWrite64(pThis, offReg, *(uint64_t *)pv); 682 else 683 iommuIntelRegWrite32(pThis, offReg, *(uint32_t *)pv); 684 break; 685 } 686 } 687 return VINF_SUCCESS; 688 } 689 return VINF_IOM_MMIO_UNUSED_FF; 690 } 691 692 693 /** 694 * @callback_method_impl{FNIOMMMIONEWREAD} 695 */ 696 static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 697 { 698 RT_NOREF1(pvUser); 699 VTD_ASSERT_MMIO_ACCESS_RET(off, cb); 700 701 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 702 uint16_t const offReg = off; 703 uint16_t const offLast = offReg + cb - 1; 704 if (VTD_IS_MMIO_OFF_VALID(offLast)) 622 705 { 623 706 if (cb == 8)
Note:
See TracChangeset
for help on using the changeset viewer.