VirtualBox

Changeset 83649 in vbox


Ignore:
Timestamp:
Apr 9, 2020 2:04:15 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137110
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

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

    r83619 r83649  
    3131*   Defined Constants And Macros                                                                                                 *
    3232*********************************************************************************************************************************/
    33 /** @name PCI configuration register offsets.
    34  @{ */
     33/**
     34 * @name PCI configuration register offsets.
     35 * In accordance with the AMD spec.
     36 * @{
     37 */
    3538#define IOMMU_PCI_OFF_CAP_HDR                       0x40
    3639#define IOMMU_PCI_OFF_BASE_ADDR_REG_LO              0x44
     
    4649/** @} */
    4750
    48 /** @name MMIO register offsets.
    49  * @{ */
     51/**
     52 * @name MMIO register offsets.
     53 * In accordance with the AMD spec.
     54 * @{
     55 */
    5056#define IOMMU_MMIO_OFF_DEV_TAB_BAR                  0x00
    5157#define IOMMU_MMIO_OFF_CMD_BUF_BAR                  0x08
     
    128134#define IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY       0x2088
    129135#define IOMMU_MMIO_OFF_PPR_LOG_B_OVERFLOW_EARLY     0x2090
     136/** @} */
     137
     138/**
     139 * @name MMIO register-access table offsets.
     140 * Each table [first..last] (both inclusive) represents the range of registers
     141 * covered by a distinct register-access table. This is done due to arbitrary large
     142 * gaps in the MMIO register offsets themselves.
     143 * @{
     144 */
     145#define IOMMU_MMIO_OFF_TABLE_0_FIRST               0x00
     146#define IOMMU_MMIO_OFF_TABLE_0_LAST                0x258
     147
     148#define IOMMU_MMIO_OFF_TABLE_1_FIRST               0x1ff8
     149#define IOMMU_MMIO_OFF_TABLE_1_LAST                0x2090
    130150/** @} */
    131151
     
    9951015} DEV_TAB_BAR_T;
    9961016AssertCompileSize(DEV_TAB_BAR_T, 8);
     1017#define IOMMU_DEV_TAB_BAR_VALID_MASK      UINT64_C(0x000ffffffffff3ff)
    9971018
    9981019/**
     
    10141035} CMD_BUF_BAR_T;
    10151036AssertCompileSize(CMD_BUF_BAR_T, 8);
     1037#define IOMMU_CMD_BUF_BAR_VALID_MASK      UINT64_C(0x0f0ffffffffff000)
    10161038
    10171039/**
     
    10331055} EVT_LOG_BAR_T;
    10341056AssertCompileSize(EVT_LOG_BAR_T, 8);
     1057#define IOMMU_EVT_LOG_BAR_VALID_MASK      UINT64_C(0x0f0ffffffffff000)
    10351058
    10361059/**
     
    19842007typedef CTX_SUFF(PIOMMU) PIOMMUCC;
    19852008
     2009/**
     2010 * IOMMU register access routines.
     2011 */
     2012typedef struct
     2013{
     2014    const char   *pszName;
     2015    VBOXSTRICTRC (*pfnRead )(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t *pu64Value);
     2016    VBOXSTRICTRC (*pfnWrite)(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t  u64Value);
     2017    bool         f64BitReg;
     2018} IOMMUREGACC;
     2019
    19862020
    19872021#ifndef VBOX_DEVICE_STRUCT_TESTCASE
    19882022
    1989 static VBOXSTRICTRC iommuAmdReadRegister(PCIOMMU pThis, uint32_t off, uint64_t *puResult)
    1990 {
    1991     Assert(off < _16K);
    1992     Assert(!(off & 7) || !(off & 3));
    1993 
    1994     /** @todo locking? */
     2023/**
     2024 * Returns the number of entries and buffer size for a power-of-2 encoded length.
     2025 *
     2026 * @param   uEncodedLen     The length to decode.
     2027 * @param   pcEntries       Where to store the number of entries. Optional, can be
     2028 *                          NULL.
     2029 * @param   pcbBuffer       Where to store the size of the buffer. Optional, can be
     2030 *                          NULL.
     2031 *
     2032 * @remarks Both @a pcEntries and @a pcbBuffer cannot both be NULL.
     2033 */
     2034static void iommuAmdDecodeBufferLength(uint8_t uEncodedLen, uint32_t *pcEntries, uint32_t *pcbBuffer)
     2035{
     2036    uint32_t cEntries;
     2037    uint32_t cbBuffer;
     2038    if (uEncodedLen > 7)
     2039    {
     2040        cEntries = 2 << (uEncodedLen - 1);
     2041        cbBuffer = *pcEntries << 4;
     2042    }
     2043    else
     2044        cEntries = cbBuffer = 0;
     2045
     2046    Assert(pcEntries || pcbBuffer);
     2047    if (pcEntries)
     2048        *pcEntries = cEntries;
     2049    if (pcbBuffer)
     2050        *pcbBuffer = cbBuffer;
     2051}
     2052
     2053/**
     2054 * Writes the Device Table Base Address Register.
     2055 */
     2056static VBOXSTRICTRC iommuAmdDevTabBar_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t  u64Value)
     2057{
     2058    RT_NOREF(pDevIns, pThis, iReg);
     2059    pThis->DevTabBaseAddr.u64 = u64Value & IOMMU_DEV_TAB_BAR_VALID_MASK;
     2060    return VINF_SUCCESS;
     2061}
     2062
     2063
     2064/**
     2065 * Writes the Command Buffer Base Address Register.
     2066 */
     2067static VBOXSTRICTRC iommuAmdCmdBufBar_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t  u64Value)
     2068{
     2069    RT_NOREF(pDevIns, pThis, iReg);
     2070    pThis->CmdBufBaseAddr.u64 = u64Value & IOMMU_CMD_BUF_BAR_VALID_MASK;
     2071
     2072#ifdef VBOX_STRICT
     2073    uint32_t cEntries;
     2074    uint8_t const uLen = pThis->CmdBufBaseAddr.n.u4CmdLen;
     2075    iommuAmdDecodeBufferLength(uLen, &cEntries, NULL /* pcbBuffer */);
     2076    if (!cEntries)
     2077        Log((IOMMU_LOG_PFX ": iommuAmdCmdBufBar_w: Invalid length %#x\n", uLen));
     2078#endif
     2079    return VINF_SUCCESS;
     2080}
     2081
     2082/**
     2083 * Writes the Event Log Base Address Register.
     2084 */
     2085static VBOXSTRICTRC iommuAmdEvtLogBar_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t  u64Value)
     2086{
     2087    RT_NOREF(pDevIns, pThis, iReg);
     2088    pThis->EvtLogBaseAddr.u64 = u64Value & IOMMU_EVT_LOG_BAR_VALID_MASK;
     2089
     2090#ifdef VBOX_STRICT
     2091    uint32_t cEntries;
     2092    uint8_t const uLen = pThis->EvtLogBaseAddr.n.u4EvtLen;
     2093    iommuAmdDecodeBufferLength(uLen, &cEntries, NULL /* pcbBuffer */);
     2094    if (!cEntries)
     2095        Log((IOMMU_LOG_PFX ": iommuAmdEvtLogBar_w: Invalid length %#x\n", uLen));
     2096#endif
     2097    return VINF_SUCCESS;
     2098}
     2099
     2100
     2101#if 0
     2102/**
     2103 * Table 0: Registers-access table.
     2104 */
     2105static const IOMMUREGACC g_aTable0Regs[] =
     2106{
     2107
     2108};
     2109
     2110/**
     2111 * Table 1: Registers-access table.
     2112 */
     2113static const IOMMUREGACC g_aTable1Regs[] =
     2114{
     2115};
     2116#endif
     2117
     2118/**
     2119 * Writes an IOMMU register (32-bit and 64-bit).
     2120 *
     2121 * @returns Strict VBox status code.
     2122 * @param   pDevIns     The device instance.
     2123 * @param   off         Offset in bytes.
     2124 * @param   cb          The size of the write access.
     2125 * @param   uValue      The value being written.
     2126 */
     2127static VBOXSTRICTRC iommuAmdWriteRegister(PPDMDEVINS pDevIns, uint32_t off, uint8_t cb, uint64_t uValue)
     2128{
     2129    Assert(off < IOMMU_MMIO_REGION_SIZE);
     2130    Assert(cb == 4 || cb == 8);
     2131    Assert(!(off & (cb - 1)));
     2132
     2133    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     2134    Assert(pThis);
     2135
     2136    VBOXSTRICTRC rcStrict;
    19952137    switch (off)
    19962138    {
    1997         case IOMMU_MMIO_OFF_DEV_TAB_BAR:          *puResult = pThis->DevTabBaseAddr.u64;        break;
    1998         case IOMMU_MMIO_OFF_CMD_BUF_BAR:          *puResult = pThis->CmdBufBaseAddr.u64;        break;
    1999         case IOMMU_MMIO_OFF_EVT_LOG_BAR:          *puResult = pThis->EvtLogBaseAddr.u64;        break;
    2000         case IOMMU_MMIO_OFF_CTRL:                 *puResult = pThis->Ctrl.u64;                  break;
    2001         case IOMMU_MMIO_OFF_EXCL_BAR:             *puResult = pThis->ExclRangeBaseAddr.u64;     break;
    2002         case IOMMU_MMIO_OFF_EXCL_RANGE_LIMIT:     *puResult = pThis->ExclRangeLimit.u64;        break;
    2003         case IOMMU_MMIO_OFF_EXT_FEAT:             *puResult = pThis->ExtFeat.u64;               break;
    2004 
    2005         case IOMMU_MMIO_OFF_PPR_LOG_BAR:          *puResult = pThis->PprLogBaseAddr.u64;        break;
    2006         case IOMMU_MMIO_OFF_HW_EVT_HI:            *puResult = pThis->HwEvtHi.u64;               break;
    2007         case IOMMU_MMIO_OFF_HW_EVT_LO:            *puResult = pThis->HwEvtLo;                   break;
    2008         case IOMMU_MMIO_OFF_HW_EVT_STATUS:        *puResult = pThis->HwEvtStatus.u64;           break;
    2009 
    2010         case IOMMU_MMIO_OFF_GALOG_BAR:            *puResult = pThis->GALogBaseAddr.u64;         break;
    2011         case IOMMU_MMIO_OFF_GALOG_TAIL_ADDR:      *puResult = pThis->GALogTailAddr.u64;         break;
    2012 
    2013         case IOMMU_MMIO_OFF_PPR_LOG_B_BAR:        *puResult = pThis->PprLogBBaseAddr.u64;       break;
    2014         case IOMMU_MMIO_OFF_PPR_EVT_B_BAR:        *puResult = pThis->EvtLogBBaseAddr.u64;       break;
     2139        case IOMMU_MMIO_OFF_DEV_TAB_BAR:        return iommuAmdDevTabBar_w(pDevIns, pThis, off, uValue);
     2140        case IOMMU_MMIO_OFF_CMD_BUF_BAR:        return iommuAmdCmdBufBar_w(pDevIns, pThis, off, uValue);
     2141        case IOMMU_MMIO_OFF_EVT_LOG_BAR:        return iommuAmdEvtLogBar_w(pDevIns, pThis, off,  uValue);
     2142        case IOMMU_MMIO_OFF_CTRL:
     2143        case IOMMU_MMIO_OFF_EXCL_BAR:
     2144        case IOMMU_MMIO_OFF_EXCL_RANGE_LIMIT:
     2145        case IOMMU_MMIO_OFF_EXT_FEAT:
     2146
     2147        case IOMMU_MMIO_OFF_PPR_LOG_BAR:
     2148        case IOMMU_MMIO_OFF_HW_EVT_HI:
     2149        case IOMMU_MMIO_OFF_HW_EVT_LO:
     2150        case IOMMU_MMIO_OFF_HW_EVT_STATUS:
     2151
     2152        case IOMMU_MMIO_OFF_GALOG_BAR:
     2153        case IOMMU_MMIO_OFF_GALOG_TAIL_ADDR:
     2154
     2155        case IOMMU_MMIO_OFF_PPR_LOG_B_BAR:
     2156        case IOMMU_MMIO_OFF_PPR_EVT_B_BAR:
    20152157
    20162158        case IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST:
     
    20192161            uint8_t const idxDevTabSeg = (off - IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST) >> 3;
    20202162            Assert(idxDevTabSeg < RT_ELEMENTS(pThis->DevTabSeg));
    2021             *puResult = pThis->DevTabSeg[idxDevTabSeg].u64;
    20222163            break;
    20232164        }
    20242165
    2025         case IOMMU_MMIO_OFF_DEV_SPECIFIC_FEAT:    *puResult = pThis->DevSpecificFeat.u64;       break;
    2026         case IOMMU_MMIO_OFF_DEV_SPECIFIC_CTRL:    *puResult = pThis->DevSpecificCtrl.u64;       break;
    2027         case IOMMU_MMIO_OFF_DEV_SPECIFIC_STATUS:  *puResult = pThis->DevSpecificStatus.u64;     break;
    2028 
    2029         case IOMMU_MMIO_OFF_MSI_VECTOR_0:         *puResult = pThis->MsiMiscInfo.u64;           break;
    2030         case IOMMU_MMIO_OFF_MSI_VECTOR_1:         *puResult = pThis->MsiMiscInfo.au32[1];       break;
    2031         case IOMMU_MMIO_OFF_MSI_CAP_HDR:          *puResult = RT_MAKE_U64(pThis->MsiCapHdr.u32, pThis->MsiAddr.au32[0]);    break;
    2032         case IOMMU_MMIO_OFF_MSI_ADDR_LO:          *puResult = pThis->MsiAddr.au32[0];           break;
    2033         case IOMMU_MMIO_OFF_MSI_ADDR_HI:          *puResult = RT_MAKE_U64(pThis->MsiAddr.au32[1], pThis->MsiData.u32);      break;
    2034         case IOMMU_MMIO_OFF_MSI_DATA:             *puResult = pThis->MsiData.u32;               break;
    2035         case IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR:  *puResult = RT_MAKE_U64(pThis->MsiMapCapHdr.u32, pThis->PerfOptCtrl.u32); break;
    2036 
    2037         case IOMMU_MMIO_OFF_PERF_OPT_CTRL:        *puResult = pThis->PerfOptCtrl.u32;           break;
    2038 
    2039         case IOMMU_MMIO_OFF_XT_GEN_INTR_CTRL:     *puResult = pThis->XtGenIntrCtrl.u64;         break;
    2040         case IOMMU_MMIO_OFF_XT_PPR_INTR_CTRL:     *puResult = pThis->XtPprIntrCtrl.u64;         break;
    2041         case IOMMU_MMIO_OFF_XT_GALOG_INT_CTRL:    *puResult = pThis->XtGALogIntrCtrl.u64;       break;
    2042 
    2043         case IOMMU_MMIO_OFF_MARC_APER_BAR_0:      *puResult = pThis->aMarcApers[0].Base.u64;    break;
    2044         case IOMMU_MMIO_OFF_MARC_APER_RELOC_0:    *puResult = pThis->aMarcApers[0].Reloc.u64;   break;
    2045         case IOMMU_MMIO_OFF_MARC_APER_LEN_0:      *puResult = pThis->aMarcApers[0].Length.u64;  break;
    2046         case IOMMU_MMIO_OFF_MARC_APER_BAR_1:      *puResult = pThis->aMarcApers[1].Base.u64;    break;
    2047         case IOMMU_MMIO_OFF_MARC_APER_RELOC_1:    *puResult = pThis->aMarcApers[1].Reloc.u64;   break;
    2048         case IOMMU_MMIO_OFF_MARC_APER_LEN_1:      *puResult = pThis->aMarcApers[1].Length.u64;  break;
    2049         case IOMMU_MMIO_OFF_MARC_APER_BAR_2:      *puResult = pThis->aMarcApers[2].Base.u64;    break;
    2050         case IOMMU_MMIO_OFF_MARC_APER_RELOC_2:    *puResult = pThis->aMarcApers[2].Reloc.u64;   break;
    2051         case IOMMU_MMIO_OFF_MARC_APER_LEN_2:      *puResult = pThis->aMarcApers[2].Length.u64;  break;
    2052         case IOMMU_MMIO_OFF_MARC_APER_BAR_3:      *puResult = pThis->aMarcApers[3].Base.u64;    break;
    2053         case IOMMU_MMIO_OFF_MARC_APER_RELOC_3:    *puResult = pThis->aMarcApers[3].Reloc.u64;   break;
    2054         case IOMMU_MMIO_OFF_MARC_APER_LEN_3:      *puResult = pThis->aMarcApers[3].Length.u64;  break;
    2055 
    2056         case IOMMU_MMIO_OFF_RSVD_REG:             *puResult = pThis->RsvdReg;                   break;
    2057 
    2058         case IOMMU_MMIO_CMD_BUF_HEAD_PTR:         *puResult = pThis->CmdBufHeadPtr.u64;         break;
    2059         case IOMMU_MMIO_CMD_BUF_TAIL_PTR:         *puResult = pThis->CmdBufTailPtr.u64;         break;
    2060         case IOMMU_MMIO_EVT_LOG_HEAD_PTR:         *puResult = pThis->EvtLogHeadPtr.u64;         break;
    2061         case IOMMU_MMIO_EVT_LOG_TAIL_PTR:         *puResult = pThis->EvtLogTailPtr.u64;         break;
    2062 
    2063         case IOMMU_MMIO_OFF_STATUS:               *puResult = pThis->Status.u64;                break;
    2064 
    2065         case IOMMU_MMIO_OFF_PPR_LOG_HEAD_PTR:     *puResult = pThis->PprLogHeadPtr.u64;         break;
    2066         case IOMMU_MMIO_OFF_PPR_LOG_TAIL_PTR:     *puResult = pThis->PprLogTailPtr.u64;         break;
    2067 
    2068         case IOMMU_MMIO_OFF_GALOG_HEAD_PTR:       *puResult = pThis->GALogHeadPtr.u64;          break;
    2069         case IOMMU_MMIO_OFF_GALOG_TAIL_PTR:       *puResult = pThis->GALogTailPtr.u64;          break;
    2070 
    2071         case IOMMU_MMIO_OFF_PPR_LOG_B_HEAD_PTR:   *puResult = pThis->PprLogBHeadPtr.u64;        break;
    2072         case IOMMU_MMIO_OFF_PPR_LOG_B_TAIL_PTR:   *puResult = pThis->PprLogBTailPtr.u64;        break;
    2073 
    2074         case IOMMU_MMIO_OFF_EVT_LOG_B_HEAD_PTR:   *puResult = pThis->EvtLogBHeadPtr.u64;        break;
    2075         case IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR:   *puResult = pThis->EvtLogBTailPtr.u64;        break;
    2076 
    2077         case IOMMU_MMIO_OFF_PPR_LOG_AUTO_RESP:          *puResult = pThis->PprLogAutoResp.u64;          break;
    2078         case IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY:     *puResult = pThis->PprLogOverflowEarly.u64;     break;
    2079         case IOMMU_MMIO_OFF_PPR_LOG_B_OVERFLOW_EARLY:   *puResult = pThis->PprLogBOverflowEarly.u64;    break;
     2166        case IOMMU_MMIO_OFF_DEV_SPECIFIC_FEAT:
     2167        case IOMMU_MMIO_OFF_DEV_SPECIFIC_CTRL:
     2168        case IOMMU_MMIO_OFF_DEV_SPECIFIC_STATUS:
     2169
     2170        case IOMMU_MMIO_OFF_MSI_VECTOR_0:
     2171        case IOMMU_MMIO_OFF_MSI_VECTOR_1:
     2172        case IOMMU_MMIO_OFF_MSI_CAP_HDR:
     2173        case IOMMU_MMIO_OFF_MSI_ADDR_LO:
     2174        case IOMMU_MMIO_OFF_MSI_ADDR_HI:
     2175        case IOMMU_MMIO_OFF_MSI_DATA:
     2176        case IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR:
     2177
     2178        case IOMMU_MMIO_OFF_PERF_OPT_CTRL:
     2179
     2180        case IOMMU_MMIO_OFF_XT_GEN_INTR_CTRL:
     2181        case IOMMU_MMIO_OFF_XT_PPR_INTR_CTRL:
     2182        case IOMMU_MMIO_OFF_XT_GALOG_INT_CTRL:
     2183
     2184        case IOMMU_MMIO_OFF_MARC_APER_BAR_0:
     2185        case IOMMU_MMIO_OFF_MARC_APER_RELOC_0:
     2186        case IOMMU_MMIO_OFF_MARC_APER_LEN_0:
     2187        case IOMMU_MMIO_OFF_MARC_APER_BAR_1:
     2188        case IOMMU_MMIO_OFF_MARC_APER_RELOC_1:
     2189        case IOMMU_MMIO_OFF_MARC_APER_LEN_1:
     2190        case IOMMU_MMIO_OFF_MARC_APER_BAR_2:
     2191        case IOMMU_MMIO_OFF_MARC_APER_RELOC_2:
     2192        case IOMMU_MMIO_OFF_MARC_APER_LEN_2:
     2193        case IOMMU_MMIO_OFF_MARC_APER_BAR_3:
     2194        case IOMMU_MMIO_OFF_MARC_APER_RELOC_3:
     2195        case IOMMU_MMIO_OFF_MARC_APER_LEN_3:
     2196
     2197        case IOMMU_MMIO_OFF_RSVD_REG:
     2198
     2199        case IOMMU_MMIO_CMD_BUF_HEAD_PTR:
     2200        case IOMMU_MMIO_CMD_BUF_TAIL_PTR:
     2201        case IOMMU_MMIO_EVT_LOG_HEAD_PTR:
     2202        case IOMMU_MMIO_EVT_LOG_TAIL_PTR:
     2203
     2204        case IOMMU_MMIO_OFF_STATUS:
     2205
     2206        case IOMMU_MMIO_OFF_PPR_LOG_HEAD_PTR:
     2207        case IOMMU_MMIO_OFF_PPR_LOG_TAIL_PTR:
     2208
     2209        case IOMMU_MMIO_OFF_GALOG_HEAD_PTR:
     2210        case IOMMU_MMIO_OFF_GALOG_TAIL_PTR:
     2211
     2212        case IOMMU_MMIO_OFF_PPR_LOG_B_HEAD_PTR:
     2213        case IOMMU_MMIO_OFF_PPR_LOG_B_TAIL_PTR:
     2214
     2215        case IOMMU_MMIO_OFF_EVT_LOG_B_HEAD_PTR:
     2216        case IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR:
     2217
     2218        case IOMMU_MMIO_OFF_PPR_LOG_AUTO_RESP:
     2219        case IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY:
     2220        case IOMMU_MMIO_OFF_PPR_LOG_B_OVERFLOW_EARLY:
     2221
     2222        /* Not implemented. */
     2223        case IOMMU_MMIO_OFF_SMI_FLT_FIRST:
     2224        case IOMMU_MMIO_OFF_SMI_FLT_LAST:
     2225        {
     2226            Log((IOMMU_LOG_PFX ": iommuAmdWriteRegister: Writing unsupported register: SMI filter %u -> Ignored\n",
     2227                 (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3));
     2228            rcStrict = VINF_SUCCESS;
     2229            break;
     2230        }
     2231
     2232        /* Unknown. */
     2233        default:
     2234        {
     2235            Log((IOMMU_LOG_PFX ": iommuAmdWriteRegister: Trying to write unknown register at %u (%#x) with %#RX64\n", off, off,
     2236                 uValue));
     2237            rcStrict = VINF_SUCCESS;
     2238            break;
     2239        }
     2240    }
     2241
     2242    return rcStrict;
     2243}
     2244
     2245
     2246/**
     2247 * Reads an IOMMU register (64-bit).
     2248 *
     2249 * All reads are 64-bit but reads to 32-bit registers that are aligned on an 8-byte
     2250 * boundary include the lower half of the subsequent register.
     2251 *
     2252 * This is because most registers are 64-bit and aligned on 8-byte boundaries but
     2253 * some are really 32-bit registers aligned on an 8-byte boundary. We cannot assume
     2254 * guests will only perform 32-bit reads on those 32-bit registers that are aligned
     2255 * on 8-byte boundaries.
     2256 *
     2257 * @returns Strict VBox status code.
     2258 * @param   pThis       The IOMMU device state.
     2259 * @param   off         Offset in bytes.
     2260 * @param   puResult    Where to store the value being read.
     2261 */
     2262static VBOXSTRICTRC iommuAmdReadRegister(PCIOMMU pThis, uint32_t off, uint64_t *puResult)
     2263{
     2264    Assert(off < IOMMU_MMIO_REGION_SIZE);
     2265    Assert(!(off & 7) || !(off & 3));
     2266
     2267    /** @todo IOMMU: fine-grained locking? */
     2268    uint64_t uReg;
     2269    switch (off)
     2270    {
     2271        case IOMMU_MMIO_OFF_DEV_TAB_BAR:              uReg = pThis->DevTabBaseAddr.u64;         break;
     2272        case IOMMU_MMIO_OFF_CMD_BUF_BAR:              uReg = pThis->CmdBufBaseAddr.u64;         break;
     2273        case IOMMU_MMIO_OFF_EVT_LOG_BAR:              uReg = pThis->EvtLogBaseAddr.u64;         break;
     2274        case IOMMU_MMIO_OFF_CTRL:                     uReg = pThis->Ctrl.u64;                   break;
     2275        case IOMMU_MMIO_OFF_EXCL_BAR:                 uReg = pThis->ExclRangeBaseAddr.u64;      break;
     2276        case IOMMU_MMIO_OFF_EXCL_RANGE_LIMIT:         uReg = pThis->ExclRangeLimit.u64;         break;
     2277        case IOMMU_MMIO_OFF_EXT_FEAT:                 uReg = pThis->ExtFeat.u64;                break;
     2278
     2279        case IOMMU_MMIO_OFF_PPR_LOG_BAR:              uReg = pThis->PprLogBaseAddr.u64;         break;
     2280        case IOMMU_MMIO_OFF_HW_EVT_HI:                uReg = pThis->HwEvtHi.u64;                break;
     2281        case IOMMU_MMIO_OFF_HW_EVT_LO:                uReg = pThis->HwEvtLo;                    break;
     2282        case IOMMU_MMIO_OFF_HW_EVT_STATUS:            uReg = pThis->HwEvtStatus.u64;            break;
     2283
     2284        case IOMMU_MMIO_OFF_GALOG_BAR:                uReg = pThis->GALogBaseAddr.u64;          break;
     2285        case IOMMU_MMIO_OFF_GALOG_TAIL_ADDR:          uReg = pThis->GALogTailAddr.u64;          break;
     2286
     2287        case IOMMU_MMIO_OFF_PPR_LOG_B_BAR:            uReg = pThis->PprLogBBaseAddr.u64;        break;
     2288        case IOMMU_MMIO_OFF_PPR_EVT_B_BAR:            uReg = pThis->EvtLogBBaseAddr.u64;        break;
     2289
     2290        case IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST:
     2291        case IOMMU_MMIO_OFF_DEV_TAB_SEG_LAST:
     2292        {
     2293            uint8_t const idxDevTabSeg = (off - IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST) >> 3;
     2294            Assert(idxDevTabSeg < RT_ELEMENTS(pThis->DevTabSeg));
     2295            uReg = pThis->DevTabSeg[idxDevTabSeg].u64;
     2296            break;
     2297        }
     2298
     2299        case IOMMU_MMIO_OFF_DEV_SPECIFIC_FEAT:        uReg = pThis->DevSpecificFeat.u64;        break;
     2300        case IOMMU_MMIO_OFF_DEV_SPECIFIC_CTRL:        uReg = pThis->DevSpecificCtrl.u64;        break;
     2301        case IOMMU_MMIO_OFF_DEV_SPECIFIC_STATUS:      uReg = pThis->DevSpecificStatus.u64;      break;
     2302
     2303        case IOMMU_MMIO_OFF_MSI_VECTOR_0:             uReg = pThis->MsiMiscInfo.u64;            break;
     2304        case IOMMU_MMIO_OFF_MSI_VECTOR_1:             uReg = pThis->MsiMiscInfo.au32[1];        break;
     2305        case IOMMU_MMIO_OFF_MSI_CAP_HDR:              uReg = RT_MAKE_U64(pThis->MsiCapHdr.u32, pThis->MsiAddr.au32[0]);     break;
     2306        case IOMMU_MMIO_OFF_MSI_ADDR_LO:              uReg = pThis->MsiAddr.au32[0];            break;
     2307        case IOMMU_MMIO_OFF_MSI_ADDR_HI:              uReg = RT_MAKE_U64(pThis->MsiAddr.au32[1], pThis->MsiData.u32);       break;
     2308        case IOMMU_MMIO_OFF_MSI_DATA:                 uReg = pThis->MsiData.u32;                break;
     2309        case IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR:      uReg = RT_MAKE_U64(pThis->MsiMapCapHdr.u32, pThis->PerfOptCtrl.u32);  break;
     2310
     2311        case IOMMU_MMIO_OFF_PERF_OPT_CTRL:            uReg = pThis->PerfOptCtrl.u32;            break;
     2312
     2313        case IOMMU_MMIO_OFF_XT_GEN_INTR_CTRL:         uReg = pThis->XtGenIntrCtrl.u64;          break;
     2314        case IOMMU_MMIO_OFF_XT_PPR_INTR_CTRL:         uReg = pThis->XtPprIntrCtrl.u64;          break;
     2315        case IOMMU_MMIO_OFF_XT_GALOG_INT_CTRL:        uReg = pThis->XtGALogIntrCtrl.u64;        break;
     2316
     2317        case IOMMU_MMIO_OFF_MARC_APER_BAR_0:          uReg = pThis->aMarcApers[0].Base.u64;     break;
     2318        case IOMMU_MMIO_OFF_MARC_APER_RELOC_0:        uReg = pThis->aMarcApers[0].Reloc.u64;    break;
     2319        case IOMMU_MMIO_OFF_MARC_APER_LEN_0:          uReg = pThis->aMarcApers[0].Length.u64;   break;
     2320        case IOMMU_MMIO_OFF_MARC_APER_BAR_1:          uReg = pThis->aMarcApers[1].Base.u64;     break;
     2321        case IOMMU_MMIO_OFF_MARC_APER_RELOC_1:        uReg = pThis->aMarcApers[1].Reloc.u64;    break;
     2322        case IOMMU_MMIO_OFF_MARC_APER_LEN_1:          uReg = pThis->aMarcApers[1].Length.u64;   break;
     2323        case IOMMU_MMIO_OFF_MARC_APER_BAR_2:          uReg = pThis->aMarcApers[2].Base.u64;     break;
     2324        case IOMMU_MMIO_OFF_MARC_APER_RELOC_2:        uReg = pThis->aMarcApers[2].Reloc.u64;    break;
     2325        case IOMMU_MMIO_OFF_MARC_APER_LEN_2:          uReg = pThis->aMarcApers[2].Length.u64;   break;
     2326        case IOMMU_MMIO_OFF_MARC_APER_BAR_3:          uReg = pThis->aMarcApers[3].Base.u64;     break;
     2327        case IOMMU_MMIO_OFF_MARC_APER_RELOC_3:        uReg = pThis->aMarcApers[3].Reloc.u64;    break;
     2328        case IOMMU_MMIO_OFF_MARC_APER_LEN_3:          uReg = pThis->aMarcApers[3].Length.u64;   break;
     2329
     2330        case IOMMU_MMIO_OFF_RSVD_REG:                 uReg = pThis->RsvdReg;                    break;
     2331
     2332        case IOMMU_MMIO_CMD_BUF_HEAD_PTR:             uReg = pThis->CmdBufHeadPtr.u64;          break;
     2333        case IOMMU_MMIO_CMD_BUF_TAIL_PTR:             uReg = pThis->CmdBufTailPtr.u64;          break;
     2334        case IOMMU_MMIO_EVT_LOG_HEAD_PTR:             uReg = pThis->EvtLogHeadPtr.u64;          break;
     2335        case IOMMU_MMIO_EVT_LOG_TAIL_PTR:             uReg = pThis->EvtLogTailPtr.u64;          break;
     2336
     2337        case IOMMU_MMIO_OFF_STATUS:                   uReg = pThis->Status.u64;                 break;
     2338
     2339        case IOMMU_MMIO_OFF_PPR_LOG_HEAD_PTR:         uReg = pThis->PprLogHeadPtr.u64;          break;
     2340        case IOMMU_MMIO_OFF_PPR_LOG_TAIL_PTR:         uReg = pThis->PprLogTailPtr.u64;          break;
     2341
     2342        case IOMMU_MMIO_OFF_GALOG_HEAD_PTR:           uReg = pThis->GALogHeadPtr.u64;           break;
     2343        case IOMMU_MMIO_OFF_GALOG_TAIL_PTR:           uReg = pThis->GALogTailPtr.u64;           break;
     2344
     2345        case IOMMU_MMIO_OFF_PPR_LOG_B_HEAD_PTR:       uReg = pThis->PprLogBHeadPtr.u64;         break;
     2346        case IOMMU_MMIO_OFF_PPR_LOG_B_TAIL_PTR:       uReg = pThis->PprLogBTailPtr.u64;         break;
     2347
     2348        case IOMMU_MMIO_OFF_EVT_LOG_B_HEAD_PTR:       uReg = pThis->EvtLogBHeadPtr.u64;         break;
     2349        case IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR:       uReg = pThis->EvtLogBTailPtr.u64;         break;
     2350
     2351        case IOMMU_MMIO_OFF_PPR_LOG_AUTO_RESP:        uReg = pThis->PprLogAutoResp.u64;         break;
     2352        case IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY:   uReg = pThis->PprLogOverflowEarly.u64;    break;
     2353        case IOMMU_MMIO_OFF_PPR_LOG_B_OVERFLOW_EARLY: uReg = pThis->PprLogBOverflowEarly.u64;   break;
    20802354
    20812355        /* Not implemented. */
     
    20852359            Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Reading unsupported register: SMI filter %u\n",
    20862360                 (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3));
    2087             *puResult = 0;
     2361            uReg = 0;
    20882362            break;
    20892363        }
    20902364
    2091         /* Unknown */
     2365        /* Unknown. */
    20922366        default:
    20932367        {
    20942368            Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Trying to read unknown register at %u (%#x)\n", off, off));
    2095             *puResult = 0;
     2369            uReg = 0;
    20962370            return VINF_IOM_MMIO_UNUSED_00;
    20972371        }
    20982372    }
     2373
     2374    *puResult = uReg;
    20992375    return VINF_SUCCESS;
    21002376}
    21012377
    2102 
    21032378/**
    21042379 * @callback_method_impl{FNIOMMMIONEWWRITE}
    21052380 */
    21062381static DECLCALLBACK(VBOXSTRICTRC) iommuAmdMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    2107 {
    2108     /** @todo IOMMU: MMIO write. */
    2109     RT_NOREF5(pDevIns, pvUser, off, pv, cb);
    2110     return VERR_NOT_IMPLEMENTED;
    2111 }
    2112 
    2113 
    2114 /**
    2115  * @callback_method_impl{FNIOMMMIONEWREAD}
    2116  */
    2117 static DECLCALLBACK(VBOXSTRICTRC) iommuAmdMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    21182382{
    21192383    NOREF(pvUser);
    21202384    Assert(cb == 4 || cb == 8);
    2121     Assert(cb == 4 || !(off & 7));
    2122     Assert(cb == 8 || !(off & 3));
    2123 
    2124     uint64_t uResult  = 0;
     2385    Assert(!(off & (cb - 1)));
     2386
     2387    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     2388    uint64_t const uValue = cb == 8 ? *(uint64_t const *)pv : *(uint32_t const *)pv;
     2389    return iommuAmdWriteRegister(pDevIns, off, cb, uValue);
     2390}
     2391
     2392
     2393/**
     2394 * @callback_method_impl{FNIOMMMIONEWREAD}
     2395 */
     2396static DECLCALLBACK(VBOXSTRICTRC) iommuAmdMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
     2397{
     2398    NOREF(pvUser);
     2399    Assert(cb == 4 || cb == 8);
     2400    Assert(!(off & (cb - 1)));
     2401
     2402    uint64_t uResult;
    21252403    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    21262404    VBOXSTRICTRC rcStrict = iommuAmdReadRegister(pThis, off, &uResult);
     
    21352413
    21362414# ifdef IN_RING3
    2137 static void iommuAmdR3DecodeBufferLength(uint8_t uEncodedLen, uint32_t *pcEntries, uint32_t *pcbBuffer)
    2138 {
    2139     if (uEncodedLen >= 8)
    2140     {
    2141         *pcEntries = 2 << (uEncodedLen - 1);
    2142         *pcbBuffer = *pcEntries << 4;
    2143     }
    2144     else
    2145     {
    2146         *pcEntries = 0;
    2147         *pcbBuffer = 0;
    2148     }
    2149 }
    2150 
    21512415
    21522416/**
     
    22272491        uint32_t      cbBuffer;
    22282492        uint8_t const uEncodedLen = CmdBufBar.n.u4CmdLen;
    2229         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2493        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    22302494        pHlp->pfnPrintf(pHlp, "  Command buffer BAR                      = %#RX64\n", CmdBufBar.u64);
    22312495        if (fVerbose)
     
    22422506        uint32_t      cbBuffer;
    22432507        uint8_t const uEncodedLen = EvtLogBar.n.u4EvtLen;
    2244         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2508        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    22452509        pHlp->pfnPrintf(pHlp, "  Event log BAR                           = %#RX64\n", EvtLogBar.u64);
    22462510        if (fVerbose)
     
    23632627        uint32_t      cbBuffer;
    23642628        uint8_t const uEncodedLen = PprLogBar.n.u4PprLogLen;
    2365         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2629        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    23662630        pHlp->pfnPrintf(pHlp, "  PPR Log BAR                             = %#RX64\n",   PprLogBar.u64);
    23672631        if (fVerbose)
     
    24002664        uint32_t      cbBuffer;
    24012665        uint8_t const uEncodedLen = GALogBar.n.u4GALogLen;
    2402         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2666        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    24032667        pHlp->pfnPrintf(pHlp, "  Guest Log BAR                           = %#RX64\n",    GALogBar.u64);
    24042668        if (fVerbose)
     
    24222686        uint32_t      cbBuffer;
    24232687        uint8_t const uEncodedLen = PprLogBBar.n.u4PprLogLen;
    2424         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2688        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    24252689        pHlp->pfnPrintf(pHlp, "  PPR Log B BAR                           = %#RX64\n",   PprLogBBar.u64);
    24262690        if (fVerbose)
     
    24372701        uint32_t      cbBuffer;
    24382702        uint8_t const uEncodedLen = EvtLogBBar.n.u4EvtLen;
    2439         iommuAmdR3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
     2703        iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);
    24402704        pHlp->pfnPrintf(pHlp, "  Event Log B BAR                         = %#RX64\n",   EvtLogBBar.u64);
    24412705        if (fVerbose)
     
    28403104    PDMPciDevSetInterruptPin(pPciDev,       0x01);                    /* INTA#. */
    28413105    PDMPciDevSetInterruptLine(pPciDev,      0x00);                    /* For software compatibility; no effect on hardware. */
    2842 
    28433106    /* Capability Header. */
    28443107    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_CAP_HDR,
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