Changeset 86214 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- Sep 22, 2020 9:59:38 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 140477
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r86210 r86214 392 392 const char *pszName; 393 393 VBOXSTRICTRC (*pfnRead)(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value); 394 VBOXSTRICTRC (*pfnWrite)(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value); 395 uint8_t cb; 394 VBOXSTRICTRC (*pfnWrite)(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value); 396 395 } IOMMUREGACC; 397 396 /** Pointer to an IOMMU register access. */ … … 761 760 762 761 /** 763 * Reads the MSI Vector Register 0 (32-bit) orthe MSI Vector Register 1 (32-bit).762 * Reads the MSI Vector Register 0 (32-bit) and the MSI Vector Register 1 (32-bit). 764 763 */ 765 764 static VBOXSTRICTRC iommuAmdDevMsiVector_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value) 766 765 { 767 766 RT_NOREF(pDevIns, offReg); 768 if (offReg == IOMMU_MMIO_OFF_MSI_VECTOR_0) 769 *pu64Value = pThis->MiscInfo.au32[0]; 770 else 771 { 772 AssertMsg(offReg == IOMMU_MMIO_OFF_MSI_VECTOR_1, ("%#x\n", offReg)); 773 *pu64Value = pThis->MiscInfo.au32[1]; 774 } 767 uint32_t const uLo = pThis->MiscInfo.au32[0]; 768 uint32_t const uHi = pThis->MiscInfo.au32[1]; 769 *pu64Value = RT_MAKE_U64(uLo, uHi); 775 770 return VINF_SUCCESS; 776 771 } … … 779 774 #ifdef IOMMU_NEW_REGISTER_ACCESS 780 775 /** 781 * Reads the MSI Capability Header Register (32-bit) orthe MSI Address (Lo)776 * Reads the MSI Capability Header Register (32-bit) and the MSI Address (Lo) 782 777 * Register (32-bit). 783 778 */ 784 static VBOXSTRICTRC iommuAmdMsiCapHdr OrAddrLo_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value)785 { 786 RT_NOREF(pThis );779 static VBOXSTRICTRC iommuAmdMsiCapHdrAndAddrLo_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value) 780 { 781 RT_NOREF(pThis, offReg); 787 782 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 788 783 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 789 if (offReg == IOMMU_MMIO_OFF_MSI_CAP_HDR) 790 *pu64Value = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR); 791 else 792 { 793 AssertMsg(offReg == IOMMU_MMIO_OFF_MSI_ADDR_LO, ("%#x\n", offReg)); 794 *pu64Value = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO); 795 } 796 return VINF_SUCCESS; 797 } 798 799 800 /** 801 * Reads the MSI Address (Hi) Register (32-bit) or the MSI data register (32-bit). 802 */ 803 static VBOXSTRICTRC iommuAmdMsiAddrHiOrData_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value) 804 { 805 RT_NOREF(pThis); 784 uint32_t const uLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR); 785 uint32_t const uHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO); 786 *pu64Value = RT_MAKE_U64(uLo, uHi); 787 return VINF_SUCCESS; 788 } 789 790 791 /** 792 * Reads the MSI Address (Hi) Register (32-bit) and the MSI data register (32-bit). 793 */ 794 static VBOXSTRICTRC iommuAmdMsiAddrHiAndData_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value) 795 { 796 RT_NOREF(pThis, offReg); 806 797 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 807 798 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 808 809 if (offReg == IOMMU_MMIO_OFF_MSI_ADDR_HI) 810 *pu64Value = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI); 811 else 812 { 813 AssertMsg(offReg == IOMMU_MMIO_OFF_MSI_DATA, ("%#x\n", offReg)); 814 *pu64Value = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA); 815 } 799 uint32_t const uLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI); 800 uint32_t const uHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA); 801 *pu64Value = RT_MAKE_U64(uLo, uHi); 816 802 return VINF_SUCCESS; 817 803 } 818 804 #endif 805 819 806 820 807 /** … … 1224 1211 #else 1225 1212 /** 1213 * Writes the MSI Vector Register 0 (32-bit) and the MSI Vector Register 1 (32-bit). 1214 */ 1215 static VBOXSTRICTRC iommuAmdDevMsiVector_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value) 1216 { 1217 RT_NOREF(pDevIns, offReg); 1218 1219 /* MSI Vector Register 0 is read-only. */ 1220 /* MSI Vector Register 1. */ 1221 uint32_t const uReg = u64Value >> 32; 1222 pThis->MiscInfo.au32[1] = uReg & IOMMU_MSI_VECTOR_1_VALID_MASK; 1223 return VINF_SUCCESS; 1224 } 1225 1226 1227 /** 1226 1228 * Writes the MSI Capability Header Register (32-bit) or the MSI Address (Lo) 1227 1229 * Register (32-bit). 1228 1230 */ 1229 static VBOXSTRICTRC iommuAmdMsiCapHdr OrAddrLo_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)1230 { 1231 RT_NOREF(pThis );1231 static VBOXSTRICTRC iommuAmdMsiCapHdrAndAddrLo_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value) 1232 { 1233 RT_NOREF(pThis, offReg); 1232 1234 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 1233 1235 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 1234 if (offReg == IOMMU_MMIO_OFF_MSI_CAP_HDR) 1235 { 1236 /* MsiMultMessEn not supported, so only MsiEn is the writable bit. */ 1236 1237 /* MSI capability header. */ 1238 { 1239 uint32_t const uReg = u64Value; 1237 1240 MSI_CAP_HDR_T MsiCapHdr; 1238 1241 MsiCapHdr.u32 = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR); 1239 MsiCapHdr.n.u1MsiEnable = RT_BOOL(u 64Value& IOMMU_MSI_CAP_HDR_MSI_EN_MASK);1242 MsiCapHdr.n.u1MsiEnable = RT_BOOL(uReg & IOMMU_MSI_CAP_HDR_MSI_EN_MASK); 1240 1243 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR, MsiCapHdr.u32); 1241 1244 } 1242 else 1243 { 1244 AssertMsg(offReg == IOMMU_MMIO_OFF_MSI_ADDR_LO, ("%#x\n", offReg)); 1245 uint32_t const uMsiAddrLo = u64Value & VBOX_MSI_ADDR_VALID_MASK; 1245 1246 /* MSI Address Lo. */ 1247 { 1248 uint32_t const uReg = u64Value >> 32; 1249 uint32_t const uMsiAddrLo = uReg & VBOX_MSI_ADDR_VALID_MASK; 1246 1250 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO, uMsiAddrLo); 1247 1251 } 1252 1248 1253 return VINF_SUCCESS; 1249 1254 } … … 1253 1258 * Writes the MSI Address (Hi) Register (32-bit) or the MSI data register (32-bit). 1254 1259 */ 1255 static VBOXSTRICTRC iommuAmdMsiAddrHi OrData_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)1256 { 1257 RT_NOREF(pThis );1260 static VBOXSTRICTRC iommuAmdMsiAddrHiAndData_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value) 1261 { 1262 RT_NOREF(pThis, offReg); 1258 1263 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 1259 1264 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 1260 if (offReg == IOMMU_MMIO_OFF_MSI_ADDR_HI) 1261 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI, u64Value); 1262 else 1263 { 1264 AssertMsg(offReg == IOMMU_MMIO_OFF_MSI_DATA, ("%#x\n", offReg)); 1265 uint32_t const uMsiData = u64Value & VBOX_MSI_DATA_VALID_MASK; 1265 1266 /* MSI Address Hi. */ 1267 { 1268 uint32_t const uReg = u64Value; 1269 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI, uReg); 1270 } 1271 1272 /* MSI Data. */ 1273 { 1274 uint32_t const uReg = u64Value >> 32; 1275 uint32_t const uMsiData = uReg & VBOX_MSI_DATA_VALID_MASK; 1266 1276 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA, uMsiData); 1267 1277 } 1278 1268 1279 return VINF_SUCCESS; 1269 1280 } … … 1457 1468 static const IOMMUREGACC g_aRegAccess0[] = 1458 1469 { 1459 /* MMIO off. Register name Read function Write function Reg. size*/1460 { /* 0x00 */ "DEV_TAB_BAR", iommuAmdDevTabBar_r, iommuAmdDevTabBar_w, 8},1461 { /* 0x08 */ "CMD_BUF_BAR", iommuAmdCmdBufBar_r, iommuAmdCmdBufBar_w, 8},1462 { /* 0x10 */ "EVT_LOG_BAR", iommuAmdEvtLogBar_r, iommuAmdEvtLogBar_w, 8},1463 { /* 0x18 */ "CTRL", iommuAmdCtrl_r, iommuAmdCtrl_w, 8},1464 { /* 0x20 */ "EXCL_BAR", iommuAmdExclRangeBar_r, iommuAmdExclRangeBar_w, 8},1465 { /* 0x28 */ "EXCL_RANGE_LIMIT", iommuAmdExclRangeLimit_r, iommuAmdExclRangeLimit_w, 8},1466 { /* 0x30 */ "EXT_FEAT", iommuAmdExtFeat_r, NULL, 8},1467 { /* 0x38 */ "PPR_LOG_BAR", iommuAmdPprLogBar_r, NULL, 8},1468 { /* 0x40 */ "HW_EVT_HI", iommuAmdHwEvtHi_r, iommuAmdHwEvtHi_w, 8},1469 { /* 0x48 */ "HW_EVT_LO", iommuAmdHwEvtLo_r, iommuAmdHwEvtLo_w, 8},1470 { /* 0x50 */ "HW_EVT_STATUS", iommuAmdHwEvtStatus_r, iommuAmdHwEvtStatus_w, 8},1471 { /* 0x58 */ NULL, NULL, NULL, 0},1472 1473 { /* 0x60 */ "SMI_FLT_0", NULL, NULL, 8},1474 { /* 0x68 */ "SMI_FLT_1", NULL, NULL, 8},1475 { /* 0x70 */ "SMI_FLT_2", NULL, NULL, 8},1476 { /* 0x78 */ "SMI_FLT_3", NULL, NULL, 8},1477 { /* 0x80 */ "SMI_FLT_4", NULL, NULL, 8},1478 { /* 0x88 */ "SMI_FLT_5", NULL, NULL, 8},1479 { /* 0x90 */ "SMI_FLT_6", NULL, NULL, 8},1480 { /* 0x98 */ "SMI_FLT_7", NULL, NULL, 8},1481 { /* 0xa0 */ "SMI_FLT_8", NULL, NULL, 8},1482 { /* 0xa8 */ "SMI_FLT_9", NULL, NULL, 8},1483 { /* 0xb0 */ "SMI_FLT_10", NULL, NULL, 8},1484 { /* 0xb8 */ "SMI_FLT_11", NULL, NULL, 8},1485 { /* 0xc0 */ "SMI_FLT_12", NULL, NULL, 8},1486 { /* 0xc8 */ "SMI_FLT_13", NULL, NULL, 8},1487 { /* 0xd0 */ "SMI_FLT_14", NULL, NULL, 8},1488 { /* 0xd8 */ "SMI_FLT_15", NULL, NULL, 8},1489 1490 { /* 0xe0 */ "GALOG_BAR", iommuAmdGALogBar_r, NULL, 8},1491 { /* 0xe8 */ "GALOG_TAIL_ADDR", NULL, NULL, 8},1492 { /* 0xf0 */ "PPR_LOG_B_BAR", iommuAmdPprLogBBaseAddr_r, NULL, 8},1493 { /* 0xf8 */ "PPR_EVT_B_BAR", iommuAmdEvtLogBBaseAddr_r, NULL, 8},1494 1495 { /* 0x100 */ "DEV_TAB_SEG_1", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1496 { /* 0x108 */ "DEV_TAB_SEG_2", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1497 { /* 0x110 */ "DEV_TAB_SEG_3", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1498 { /* 0x118 */ "DEV_TAB_SEG_4", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1499 { /* 0x120 */ "DEV_TAB_SEG_5", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1500 { /* 0x128 */ "DEV_TAB_SEG_6", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1501 { /* 0x130 */ "DEV_TAB_SEG_7", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w, 8},1502 1503 { /* 0x138 */ "DEV_SPECIFIC_FEAT", iommuAmdDevSpecificFeat_r, NULL, 8},1504 { /* 0x140 */ "DEV_SPECIFIC_CTRL", iommuAmdDevSpecificCtrl_r, NULL, 8},1505 { /* 0x148 */ "DEV_SPECIFIC_STATUS", iommuAmdDevSpecificStatus_r, NULL, 8},1506 1507 { /* 0x150 */ "MSI_VECTOR_0 or MSI_VECTOR_1", iommuAmdDevMsiVector_r, NULL, 4},1508 { /* 0x158 */ "MSI_CAP_HDR or MSI_ADDR_LO", iommuAmdMsiCapHdr OrAddrLo_r, iommuAmdMsiCapHdrOrAddrLo_w, 4},1509 { /* 0x160 */ "MSI_ADDR_HI or MSI_DATA", iommuAmdMsiAddrHi OrData_r, iommuAmdMsiAddrHiOrData_w, 4},1510 { /* 0x168 */ "MSI_MAPPING_CAP_HDR or PERF_OPT_CTRL", NULL, NULL, 4},1511 1512 { /* 0x170 */ "XT_GEN_INTR_CTRL", NULL, NULL, 8},1513 { /* 0x178 */ "XT_PPR_INTR_CTRL", NULL, NULL, 8},1514 { /* 0x180 */ "XT_GALOG_INT_CTRL", NULL, NULL, 8},1470 /* MMIO off. Register name Read function Write function */ 1471 { /* 0x00 */ "DEV_TAB_BAR", iommuAmdDevTabBar_r, iommuAmdDevTabBar_w }, 1472 { /* 0x08 */ "CMD_BUF_BAR", iommuAmdCmdBufBar_r, iommuAmdCmdBufBar_w }, 1473 { /* 0x10 */ "EVT_LOG_BAR", iommuAmdEvtLogBar_r, iommuAmdEvtLogBar_w }, 1474 { /* 0x18 */ "CTRL", iommuAmdCtrl_r, iommuAmdCtrl_w }, 1475 { /* 0x20 */ "EXCL_BAR", iommuAmdExclRangeBar_r, iommuAmdExclRangeBar_w }, 1476 { /* 0x28 */ "EXCL_RANGE_LIMIT", iommuAmdExclRangeLimit_r, iommuAmdExclRangeLimit_w }, 1477 { /* 0x30 */ "EXT_FEAT", iommuAmdExtFeat_r, NULL }, 1478 { /* 0x38 */ "PPR_LOG_BAR", iommuAmdPprLogBar_r, NULL }, 1479 { /* 0x40 */ "HW_EVT_HI", iommuAmdHwEvtHi_r, iommuAmdHwEvtHi_w }, 1480 { /* 0x48 */ "HW_EVT_LO", iommuAmdHwEvtLo_r, iommuAmdHwEvtLo_w }, 1481 { /* 0x50 */ "HW_EVT_STATUS", iommuAmdHwEvtStatus_r, iommuAmdHwEvtStatus_w }, 1482 { /* 0x58 */ NULL, NULL, NULL }, 1483 1484 { /* 0x60 */ "SMI_FLT_0", NULL, NULL }, 1485 { /* 0x68 */ "SMI_FLT_1", NULL, NULL }, 1486 { /* 0x70 */ "SMI_FLT_2", NULL, NULL }, 1487 { /* 0x78 */ "SMI_FLT_3", NULL, NULL }, 1488 { /* 0x80 */ "SMI_FLT_4", NULL, NULL }, 1489 { /* 0x88 */ "SMI_FLT_5", NULL, NULL }, 1490 { /* 0x90 */ "SMI_FLT_6", NULL, NULL }, 1491 { /* 0x98 */ "SMI_FLT_7", NULL, NULL }, 1492 { /* 0xa0 */ "SMI_FLT_8", NULL, NULL }, 1493 { /* 0xa8 */ "SMI_FLT_9", NULL, NULL }, 1494 { /* 0xb0 */ "SMI_FLT_10", NULL, NULL }, 1495 { /* 0xb8 */ "SMI_FLT_11", NULL, NULL }, 1496 { /* 0xc0 */ "SMI_FLT_12", NULL, NULL }, 1497 { /* 0xc8 */ "SMI_FLT_13", NULL, NULL }, 1498 { /* 0xd0 */ "SMI_FLT_14", NULL, NULL }, 1499 { /* 0xd8 */ "SMI_FLT_15", NULL, NULL }, 1500 1501 { /* 0xe0 */ "GALOG_BAR", iommuAmdGALogBar_r, NULL }, 1502 { /* 0xe8 */ "GALOG_TAIL_ADDR", NULL, NULL }, 1503 { /* 0xf0 */ "PPR_LOG_B_BAR", iommuAmdPprLogBBaseAddr_r, NULL }, 1504 { /* 0xf8 */ "PPR_EVT_B_BAR", iommuAmdEvtLogBBaseAddr_r, NULL }, 1505 1506 { /* 0x100 */ "DEV_TAB_SEG_1", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1507 { /* 0x108 */ "DEV_TAB_SEG_2", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1508 { /* 0x110 */ "DEV_TAB_SEG_3", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1509 { /* 0x118 */ "DEV_TAB_SEG_4", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1510 { /* 0x120 */ "DEV_TAB_SEG_5", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1511 { /* 0x128 */ "DEV_TAB_SEG_6", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1512 { /* 0x130 */ "DEV_TAB_SEG_7", iommuAmdDevTabSegBar_r, iommuAmdDevTabSegBar_w }, 1513 1514 { /* 0x138 */ "DEV_SPECIFIC_FEAT", iommuAmdDevSpecificFeat_r, NULL }, 1515 { /* 0x140 */ "DEV_SPECIFIC_CTRL", iommuAmdDevSpecificCtrl_r, NULL }, 1516 { /* 0x148 */ "DEV_SPECIFIC_STATUS", iommuAmdDevSpecificStatus_r, NULL }, 1517 1518 { /* 0x150 */ "MSI_VECTOR_0 or MSI_VECTOR_1", iommuAmdDevMsiVector_r, iommuAmdDevMsiVector_w }, 1519 { /* 0x158 */ "MSI_CAP_HDR or MSI_ADDR_LO", iommuAmdMsiCapHdrAndAddrLo_r, iommuAmdMsiCapHdrAndAddrLo_w }, 1520 { /* 0x160 */ "MSI_ADDR_HI or MSI_DATA", iommuAmdMsiAddrHiAndData_r, iommuAmdMsiAddrHiAndData_w }, 1521 { /* 0x168 */ "MSI_MAPPING_CAP_HDR or PERF_OPT_CTRL", NULL, NULL }, 1522 1523 { /* 0x170 */ "XT_GEN_INTR_CTRL", NULL, NULL }, 1524 { /* 0x178 */ "XT_PPR_INTR_CTRL", NULL, NULL }, 1525 { /* 0x180 */ "XT_GALOG_INT_CTRL", NULL, NULL }, 1515 1526 }; 1516 1527 AssertCompile(RT_ELEMENTS(g_aRegAccess0) == (IOMMU_MMIO_OFF_QWORD_TABLE_0_END - IOMMU_MMIO_OFF_QWORD_TABLE_0_START) / 8); … … 1522 1533 static const IOMMUREGACC g_aRegAccess1[] = 1523 1534 { 1524 /* MMIO offset Register name Read function Write function Register size.*/1525 { /* 0x200 */ "MARC_APER_BAR_0", NULL, NULL, 8},1526 { /* 0x208 */ "MARC_APER_RELOC_0", NULL, NULL, 8},1527 { /* 0x210 */ "MARC_APER_LEN_0", NULL, NULL, 8},1528 { /* 0x218 */ "MARC_APER_BAR_1", NULL, NULL, 8},1529 { /* 0x220 */ "MARC_APER_RELOC_1", NULL, NULL, 8},1530 { /* 0x228 */ "MARC_APER_LEN_1", NULL, NULL, 8},1531 { /* 0x230 */ "MARC_APER_BAR_2", NULL, NULL, 8},1532 { /* 0x238 */ "MARC_APER_RELOC_2", NULL, NULL, 8},1533 { /* 0x240 */ "MARC_APER_LEN_2", NULL, NULL, 8},1534 { /* 0x248 */ "MARC_APER_BAR_3", NULL, NULL, 8},1535 { /* 0x250 */ "MARC_APER_RELOC_3", NULL, NULL, 8},1536 { /* 0x258 */ "MARC_APER_LEN_3", NULL, NULL, 8}1535 /* MMIO offset Register name Read function Write function */ 1536 { /* 0x200 */ "MARC_APER_BAR_0", NULL, NULL }, 1537 { /* 0x208 */ "MARC_APER_RELOC_0", NULL, NULL }, 1538 { /* 0x210 */ "MARC_APER_LEN_0", NULL, NULL }, 1539 { /* 0x218 */ "MARC_APER_BAR_1", NULL, NULL }, 1540 { /* 0x220 */ "MARC_APER_RELOC_1", NULL, NULL }, 1541 { /* 0x228 */ "MARC_APER_LEN_1", NULL, NULL }, 1542 { /* 0x230 */ "MARC_APER_BAR_2", NULL, NULL }, 1543 { /* 0x238 */ "MARC_APER_RELOC_2", NULL, NULL }, 1544 { /* 0x240 */ "MARC_APER_LEN_2", NULL, NULL }, 1545 { /* 0x248 */ "MARC_APER_BAR_3", NULL, NULL }, 1546 { /* 0x250 */ "MARC_APER_RELOC_3", NULL, NULL }, 1547 { /* 0x258 */ "MARC_APER_LEN_3", NULL, NULL } 1537 1548 }; 1538 1549 AssertCompile(RT_ELEMENTS(g_aRegAccess1) == (IOMMU_MMIO_OFF_QWORD_TABLE_1_END - IOMMU_MMIO_OFF_QWORD_TABLE_1_START) / 8); … … 1544 1555 static const IOMMUREGACC g_aRegAccess2[] = 1545 1556 { 1546 /* MMIO offset Register name Read Function Write function Register size (bytes)*/1547 { /* 0x1ff8 */ "RSVD_REG", NULL, NULL , 8},1548 1549 { /* 0x2000 */ "CMD_BUF_HEAD_PTR", iommuAmdCmdBufHeadPtr_r, iommuAmdCmdBufHeadPtr_w , 8},1550 { /* 0x2008 */ "CMD_BUF_TAIL_PTR", iommuAmdCmdBufTailPtr_r , iommuAmdCmdBufTailPtr_w , 8},1551 { /* 0x2010 */ "EVT_LOG_HEAD_PTR", iommuAmdEvtLogHeadPtr_r, iommuAmdEvtLogHeadPtr_w , 8},1552 { /* 0x2018 */ "EVT_LOG_TAIL_PTR", iommuAmdEvtLogTailPtr_r, iommuAmdEvtLogTailPtr_w , 8},1553 1554 { /* 0x2020 */ "STATUS", iommuAmdStatus_r, iommuAmdStatus_w , 8},1555 { /* 0x2028 */ NULL, NULL, NULL , 0},1556 1557 { /* 0x2030 */ "PPR_LOG_HEAD_PTR", NULL, NULL , 8},1558 { /* 0x2038 */ "PPR_LOG_TAIL_PTR", NULL, NULL , 8},1559 1560 { /* 0x2040 */ "GALOG_HEAD_PTR", NULL, NULL , 8},1561 { /* 0x2048 */ "GALOG_TAIL_PTR", NULL, NULL , 8},1562 1563 { /* 0x2050 */ "PPR_LOG_B_HEAD_PTR", NULL, NULL , 8},1564 { /* 0x2058 */ "PPR_LOG_B_TAIL_PTR", NULL, NULL , 8},1565 1566 { /* 0x2060 */ NULL, NULL, NULL , 0},1567 { /* 0x2068 */ NULL, NULL, NULL , 0},1568 1569 { /* 0x2070 */ "EVT_LOG_B_HEAD_PTR", NULL, NULL , 8},1570 { /* 0x2078 */ "EVT_LOG_B_TAIL_PTR", NULL, NULL , 8},1571 1572 { /* 0x2080 */ "PPR_LOG_AUTO_RESP", NULL, NULL , 8},1573 { /* 0x2088 */ "PPR_LOG_OVERFLOW_EARLY", NULL, NULL , 8},1574 { /* 0x2090 */ "PPR_LOG_B_OVERFLOW_EARLY", NULL, NULL , 8}1557 /* MMIO offset Register name Read Function Write function */ 1558 { /* 0x1ff8 */ "RSVD_REG", NULL, NULL }, 1559 1560 { /* 0x2000 */ "CMD_BUF_HEAD_PTR", iommuAmdCmdBufHeadPtr_r, iommuAmdCmdBufHeadPtr_w }, 1561 { /* 0x2008 */ "CMD_BUF_TAIL_PTR", iommuAmdCmdBufTailPtr_r , iommuAmdCmdBufTailPtr_w }, 1562 { /* 0x2010 */ "EVT_LOG_HEAD_PTR", iommuAmdEvtLogHeadPtr_r, iommuAmdEvtLogHeadPtr_w }, 1563 { /* 0x2018 */ "EVT_LOG_TAIL_PTR", iommuAmdEvtLogTailPtr_r, iommuAmdEvtLogTailPtr_w }, 1564 1565 { /* 0x2020 */ "STATUS", iommuAmdStatus_r, iommuAmdStatus_w }, 1566 { /* 0x2028 */ NULL, NULL, NULL }, 1567 1568 { /* 0x2030 */ "PPR_LOG_HEAD_PTR", NULL, NULL }, 1569 { /* 0x2038 */ "PPR_LOG_TAIL_PTR", NULL, NULL }, 1570 1571 { /* 0x2040 */ "GALOG_HEAD_PTR", NULL, NULL }, 1572 { /* 0x2048 */ "GALOG_TAIL_PTR", NULL, NULL }, 1573 1574 { /* 0x2050 */ "PPR_LOG_B_HEAD_PTR", NULL, NULL }, 1575 { /* 0x2058 */ "PPR_LOG_B_TAIL_PTR", NULL, NULL }, 1576 1577 { /* 0x2060 */ NULL, NULL, NULL }, 1578 { /* 0x2068 */ NULL, NULL, NULL }, 1579 1580 { /* 0x2070 */ "EVT_LOG_B_HEAD_PTR", NULL, NULL }, 1581 { /* 0x2078 */ "EVT_LOG_B_TAIL_PTR", NULL, NULL }, 1582 1583 { /* 0x2080 */ "PPR_LOG_AUTO_RESP", NULL, NULL }, 1584 { /* 0x2088 */ "PPR_LOG_OVERFLOW_EARLY", NULL, NULL }, 1585 { /* 0x2090 */ "PPR_LOG_B_OVERFLOW_EARLY", NULL, NULL } 1575 1586 }; 1576 1587 AssertCompile(RT_ELEMENTS(g_aRegAccess2) == (IOMMU_MMIO_OFF_QWORD_TABLE_2_END - IOMMU_MMIO_OFF_QWORD_TABLE_2_START) / 8); … … 1759 1770 else 1760 1771 { 1761 LogFunc(("Writing unknown register % u (%#x) with %#RX64 -> Ignored\n", off, off, uValue));1772 LogFunc(("Writing unknown register %#x with %#RX64 -> Ignored\n", off, uValue)); 1762 1773 return VINF_SUCCESS; 1763 1774 } … … 1773 1784 1774 1785 /* 1775 * If the write access is aligned and matches the register size, dispatch right away. 1776 * This handles all aligned, 32-bit writes as well as aligned 64-bit writes. 1786 * If the write access is 64-bits and aligned on a 64-bit boundary, dispatch right away. 1787 * This handles writes to 64-bit registers as well as aligned, 64-bit writes to two 1788 * consecutive 32-bit registers. 1777 1789 */ 1778 if ( cb == pReg->cb 1779 && !(off & (cb - 1))) 1780 return pReg->pfnWrite(pDevIns, pThis, off, uValue); 1781 1782 /* 1783 * A 32-bit write for a 64-bit register. 1784 * We shouldn't get sizes other than 32 bits here as we've specified so with IOM. 1785 */ 1790 if (cb == 8) 1791 { 1792 if (!(off & 7)) 1793 return pReg->pfnWrite(pDevIns, pThis, off, uValue); 1794 1795 LogFunc(("Misaligned access while writing register at off=%#x (cb=%u) with %#RX64 -> Ignored\n", off, cb, uValue)); 1796 return VINF_SUCCESS; 1797 } 1798 1799 /* We shouldn't get sizes other than 32 bits here as we've specified so with IOM. */ 1786 1800 Assert(cb == 4); 1787 1801 if (!(off & 7)) 1788 1802 { 1789 1803 /* 1790 * Lower 32 bits of theregister is being written.1791 * Merge with higher 32 bits (after reading the full value from the register).1804 * Lower 32 bits of a 64-bit register or a 32-bit register is being written. 1805 * Merge with higher 32 bits (after reading the full 64-bits) and perform a 64-bit write. 1792 1806 */ 1793 1807 uint64_t u64Read; … … 1809 1823 1810 1824 /* 1811 * Higher 32 bits of the registeris being written.1812 * Merge with lower 32 bits (after reading the full value from the register).1825 * Higher 32 bits of a 64-bit register or a 32-bit register at a 32-bit boundary is being written. 1826 * Merge with lower 32 bits (after reading the full 64-bits) and perform a 64-bit write. 1813 1827 */ 1814 1828 Assert(!(off & 3)); 1815 1829 Assert(off & 7); 1816 Assert(off > 4);1830 Assert(off >= 4); 1817 1831 uint64_t u64Read; 1818 1832 if (pReg->pfnRead) … … 1863 1877 Log5Func(("off=%#x\n", off)); 1864 1878 1879 #ifndef IOMMU_NEW_REGISTER_ACCESS 1865 1880 /** @todo IOMMU: fine-grained locking? */ 1866 1881 uint64_t uReg; … … 2007 2022 *puResult = uReg; 2008 2023 return VINF_SUCCESS; 2024 #else 2025 PCIOMMUREGACC pReg = iommuAmdGetRegAccessForOffset(off); 2026 if (pReg) 2027 { /* likely */ } 2028 else 2029 { 2030 LogFunc(("Reading unknown register %#x -> Ignored\n", off)); 2031 return VINF_IOM_MMIO_UNUSED_FF; 2032 } 2033 2034 /* If a read handler doesn't exist, it's reserved or unknown register. */ 2035 if (pReg->pfnRead) 2036 { /* likely */ } 2037 else 2038 { 2039 LogFunc(("Reading reserved or unknown register off=%#x -> returning 0s\n", off)); 2040 return VINF_IOM_MMIO_UNUSED_00; 2041 } 2042 2043 /* 2044 * If the read access is aligned on a 64-bit boundary, read the full 64-bits and return. 2045 * The caller takes care of truncating upper 32 bits for 32-bit reads. 2046 */ 2047 if (!(off & 7)) 2048 return pReg->pfnRead(pDevIns, pThis, off, puResult); 2049 2050 /* 2051 * High 32 bits of a 64-bit register or a 32-bit register at a non 64-bit boundary is being read. 2052 * Read full 64 bits at the previous 64-bit boundary but return only the high 32 bits. 2053 */ 2054 Assert(!(off & 3)); 2055 Assert(off & 7); 2056 Assert(off >= 4); 2057 VBOXSTRICTRC rcStrict = pReg->pfnRead(pDevIns, pThis, off - 4, puResult); 2058 if (RT_SUCCESS(rcStrict)) 2059 *puResult >>= 32; 2060 else 2061 { 2062 *puResult = 0; 2063 LogFunc(("Reading off %#x during split read failed! rc=%Rrc\n -> Ignored", off, VBOXSTRICTRC_VAL(rcStrict))); 2064 } 2065 2066 return rcStrict; 2067 #endif 2009 2068 } 2010 2069
Note:
See TracChangeset
for help on using the changeset viewer.