VirtualBox

source: vbox/trunk/src/VBox/Main/BusAssignmentManager.cpp@ 33696

Last change on this file since 33696 was 33690, checked in by vboxsync, 14 years ago

PCI: more slot management bits

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.6 KB
Line 
1/* $Id: BusAssignmentManager.cpp 33690 2010-11-02 14:02:19Z vboxsync $ */
2
3/** @file
4 *
5 * VirtualBox bus slots assignment manager
6 */
7
8/*
9 * Copyright (C) 2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19#include "BusAssignmentManager.h"
20
21#include <iprt/asm.h>
22
23#include <VBox/cfgm.h>
24
25#include <map>
26#include <vector>
27
28struct BusAssignmentManager::State
29{
30 struct PciDeviceRecord
31 {
32 char szDevName[16];
33
34 PciDeviceRecord(const char* pszName)
35 {
36 ::strncpy(szDevName, pszName, sizeof(szDevName));
37 }
38
39 bool operator<(const PciDeviceRecord &a) const
40 {
41 return ::strcmp(szDevName, a.szDevName) < 0;
42 }
43
44 bool operator==(const PciDeviceRecord &a) const
45 {
46 return ::strcmp(szDevName, a.szDevName) == 0;
47 }
48 };
49
50 typedef std::map <PciBusAddress,PciDeviceRecord > PciMap;
51 typedef std::vector<PciBusAddress> PciAddrList;
52 typedef std::map <PciDeviceRecord,PciAddrList > ReversePciMap;
53
54 volatile int32_t cRefCnt;
55 ChipsetType_T mChipsetType;
56 PciMap mPciMap;
57 ReversePciMap mReversePciMap;
58
59 State()
60 : cRefCnt(1), mChipsetType(ChipsetType_Null)
61 {}
62 ~State()
63 {}
64
65 HRESULT init(ChipsetType_T chipsetType);
66
67 HRESULT record(const char* pszName, PciBusAddress& Address);
68 HRESULT autoAssign(const char* pszName, PciBusAddress& Address);
69 bool checkAvailable(PciBusAddress& Address);
70 bool findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address);
71};
72
73HRESULT BusAssignmentManager::State::init(ChipsetType_T chipsetType)
74{
75 mChipsetType = chipsetType;
76 return S_OK;
77}
78
79
80HRESULT BusAssignmentManager::State::record(const char* pszName, PciBusAddress& Address)
81{
82 PciDeviceRecord devRec(pszName);
83
84 /* Remember address -> device mapping */
85 mPciMap.insert(PciMap::value_type(Address, devRec));
86
87 ReversePciMap::iterator it = mReversePciMap.find(devRec);
88 if (it == mReversePciMap.end())
89 {
90 mReversePciMap.insert(ReversePciMap::value_type(devRec, PciAddrList()));
91 it = mReversePciMap.find(devRec);
92 }
93
94 /* Remember device name -> addresses mapping */
95 it->second.push_back(Address);
96
97 return S_OK;
98}
99
100bool BusAssignmentManager::State::findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address)
101{
102 PciDeviceRecord devRec(pszDevName);
103
104 ReversePciMap::iterator it = mReversePciMap.find(devRec);
105 if (it == mReversePciMap.end())
106 return false;
107
108 if (iInstance >= (int)it->second.size())
109 return false;
110
111 Address = it->second[iInstance];
112 return true;
113}
114
115HRESULT BusAssignmentManager::State::autoAssign(const char* pszName, PciBusAddress& Address)
116{
117 // unimplemented yet
118 Assert(false);
119 return S_OK;
120}
121
122bool BusAssignmentManager::State::checkAvailable(PciBusAddress& Address)
123{
124 PciMap::const_iterator it = mPciMap.find(Address);
125
126 return (it == mPciMap.end());
127}
128
129BusAssignmentManager::BusAssignmentManager()
130 : pState(NULL)
131{
132 pState = new State();
133 Assert(pState);
134}
135
136BusAssignmentManager::~BusAssignmentManager()
137{
138 if (pState)
139 {
140 delete pState;
141 pState = NULL;
142 }
143}
144
145
146BusAssignmentManager* BusAssignmentManager::pInstance = NULL;
147
148BusAssignmentManager* BusAssignmentManager::getInstance(ChipsetType_T chipsetType)
149{
150 if (pInstance == NULL)
151 {
152 pInstance = new BusAssignmentManager();
153 pInstance->pState->init(chipsetType);
154 Assert(pInstance);
155 return pInstance;
156 }
157
158 pInstance->AddRef();
159 return pInstance;
160}
161
162void BusAssignmentManager::AddRef()
163{
164 ASMAtomicIncS32(&pState->cRefCnt);
165}
166void BusAssignmentManager::Release()
167{
168 if (ASMAtomicDecS32(&pState->cRefCnt) == 1)
169 delete this;
170}
171
172DECLINLINE(HRESULT) InsertConfigInteger(PCFGMNODE pCfg, const char* pszName, uint64_t u64)
173{
174 int vrc = CFGMR3InsertInteger(pCfg, pszName, u64);
175 if (RT_FAILURE(vrc))
176 return E_INVALIDARG;
177
178 return S_OK;
179}
180
181HRESULT BusAssignmentManager::assignPciDevice(const char* pszDevName, PCFGMNODE pCfg,
182 PciBusAddress& Address, bool fAddressRequired)
183{
184 HRESULT rc = S_OK;
185
186 if (!Address.valid())
187 rc = pState->autoAssign(pszDevName, Address);
188 else
189 {
190 bool fAvailable = pState->checkAvailable(Address);
191
192 if (!fAvailable)
193 {
194 if (fAddressRequired)
195 return E_ACCESSDENIED;
196 else
197 rc = pState->autoAssign(pszDevName, Address);
198 }
199 }
200
201 if (FAILED(rc))
202 return rc;
203
204 Assert(Address.valid());
205
206 rc = pState->record(pszDevName, Address);
207 if (FAILED(rc))
208 return rc;
209
210 rc = InsertConfigInteger(pCfg, "PCIBusNo", Address.iBus);
211 if (FAILED(rc))
212 return rc;
213 rc = InsertConfigInteger(pCfg, "PCIDeviceNo", Address.iDevice);
214 if (FAILED(rc))
215 return rc;
216 rc = InsertConfigInteger(pCfg, "PCIFunctionNo", Address.iFn);
217 if (FAILED(rc))
218 return rc;
219
220 return S_OK;
221}
222
223
224bool BusAssignmentManager::findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address)
225{
226 return pState->findPciAddress(pszDevName, iInstance, Address);
227}
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