VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/ResourceAssignmentManager.cpp@ 106951

Last change on this file since 106951 was 106061, checked in by vboxsync, 5 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: ResourceAssignmentManager.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VirtualBox bus slots assignment manager
4 */
5
6/*
7 * Copyright (C) 2010-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_MAIN
33#include "LoggingNew.h"
34
35#include "ResourceAssignmentManager.h"
36
37#include <iprt/asm.h>
38#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
48
49/*********************************************************************************************************************************
50* Structures and Typedefs *
51*********************************************************************************************************************************/
52
53
54/*********************************************************************************************************************************
55* Global Variables *
56*********************************************************************************************************************************/
57
58
59/**
60 * Resource assignment manage state data.
61 * @internal
62 */
63struct ResourceAssignmentManager::State
64{
65 struct MemoryRange
66 {
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) const
79 {
80 return RTStrNCmp(szDevName, a.szDevName, sizeof(szDevName)) == 0;
81 }
82 };
83
84 typedef std::vector<MemoryRange> AddrRangeList;
85
86 ChipsetType_T mChipsetType;
87 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;
97 uint32_t mcInterrupts;
98 uint32_t miInterrupt;
99
100 State()
101 : mChipsetType(ChipsetType_Null), mpVMM(NULL)
102 {}
103 ~State()
104 {}
105
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);
111};
112
113
114HRESULT 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
120 Assert(chipsetType == ChipsetType_ARMv8Virtual);
121 Assert(iommuType == IommuType_None); /* For now no IOMMU support on ARMv8. */
122
123 mChipsetType = chipsetType;
124 mIommuType = iommuType;
125 mGCPhysMmioStart = GCPhysMmioStart;
126 mGCPhysMmioStartOrig = GCPhysMmioStart;
127 mGCPhysRamStart = GCPhysRamStart;
128 mGCPhysMmio32Start = GCPhysMmio32Start;
129 mGCPhysMmio32StartOrig = GCPhysMmio32Start;
130 mcbMmio32 = cbMmio32;
131 mcInterrupts = cInterrupts;
132 miInterrupt = 0;
133 return S_OK;
134}
135
136HRESULT 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}
142
143ResourceAssignmentManager::ResourceAssignmentManager()
144 : pState(NULL)
145{
146 pState = new State();
147 Assert(pState);
148}
149
150ResourceAssignmentManager::~ResourceAssignmentManager()
151{
152 if (pState)
153 {
154 delete pState;
155 pState = NULL;
156 }
157}
158
159ResourceAssignmentManager *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{
164 ResourceAssignmentManager *pInstance = new ResourceAssignmentManager();
165 pInstance->pState->init(pVMM, chipsetType, iommuType, GCPhysMmioTop, GCPhysRamStart, GCPhysMmio32Start, cbMmio32, cInterrupts);
166 Assert(pInstance);
167 return pInstance;
168}
169
170HRESULT ResourceAssignmentManager::assignMmioRegion(const char *pszName, RTGCPHYS cbRegion, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion)
171{
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}
181
182HRESULT ResourceAssignmentManager::assignMmio32Region(const char *pszName, RTGCPHYS cbRegion, PRTGCPHYS pGCPhysStart, PRTGCPHYS pcbRegion)
183{
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
200HRESULT 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
214HRESULT ResourceAssignmentManager::assignFixedAddress(const char *pszName, RTGCPHYS GCPhysStart, RTGCPHYS cbRegion)
215{
216 RT_NOREF(pszName, GCPhysStart, cbRegion);
217 AssertReleaseFailed();
218 return S_OK;
219}
220
221HRESULT 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}
228
229HRESULT ResourceAssignmentManager::assignInterrupts(const char *pszName, uint32_t cInterrupts, uint32_t *piInterruptFirst)
230{
231 if (pState->miInterrupt + cInterrupts > pState->mcInterrupts)
232 {
233 AssertLogRelMsgFailed(("ResourceAssignmentManager: Interrupt count for %s exceeds number of available interrupts\n", pszName));
234 return E_INVALIDARG;
235 }
236
237 *piInterruptFirst = pState->miInterrupt;
238 pState->miInterrupt += cInterrupts;
239 return S_OK;
240}
241
242HRESULT ResourceAssignmentManager::assignSingleInterrupt(const char *pszName, uint32_t *piInterrupt)
243{
244 return assignInterrupts(pszName, 1, piInterrupt);
245}
246
247HRESULT ResourceAssignmentManager::queryMmioRegion(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio)
248{
249 *pGCPhysMmioStart = pState->mGCPhysMmioStartOrig;
250 *pcbMmio = pState->mGCPhysMmioStart - pState->mGCPhysMmioStartOrig;
251 return S_OK;
252}
253
254HRESULT ResourceAssignmentManager::queryMmio32Region(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio)
255{
256 *pGCPhysMmioStart = pState->mGCPhysMmio32StartOrig;
257 *pcbMmio = pState->mcbMmio32;
258 return S_OK;
259}
Note: See TracBrowser for help on using the repository browser.

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