Changeset 106957 in vbox for trunk/src/VBox/Main/src-client/ResourceAssignmentManager.cpp
- Timestamp:
- Nov 12, 2024 12:09:04 PM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ResourceAssignmentManager.cpp
r106061 r106957 35 35 #include "ResourceAssignmentManager.h" 36 36 37 #include <VBox/com/array.h> 38 37 39 #include <iprt/asm.h> 40 #include <iprt/mem.h> 38 41 #include <iprt/string.h> 39 40 #include <VBox/vmm/cfgm.h>41 #include <VBox/vmm/vmmr3vtable.h>42 #include <VBox/com/array.h>43 44 #include <map>45 #include <vector>46 #include <algorithm>47 42 48 43 … … 50 45 * Structures and Typedefs * 51 46 *********************************************************************************************************************************/ 47 /** 48 * Address space range type. 49 */ 50 typedef enum RESOURCEREGIONTYPE 51 { 52 /** Free region. */ 53 kResourceRegionType_Free = 0, 54 /** RAM. */ 55 kResourceRegionType_Ram, 56 /** ROM. */ 57 kResourceRegionType_Rom, 58 /** MMIO. */ 59 kResourceRegionType_Mmio, 60 /** 32bit hack. */ 61 kResourceRegionType_32Bit_Hack = 0x7fffffff 62 } RESOURCEREGIONTYPE; 63 64 65 /** 66 * Address space range descriptor. 67 */ 68 typedef struct RESOURCEREGION 69 { 70 /** Region name. */ 71 char szName[32]; 72 /** Physical start address of the region. */ 73 RTGCPHYS GCPhysStart; 74 /** Physical end address of the region. */ 75 RTGCPHYS GCPhysEnd; 76 /** Region type. */ 77 RESOURCEREGIONTYPE enmType; 78 /** Padding. */ 79 uint32_t u32Pad; 80 } RESOURCEREGION; 81 AssertCompileSize(RESOURCEREGION, 56); 82 /** Pointer to a resource region. */ 83 typedef RESOURCEREGION *PRESOURCEREGION; 84 /** Pointer to a const resource region. */ 85 typedef const RESOURCEREGION *PCRESOURCEREGION; 52 86 53 87 … … 63 97 struct ResourceAssignmentManager::State 64 98 { 65 struct MemoryRange66 {67 char szDevName[32];68 RTGCPHYS mGCPhysStart;69 RTGCPHYS mGCPhysEnd;70 71 MemoryRange(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS GCPhysEnd)72 {73 RTStrCopy(this->szDevName, sizeof(szDevName), pszName);74 this->mGCPhysStart = GCPhysStart;75 this->mGCPhysEnd = GCPhysEnd;76 }77 78 bool operator==(const MemoryRange &a) const79 {80 return RTStrNCmp(szDevName, a.szDevName, sizeof(szDevName)) == 0;81 }82 };83 84 typedef std::vector<MemoryRange> AddrRangeList;85 86 99 ChipsetType_T mChipsetType; 87 100 IommuType_T mIommuType; 88 PCVMMR3VTABLE mpVMM; 89 AddrRangeList mAddrRanges; 90 91 RTGCPHYS mGCPhysMmioStartOrig; 92 RTGCPHYS mGCPhysMmioStart; 93 RTGCPHYS mGCPhysMmio32StartOrig; 94 RTGCPHYS mGCPhysMmio32Start; 95 RTGCPHYS mcbMmio32; 96 RTGCPHYS mGCPhysRamStart; 101 102 /** Pointer to the array of regions (sorted by address, not overlapping, adjacent). */ 103 PRESOURCEREGION m_paRegions; 104 /** Number of used regions. */ 105 uint32_t m_cRegions; 106 /** Number of regions the allocated array can hold. */ 107 uint32_t m_cRegionsMax; 108 97 109 uint32_t mcInterrupts; 98 110 uint32_t miInterrupt; 99 111 100 112 State() 101 : mChipsetType(ChipsetType_Null), mpVMM(NULL) 113 : mChipsetType(ChipsetType_Null) 114 , mIommuType(IommuType_None) 115 , m_paRegions(NULL) 116 , m_cRegions(0) 117 , m_cRegionsMax(0) 118 , mcInterrupts(0) 119 , miInterrupt(0) 102 120 {} 103 121 ~State() 104 122 {} 105 123 106 HRESULT init(PCVMMR3VTABLE pVMM, ChipsetType_T chipsetType, IommuType_T iommuType, 107 RTGCPHYS GCPhysMmioTop, RTGCPHYS GCPhysRamStart, 108 RTGCPHYS GCPhysMmio32Start, RTGCPHYS cbMmio32, uint32_t cInterrupts); 109 110 HRESULT addAddrRange(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS GCPhysEnd); 124 HRESULT init(ChipsetType_T chipsetType, IommuType_T iommuType, uint32_t cInterrupts); 125 126 HRESULT ensureAdditionalRegions(uint32_t cRegions); 127 void setRegion(PRESOURCEREGION pRegion, const char *pszName, RESOURCEREGIONTYPE enmType, 128 RTGCPHYS GCPhysStart, RTGCPHYS GCPhysEnd); 129 HRESULT addAddrRange(const char *pszName, RESOURCEREGIONTYPE enmType, RTGCPHYS GCPhysStart, RTGCPHYS GCPhysEnd); 130 HRESULT findNextFreeAddrRange(RTGCPHYS cbRegion, RTGCPHYS cbAlignment, RTGCPHYS GCPhysMax, RTGCPHYS GCPhysHint, 131 PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion); 132 133 void dumpToReleaseLog(void); 111 134 }; 112 135 113 136 114 HRESULT ResourceAssignmentManager::State::init(PCVMMR3VTABLE pVMM, ChipsetType_T chipsetType, IommuType_T iommuType, 115 RTGCPHYS GCPhysMmioStart, RTGCPHYS GCPhysRamStart, 116 RTGCPHYS GCPhysMmio32Start, RTGCPHYS cbMmio32, uint32_t cInterrupts) 117 { 118 mpVMM = pVMM; 119 137 HRESULT ResourceAssignmentManager::State::init(ChipsetType_T chipsetType, IommuType_T iommuType, 138 uint32_t cInterrupts) 139 { 120 140 Assert(chipsetType == ChipsetType_ARMv8Virtual); 121 141 Assert(iommuType == IommuType_None); /* For now no IOMMU support on ARMv8. */ … … 123 143 mChipsetType = chipsetType; 124 144 mIommuType = iommuType; 125 mGCPhysMmioStart = GCPhysMmioStart;126 mGCPhysMmioStartOrig = GCPhysMmioStart;127 mGCPhysRamStart = GCPhysRamStart;128 mGCPhysMmio32Start = GCPhysMmio32Start;129 mGCPhysMmio32StartOrig = GCPhysMmio32Start;130 mcbMmio32 = cbMmio32;131 145 mcInterrupts = cInterrupts; 132 146 miInterrupt = 0; 133 return S_OK; 134 } 135 136 HRESULT ResourceAssignmentManager::State::addAddrRange(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 137 { 138 MemoryRange memRange(pszName, GCPhysStart, GCPhysStart + cbRegion - 1); 139 mAddrRanges.push_back(memRange); 140 return S_OK; 141 } 147 148 m_paRegions = (PRESOURCEREGION)RTMemRealloc(m_paRegions, 32 * sizeof(*m_paRegions)); 149 if (!m_paRegions) 150 return E_OUTOFMEMORY; 151 152 m_paRegions[m_cRegions].enmType = kResourceRegionType_Free; 153 m_paRegions[m_cRegions].GCPhysStart = 0; 154 m_paRegions[m_cRegions].GCPhysEnd = UINT64_MAX; 155 strcpy(&m_paRegions[m_cRegions].szName[0], "Free"); 156 m_cRegions++; 157 158 return S_OK; 159 } 160 161 162 HRESULT ResourceAssignmentManager::State::ensureAdditionalRegions(uint32_t cRegions) 163 { 164 if (m_cRegions + cRegions == m_cRegionsMax) 165 { 166 uint32_t const cRegionsNew = m_cRegionsMax + 32; 167 PRESOURCEREGION paDescsNew = (PRESOURCEREGION)RTMemRealloc(m_paRegions, cRegionsNew * sizeof(*paDescsNew)); 168 if (!paDescsNew) 169 return E_OUTOFMEMORY; 170 171 m_paRegions = paDescsNew; 172 m_cRegionsMax = cRegionsNew; 173 } 174 175 return S_OK; 176 } 177 178 179 void ResourceAssignmentManager::State::setRegion(PRESOURCEREGION pRegion, const char *pszName, RESOURCEREGIONTYPE enmType, 180 RTGCPHYS GCPhysStart, RTGCPHYS GCPhysEnd) 181 { 182 strncpy(&pRegion->szName[0], pszName, sizeof(pRegion->szName)); 183 pRegion->szName[sizeof(pRegion->szName) - 1] = '\0'; 184 pRegion->enmType = enmType; 185 pRegion->GCPhysStart = GCPhysStart; 186 pRegion->GCPhysEnd = GCPhysEnd; 187 } 188 189 190 HRESULT ResourceAssignmentManager::State::addAddrRange(const char *pszName, RESOURCEREGIONTYPE enmType, 191 RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 192 { 193 RTGCPHYS GCPhysEnd = GCPhysStart + cbRegion - 1; 194 195 /* Find the right spot in the array where to insert the range, it must not overlap with an existing used range. */ 196 uint32_t iRegion = 0; 197 while ( iRegion < m_cRegions 198 && GCPhysStart > m_paRegions[iRegion].GCPhysEnd) 199 iRegion++; 200 201 Assert( iRegion == m_cRegions - 1 202 || m_paRegions[iRegion].enmType != m_paRegions[iRegion + 1].enmType); 203 204 /* Check that there is sufficient free space. */ 205 if ( (m_paRegions[iRegion].enmType != kResourceRegionType_Free) 206 || GCPhysEnd > m_paRegions[iRegion].GCPhysEnd) 207 return E_INVALIDARG; 208 209 Assert(m_paRegions[iRegion].enmType == kResourceRegionType_Free); 210 211 /* Requested region fits exactly into the free region. */ 212 if ( GCPhysStart == m_paRegions[iRegion].GCPhysStart 213 && GCPhysEnd == m_paRegions[iRegion].GCPhysEnd) 214 { 215 setRegion(&m_paRegions[iRegion], pszName, enmType, GCPhysStart, GCPhysEnd); 216 return S_OK; 217 } 218 219 HRESULT hrc = ensureAdditionalRegions(2 /*cRegions*/); /* Need two additional region descriptors max. */ 220 if (FAILED(hrc)) 221 return hrc; 222 223 /* Need to split the region into two or three depending on where the requested region lies. */ 224 if (GCPhysStart == m_paRegions[iRegion].GCPhysStart) 225 { 226 /* At the start, move the free regions and everything at the end. */ 227 memmove(&m_paRegions[iRegion + 1], &m_paRegions[iRegion], (m_cRegions - iRegion) * sizeof(*m_paRegions)); 228 setRegion(&m_paRegions[iRegion], pszName, enmType, GCPhysStart, GCPhysEnd); 229 230 /* Adjust the free region. */ 231 m_paRegions[iRegion + 1].GCPhysStart = GCPhysStart + cbRegion; 232 m_cRegions++; 233 } 234 else if (GCPhysStart + cbRegion - 1 == m_paRegions[iRegion].GCPhysEnd) 235 { 236 /* At the end of the region, move the remaining regions and adjust ranges. */ 237 if (iRegion < m_cRegions) 238 memmove(&m_paRegions[iRegion + 2], &m_paRegions[iRegion + 1], (m_cRegions - iRegion) * sizeof(*m_paRegions)); 239 setRegion(&m_paRegions[iRegion + 1], pszName, enmType, GCPhysStart, GCPhysEnd); 240 m_paRegions[iRegion].GCPhysEnd = GCPhysStart - 1; 241 m_cRegions++; 242 } 243 else 244 { 245 /* Somewhere in the middle, split into three regions. */ 246 if (iRegion < m_cRegions) 247 memmove(&m_paRegions[iRegion + 3], &m_paRegions[iRegion + 1], (m_cRegions - iRegion) * sizeof(*m_paRegions)); 248 setRegion(&m_paRegions[iRegion + 1], pszName, enmType, GCPhysStart, GCPhysEnd); 249 setRegion(&m_paRegions[iRegion + 2], "Free", kResourceRegionType_Free, GCPhysStart + cbRegion, m_paRegions[iRegion].GCPhysEnd); 250 m_paRegions[iRegion].GCPhysEnd = GCPhysStart - 1; 251 m_cRegions += 2; 252 } 253 254 return S_OK; 255 } 256 257 258 HRESULT ResourceAssignmentManager::State::findNextFreeAddrRange(RTGCPHYS cbRegion, RTGCPHYS cbAlignment, RTGCPHYS GCPhysMax, 259 RTGCPHYS GCPhysHint, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion) 260 { 261 AssertReturn(GCPhysMax >= cbRegion, E_FAIL); 262 GCPhysMax -= cbRegion; 263 264 uint32_t iRegion = 0; 265 if (GCPhysHint) 266 { 267 /* Look for free address range downwards from the hint first. */ 268 iRegion = m_cRegions - 1; 269 while (iRegion) 270 { 271 PCRESOURCEREGION pRegion = &m_paRegions[iRegion]; 272 273 /* Region must be free and satisfy the alignment++ requirements. */ 274 RTGCPHYS GCPhysStartAligned = RT_ALIGN_T(pRegion->GCPhysEnd - cbRegion + 1, cbAlignment, RTGCPHYS); 275 if ( pRegion->enmType == kResourceRegionType_Free 276 && GCPhysHint >= pRegion->GCPhysEnd 277 && GCPhysMax >= pRegion->GCPhysEnd 278 && GCPhysStartAligned >= pRegion->GCPhysStart 279 && pRegion->GCPhysEnd - GCPhysStartAligned + 1 >= cbRegion) 280 { 281 *pGCPhysStart = GCPhysStartAligned; 282 *pcbRegion = cbRegion; 283 return S_OK; 284 } 285 286 iRegion--; 287 } 288 } 289 290 /* Find a free region which satisfies or requirements. */ 291 while ( iRegion < m_cRegions 292 && GCPhysMax >= m_paRegions[iRegion].GCPhysStart) 293 { 294 PCRESOURCEREGION pRegion = &m_paRegions[iRegion]; 295 296 /* Region must be free and satisfy the alignment++ requirements. */ 297 RTGCPHYS GCPhysStartAligned = RT_ALIGN_T(pRegion->GCPhysStart, cbAlignment, RTGCPHYS); 298 if ( pRegion->enmType == kResourceRegionType_Free 299 && GCPhysStartAligned >= pRegion->GCPhysStart 300 && pRegion->GCPhysEnd - GCPhysStartAligned + 1 >= cbRegion) 301 { 302 *pGCPhysStart = pRegion->GCPhysStart; 303 *pcbRegion = cbRegion; 304 return S_OK; 305 } 306 307 iRegion++; 308 } 309 310 return E_OUTOFMEMORY; 311 } 312 313 314 static const char *resourceManagerRegionType2Str(RESOURCEREGIONTYPE enmType) 315 { 316 switch (enmType) 317 { 318 case kResourceRegionType_Free: return "FREE"; 319 case kResourceRegionType_Ram: return "RAM "; 320 case kResourceRegionType_Rom: return "ROM "; 321 case kResourceRegionType_Mmio: return "MMIO"; 322 default: AssertFailed(); return "UNKNOWN"; 323 } 324 } 325 326 327 void ResourceAssignmentManager::State::dumpToReleaseLog(void) 328 { 329 LogRel(("Memory Regions:\n")); 330 for (uint32_t iRegion = 0; iRegion < m_cRegions; iRegion++) 331 { 332 LogRel((" %RGp - %RGp (%zu) %s %s\n", 333 m_paRegions[iRegion].GCPhysStart, 334 m_paRegions[iRegion].GCPhysEnd, 335 m_paRegions[iRegion].GCPhysEnd - m_paRegions[iRegion].GCPhysStart + 1, 336 m_paRegions[iRegion].szName)); 337 } 338 } 339 142 340 143 341 ResourceAssignmentManager::ResourceAssignmentManager() 144 : pState(NULL) 145 { 146 pState = new State(); 147 Assert(pState); 148 } 342 : m_pState(NULL) 343 { 344 m_pState = new State(); 345 Assert(m_pState); 346 } 347 149 348 150 349 ResourceAssignmentManager::~ResourceAssignmentManager() 151 350 { 152 if (pState) 153 { 154 delete pState; 155 pState = NULL; 156 } 157 } 351 if (m_pState) 352 { 353 delete m_pState; 354 m_pState = NULL; 355 } 356 } 357 158 358 159 359 ResourceAssignmentManager *ResourceAssignmentManager::createInstance(PCVMMR3VTABLE pVMM, ChipsetType_T chipsetType, IommuType_T iommuType, 160 RTGCPHYS GCPhysMmioTop, RTGCPHYS GCPhysRamStart,161 RTGCPHYS GCPhysMmio32Start, RTGCPHYS cbMmio32, 162 uint32_t cInterrupts)163 { 360 uint32_t cInterrupts, RTGCPHYS GCPhysMmioHint) 361 { 362 RT_NOREF(pVMM); 363 164 364 ResourceAssignmentManager *pInstance = new ResourceAssignmentManager(); 165 pInstance->pState->init(pVMM, chipsetType, iommuType, GCPhysMmioTop, GCPhysRamStart, GCPhysMmio32Start, cbMmio32, cInterrupts); 365 366 pInstance->m_GCPhysMmioHint = GCPhysMmioHint; 367 pInstance->m_pState->init(chipsetType, iommuType, cInterrupts); 166 368 Assert(pInstance); 167 369 return pInstance; 168 370 } 169 371 372 373 HRESULT ResourceAssignmentManager::assignFixedRomRegion(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 374 { 375 return m_pState->addAddrRange(pszName, kResourceRegionType_Rom, GCPhysStart, cbRegion); 376 } 377 378 379 HRESULT ResourceAssignmentManager::assignFixedRamRegion(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 380 { 381 return m_pState->addAddrRange(pszName, kResourceRegionType_Ram, GCPhysStart, cbRegion); 382 } 383 384 385 HRESULT ResourceAssignmentManager::assignFixedMmioRegion(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 386 { 387 return m_pState->addAddrRange(pszName, kResourceRegionType_Mmio, GCPhysStart, cbRegion); 388 } 389 390 391 HRESULT ResourceAssignmentManager::assignMmioRegionAligned(const char *pszName, RTGCPHYS cbRegion, RTGCPHYS cbAlignment, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion, 392 bool fOnly32Bit) 393 { 394 RTGCPHYS GCPhysRegionStart; 395 RTGCPHYS cbRegionFinal; 396 HRESULT hrc = m_pState->findNextFreeAddrRange(cbRegion, cbAlignment, fOnly32Bit ? _4G : RTGCPHYS_MAX, 397 m_GCPhysMmioHint, &GCPhysRegionStart, &cbRegionFinal); 398 if (SUCCEEDED(hrc)) 399 { 400 *pGCPhysStart = GCPhysRegionStart; 401 *pcbRegion = cbRegionFinal; 402 return assignFixedMmioRegion(pszName, GCPhysRegionStart, cbRegion); 403 } 404 405 return hrc; 406 } 407 408 170 409 HRESULT ResourceAssignmentManager::assignMmioRegion(const char *pszName, RTGCPHYS cbRegion, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion) 171 410 { 172 RTGCPHYS cbRegionAligned = RT_ALIGN_T(cbRegion, _4K, RTGCPHYS); 173 RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart; 174 175 *pGCPhysStart = GCPhysMmioStart; 176 *pcbRegion = cbRegionAligned; 177 pState->mGCPhysMmioStart += cbRegionAligned; 178 pState->addAddrRange(pszName, GCPhysMmioStart, cbRegionAligned); 179 return S_OK; 180 } 411 return assignMmioRegionAligned(pszName, cbRegion, _4K, pGCPhysStart, pcbRegion, false /*fOnly32Bit*/); 412 } 413 181 414 182 415 HRESULT ResourceAssignmentManager::assignMmio32Region(const char *pszName, RTGCPHYS cbRegion, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion) 183 416 { 184 RTGCPHYS cbRegionAligned = RT_ALIGN_T(cbRegion, _4K, RTGCPHYS); 185 RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmio32Start; 186 187 if (GCPhysMmioStart > pState->mGCPhysRamStart) 188 { 189 AssertLogRelMsgFailed(("ResourceAssignmentManager: MMIO32 range for %s would overlap RAM region\n", pszName)); 190 return E_INVALIDARG; 191 } 192 193 *pGCPhysStart = GCPhysMmioStart; 194 *pcbRegion = cbRegionAligned; 195 pState->mGCPhysMmio32Start += cbRegionAligned; 196 pState->addAddrRange(pszName, GCPhysMmioStart, cbRegionAligned); 197 return S_OK; 198 } 199 200 HRESULT ResourceAssignmentManager::assignMmioRegionAligned(const char *pszName, RTGCPHYS cbRegion, RTGCPHYS cbAlignment, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion) 201 { 202 RTGCPHYS cbRegionAligned = RT_ALIGN_T(cbRegion, cbAlignment, RTGCPHYS); 203 RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart; 204 205 GCPhysMmioStart = RT_ALIGN_T(GCPhysMmioStart, cbAlignment, RTGCPHYS); 206 207 *pGCPhysStart = GCPhysMmioStart; 208 *pcbRegion = cbRegionAligned; 209 pState->mGCPhysMmioStart = GCPhysMmioStart + cbRegionAligned; 210 pState->addAddrRange(pszName, GCPhysMmioStart, cbRegionAligned); 211 return S_OK; 212 } 213 214 HRESULT ResourceAssignmentManager::assignFixedAddress(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion) 215 { 216 RT_NOREF(pszName, GCPhysStart, cbRegion); 217 AssertReleaseFailed(); 218 return S_OK; 219 } 220 221 HRESULT ResourceAssignmentManager::assignRamRegion(const char *pszName, RTGCPHYS cbRam, PRTGCPHYS pGCPhysStart) 222 { 223 *pGCPhysStart = pState->mGCPhysRamStart; 224 pState->mGCPhysRamStart += cbRam; 225 pState->addAddrRange(pszName, *pGCPhysStart, cbRam); 226 return S_OK; 227 } 417 return assignMmioRegionAligned(pszName, cbRegion, _4K, pGCPhysStart, pcbRegion, true /*fOnly32Bit*/); 418 } 419 228 420 229 421 HRESULT ResourceAssignmentManager::assignInterrupts(const char *pszName, uint32_t cInterrupts, uint32_t *piInterruptFirst) 230 422 { 231 if ( pState->miInterrupt + cInterrupts >pState->mcInterrupts)423 if (m_pState->miInterrupt + cInterrupts > m_pState->mcInterrupts) 232 424 { 233 425 AssertLogRelMsgFailed(("ResourceAssignmentManager: Interrupt count for %s exceeds number of available interrupts\n", pszName)); … … 235 427 } 236 428 237 *piInterruptFirst = pState->miInterrupt; 238 pState->miInterrupt += cInterrupts; 239 return S_OK; 240 } 429 *piInterruptFirst = m_pState->miInterrupt; 430 m_pState->miInterrupt += cInterrupts; 431 return S_OK; 432 } 433 434 HRESULT ResourceAssignmentManager::queryMmioRegion(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio) 435 { 436 /* 437 * This ASSUMES that there are adjacent MMIO regions above 4GiB which can be combined into one single region 438 * (adjacent and no ROM/RAM regions inbetween). 439 */ 440 *pGCPhysMmioStart = 0; 441 *pcbMmio = 0; 442 443 /* Look for the start. */ 444 for (uint32_t i = 0; i < m_pState->m_cRegions; i++) 445 { 446 PCRESOURCEREGION pRegion = &m_pState->m_paRegions[i]; 447 448 if ( pRegion->GCPhysStart >= _4G 449 && pRegion->enmType == kResourceRegionType_Mmio) 450 { 451 RTGCPHYS cbMmio = pRegion->GCPhysEnd - pRegion->GCPhysStart + 1; 452 453 *pGCPhysMmioStart = pRegion->GCPhysStart; 454 455 /* Add up any remaining MMIO regions adjacent to this one. */ 456 for (uint32_t j = i; j < m_pState->m_cRegions; j++) 457 { 458 pRegion = &m_pState->m_paRegions[i]; 459 if ( pRegion->enmType == kResourceRegionType_Mmio 460 && pRegion->GCPhysStart == *pGCPhysMmioStart + cbMmio) 461 cbMmio += pRegion->GCPhysEnd - pRegion->GCPhysStart + 1; 462 else 463 break; 464 } 465 466 *pcbMmio = cbMmio; 467 return S_OK; 468 } 469 } 470 471 return S_OK; 472 } 473 474 475 HRESULT ResourceAssignmentManager::queryMmio32Region(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio) 476 { 477 RT_NOREF(pGCPhysMmioStart, pcbMmio); 478 return S_OK; 479 } 480 241 481 242 482 HRESULT ResourceAssignmentManager::assignSingleInterrupt(const char *pszName, uint32_t *piInterrupt) … … 245 485 } 246 486 247 HRESULT ResourceAssignmentManager::queryMmioRegion(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio) 248 { 249 *pGCPhysMmioStart = pState->mGCPhysMmioStartOrig; 250 *pcbMmio = pState->mGCPhysMmioStart - pState->mGCPhysMmioStartOrig; 251 return S_OK; 252 } 253 254 HRESULT ResourceAssignmentManager::queryMmio32Region(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio) 255 { 256 *pGCPhysMmioStart = pState->mGCPhysMmio32StartOrig; 257 *pcbMmio = pState->mcbMmio32; 258 return S_OK; 259 } 487 488 void ResourceAssignmentManager::dumpMemoryRegionsToReleaseLog(void) 489 { 490 m_pState->dumpToReleaseLog(); 491 }
Note:
See TracChangeset
for help on using the changeset viewer.