Changeset 83649 in vbox for trunk/src/VBox
- Timestamp:
- Apr 9, 2020 2:04:15 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137110
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r83619 r83649 31 31 * Defined Constants And Macros * 32 32 *********************************************************************************************************************************/ 33 /** @name PCI configuration register offsets. 34 @{ */ 33 /** 34 * @name PCI configuration register offsets. 35 * In accordance with the AMD spec. 36 * @{ 37 */ 35 38 #define IOMMU_PCI_OFF_CAP_HDR 0x40 36 39 #define IOMMU_PCI_OFF_BASE_ADDR_REG_LO 0x44 … … 46 49 /** @} */ 47 50 48 /** @name MMIO register offsets. 49 * @{ */ 51 /** 52 * @name MMIO register offsets. 53 * In accordance with the AMD spec. 54 * @{ 55 */ 50 56 #define IOMMU_MMIO_OFF_DEV_TAB_BAR 0x00 51 57 #define IOMMU_MMIO_OFF_CMD_BUF_BAR 0x08 … … 128 134 #define IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY 0x2088 129 135 #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 130 150 /** @} */ 131 151 … … 995 1015 } DEV_TAB_BAR_T; 996 1016 AssertCompileSize(DEV_TAB_BAR_T, 8); 1017 #define IOMMU_DEV_TAB_BAR_VALID_MASK UINT64_C(0x000ffffffffff3ff) 997 1018 998 1019 /** … … 1014 1035 } CMD_BUF_BAR_T; 1015 1036 AssertCompileSize(CMD_BUF_BAR_T, 8); 1037 #define IOMMU_CMD_BUF_BAR_VALID_MASK UINT64_C(0x0f0ffffffffff000) 1016 1038 1017 1039 /** … … 1033 1055 } EVT_LOG_BAR_T; 1034 1056 AssertCompileSize(EVT_LOG_BAR_T, 8); 1057 #define IOMMU_EVT_LOG_BAR_VALID_MASK UINT64_C(0x0f0ffffffffff000) 1035 1058 1036 1059 /** … … 1984 2007 typedef CTX_SUFF(PIOMMU) PIOMMUCC; 1985 2008 2009 /** 2010 * IOMMU register access routines. 2011 */ 2012 typedef 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 1986 2020 1987 2021 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 1988 2022 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 */ 2034 static 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 */ 2056 static 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 */ 2067 static 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 */ 2085 static 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 */ 2105 static const IOMMUREGACC g_aTable0Regs[] = 2106 { 2107 2108 }; 2109 2110 /** 2111 * Table 1: Registers-access table. 2112 */ 2113 static 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 */ 2127 static 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; 1995 2137 switch (off) 1996 2138 { 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: 2015 2157 2016 2158 case IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST: … … 2019 2161 uint8_t const idxDevTabSeg = (off - IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST) >> 3; 2020 2162 Assert(idxDevTabSeg < RT_ELEMENTS(pThis->DevTabSeg)); 2021 *puResult = pThis->DevTabSeg[idxDevTabSeg].u64;2022 2163 break; 2023 2164 } 2024 2165 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 */ 2262 static 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; 2080 2354 2081 2355 /* Not implemented. */ … … 2085 2359 Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Reading unsupported register: SMI filter %u\n", 2086 2360 (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3)); 2087 *puResult= 0;2361 uReg = 0; 2088 2362 break; 2089 2363 } 2090 2364 2091 /* Unknown */2365 /* Unknown. */ 2092 2366 default: 2093 2367 { 2094 2368 Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Trying to read unknown register at %u (%#x)\n", off, off)); 2095 *puResult= 0;2369 uReg = 0; 2096 2370 return VINF_IOM_MMIO_UNUSED_00; 2097 2371 } 2098 2372 } 2373 2374 *puResult = uReg; 2099 2375 return VINF_SUCCESS; 2100 2376 } 2101 2377 2102 2103 2378 /** 2104 2379 * @callback_method_impl{FNIOMMMIONEWWRITE} 2105 2380 */ 2106 2381 static 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)2118 2382 { 2119 2383 NOREF(pvUser); 2120 2384 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 */ 2396 static 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; 2125 2403 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 2126 2404 VBOXSTRICTRC rcStrict = iommuAmdReadRegister(pThis, off, &uResult); … … 2135 2413 2136 2414 # 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 else2145 {2146 *pcEntries = 0;2147 *pcbBuffer = 0;2148 }2149 }2150 2151 2415 2152 2416 /** … … 2227 2491 uint32_t cbBuffer; 2228 2492 uint8_t const uEncodedLen = CmdBufBar.n.u4CmdLen; 2229 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2493 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2230 2494 pHlp->pfnPrintf(pHlp, " Command buffer BAR = %#RX64\n", CmdBufBar.u64); 2231 2495 if (fVerbose) … … 2242 2506 uint32_t cbBuffer; 2243 2507 uint8_t const uEncodedLen = EvtLogBar.n.u4EvtLen; 2244 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2508 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2245 2509 pHlp->pfnPrintf(pHlp, " Event log BAR = %#RX64\n", EvtLogBar.u64); 2246 2510 if (fVerbose) … … 2363 2627 uint32_t cbBuffer; 2364 2628 uint8_t const uEncodedLen = PprLogBar.n.u4PprLogLen; 2365 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2629 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2366 2630 pHlp->pfnPrintf(pHlp, " PPR Log BAR = %#RX64\n", PprLogBar.u64); 2367 2631 if (fVerbose) … … 2400 2664 uint32_t cbBuffer; 2401 2665 uint8_t const uEncodedLen = GALogBar.n.u4GALogLen; 2402 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2666 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2403 2667 pHlp->pfnPrintf(pHlp, " Guest Log BAR = %#RX64\n", GALogBar.u64); 2404 2668 if (fVerbose) … … 2422 2686 uint32_t cbBuffer; 2423 2687 uint8_t const uEncodedLen = PprLogBBar.n.u4PprLogLen; 2424 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2688 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2425 2689 pHlp->pfnPrintf(pHlp, " PPR Log B BAR = %#RX64\n", PprLogBBar.u64); 2426 2690 if (fVerbose) … … 2437 2701 uint32_t cbBuffer; 2438 2702 uint8_t const uEncodedLen = EvtLogBBar.n.u4EvtLen; 2439 iommuAmd R3DecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2703 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2440 2704 pHlp->pfnPrintf(pHlp, " Event Log B BAR = %#RX64\n", EvtLogBBar.u64); 2441 2705 if (fVerbose) … … 2840 3104 PDMPciDevSetInterruptPin(pPciDev, 0x01); /* INTA#. */ 2841 3105 PDMPciDevSetInterruptLine(pPciDev, 0x00); /* For software compatibility; no effect on hardware. */ 2842 2843 3106 /* Capability Header. */ 2844 3107 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_CAP_HDR,
Note:
See TracChangeset
for help on using the changeset viewer.