VirtualBox

Changeset 86214 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
Sep 22, 2020 9:59:38 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
140477
Message:

AMD IOMMU: bugref:9654 Fix split register accesses.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r86210 r86214  
    392392    const char   *pszName;
    393393    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);
    396395} IOMMUREGACC;
    397396/** Pointer to an IOMMU register access. */
     
    761760
    762761/**
    763  * Reads the MSI Vector Register 0 (32-bit) or the MSI Vector Register 1 (32-bit).
     762 * Reads the MSI Vector Register 0 (32-bit) and the MSI Vector Register 1 (32-bit).
    764763 */
    765764static VBOXSTRICTRC iommuAmdDevMsiVector_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value)
    766765{
    767766    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);
    775770    return VINF_SUCCESS;
    776771}
     
    779774#ifdef IOMMU_NEW_REGISTER_ACCESS
    780775/**
    781  * Reads the MSI Capability Header Register (32-bit) or the MSI Address (Lo)
     776 * Reads the MSI Capability Header Register (32-bit) and the MSI Address (Lo)
    782777 * Register (32-bit).
    783778 */
    784 static VBOXSTRICTRC iommuAmdMsiCapHdrOrAddrLo_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value)
    785 {
    786     RT_NOREF(pThis);
     779static VBOXSTRICTRC iommuAmdMsiCapHdrAndAddrLo_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value)
     780{
     781    RT_NOREF(pThis, offReg);
    787782    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    788783    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 */
     794static VBOXSTRICTRC iommuAmdMsiAddrHiAndData_r(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t *pu64Value)
     795{
     796    RT_NOREF(pThis, offReg);
    806797    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    807798    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);
    816802    return VINF_SUCCESS;
    817803}
    818804#endif
     805
    819806
    820807/**
     
    12241211#else
    12251212/**
     1213 * Writes the MSI Vector Register 0 (32-bit) and the MSI Vector Register 1 (32-bit).
     1214 */
     1215static 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/**
    12261228 * Writes the MSI Capability Header Register (32-bit) or the MSI Address (Lo)
    12271229 * Register (32-bit).
    12281230 */
    1229 static VBOXSTRICTRC iommuAmdMsiCapHdrOrAddrLo_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)
    1230 {
    1231     RT_NOREF(pThis);
     1231static VBOXSTRICTRC iommuAmdMsiCapHdrAndAddrLo_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)
     1232{
     1233    RT_NOREF(pThis, offReg);
    12321234    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    12331235    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;
    12371240        MSI_CAP_HDR_T MsiCapHdr;
    12381241        MsiCapHdr.u32           = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR);
    1239         MsiCapHdr.n.u1MsiEnable = RT_BOOL(u64Value & IOMMU_MSI_CAP_HDR_MSI_EN_MASK);
     1242        MsiCapHdr.n.u1MsiEnable = RT_BOOL(uReg & IOMMU_MSI_CAP_HDR_MSI_EN_MASK);
    12401243        PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR, MsiCapHdr.u32);
    12411244    }
    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;
    12461250        PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO, uMsiAddrLo);
    12471251    }
     1252
    12481253    return VINF_SUCCESS;
    12491254}
     
    12531258 * Writes the MSI Address (Hi) Register (32-bit) or the MSI data register (32-bit).
    12541259 */
    1255 static VBOXSTRICTRC iommuAmdMsiAddrHiOrData_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)
    1256 {
    1257     RT_NOREF(pThis);
     1260static VBOXSTRICTRC iommuAmdMsiAddrHiAndData_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t offReg, uint64_t u64Value)
     1261{
     1262    RT_NOREF(pThis, offReg);
    12581263    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    12591264    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;
    12661276        PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA, uMsiData);
    12671277    }
     1278
    12681279    return VINF_SUCCESS;
    12691280}
     
    14571468static const IOMMUREGACC g_aRegAccess0[] =
    14581469{
    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",           iommuAmdMsiCapHdrOrAddrLo_r, iommuAmdMsiCapHdrOrAddrLo_w, 4 },
    1509     { /* 0x160 */  "MSI_ADDR_HI or MSI_DATA",              iommuAmdMsiAddrHiOrData_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                          },
    15151526};
    15161527AssertCompile(RT_ELEMENTS(g_aRegAccess0) == (IOMMU_MMIO_OFF_QWORD_TABLE_0_END - IOMMU_MMIO_OFF_QWORD_TABLE_0_START) / 8);
     
    15221533static const IOMMUREGACC g_aRegAccess1[] =
    15231534{
    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 }
    15371548};
    15381549AssertCompile(RT_ELEMENTS(g_aRegAccess1) == (IOMMU_MMIO_OFF_QWORD_TABLE_1_END - IOMMU_MMIO_OFF_QWORD_TABLE_1_START) / 8);
     
    15441555static const IOMMUREGACC g_aRegAccess2[] =
    15451556{
    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                    }
    15751586};
    15761587AssertCompile(RT_ELEMENTS(g_aRegAccess2) == (IOMMU_MMIO_OFF_QWORD_TABLE_2_END - IOMMU_MMIO_OFF_QWORD_TABLE_2_START) / 8);
     
    17591770    else
    17601771    {
    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));
    17621773        return VINF_SUCCESS;
    17631774    }
     
    17731784
    17741785    /*
    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.
    17771789     */
    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. */
    17861800    Assert(cb == 4);
    17871801    if (!(off & 7))
    17881802    {
    17891803        /*
    1790          * Lower 32 bits of the register 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.
    17921806         */
    17931807        uint64_t u64Read;
     
    18091823
    18101824    /*
    1811      * Higher 32 bits of the register is 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.
    18131827     */
    18141828    Assert(!(off & 3));
    18151829    Assert(off & 7);
    1816     Assert(off > 4);
     1830    Assert(off >= 4);
    18171831    uint64_t u64Read;
    18181832    if (pReg->pfnRead)
     
    18631877    Log5Func(("off=%#x\n", off));
    18641878
     1879#ifndef IOMMU_NEW_REGISTER_ACCESS
    18651880    /** @todo IOMMU: fine-grained locking? */
    18661881    uint64_t uReg;
     
    20072022    *puResult = uReg;
    20082023    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
    20092068}
    20102069
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette