blob: 3882c93ada2cb501950598918b81098ab22cd704 [file] [log] [blame]
Kevin Rocard93250d12012-07-19 17:48:30 +02001/*
Patrick Benavoli68a91282011-08-31 11:23:23 +02002 * INTEL CONFIDENTIAL
3 * Copyright © 2011 Intel
4 * Corporation All Rights Reserved.
5 *
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material contains trade secrets and proprietary
10 * and confidential information of Intel or its suppliers and licensors. The
11 * Material is protected by worldwide copyright and trade secret laws and
12 * treaty provisions. No part of the Material may be used, copied, reproduced,
13 * modified, published, uploaded, posted, transmitted, distributed, or
14 * disclosed in any way without Intel’s prior express written permission.
15 *
16 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Intel in writing.
21 *
Patrick Benavoli68a91282011-08-31 11:23:23 +020022 * CREATED: 2011-06-01
23 * UPDATED: 2011-07-27
Patrick Benavoli68a91282011-08-31 11:23:23 +020024 */
25#include "Subsystem.h"
26#include "ComponentLibrary.h"
27#include "InstanceDefinition.h"
28#include "XmlParameterSerializingContext.h"
29#include "ParameterAccessContext.h"
30#include "ConfigurationAccessContext.h"
31#include "SubsystemObjectCreator.h"
32#include <assert.h>
33
34#define base CConfigurableElement
35
36CSubsystem::CSubsystem(const string& strName) : base(strName), _pComponentLibrary(new CComponentLibrary), _pInstanceDefinition(new CInstanceDefinition), _bBigEndian(false)
37{
38 // Note: A subsystem contains instance components
39 // InstanceDefintion and ComponentLibrary objects are then not chosen to be children
40 // They'll be delt with locally
41}
42
43CSubsystem::~CSubsystem()
44{
45 // Remove subsystem objects
46 SubsystemObjectListIterator subsystemObjectIt;
47
48 for (subsystemObjectIt = _subsystemObjectList.begin(); subsystemObjectIt != _subsystemObjectList.end(); ++subsystemObjectIt) {
49
50 delete *subsystemObjectIt;
51 }
52
53 // Remove susbsystem creators
54 uint32_t uiIndex;
55
56 for (uiIndex = 0; uiIndex < _subsystemObjectCreatorArray.size(); uiIndex++) {
57
58 delete _subsystemObjectCreatorArray[uiIndex];
59 }
60
61 // Order matters!
62 delete _pInstanceDefinition;
63 delete _pComponentLibrary;
64}
65
66string CSubsystem::getKind() const
67{
68 return "Subsystem";
69}
70
71// Susbsystem Endianness
72bool CSubsystem::isBigEndian() const
73{
74 return _bBigEndian;
75}
76
77// From IXmlSink
78bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
79{
80 // Context
81 CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext);
82
83 // Install temporary component library for further component creation
84 parameterBuildContext.setComponentLibrary(_pComponentLibrary);
85
86 CXmlElement childElement;
87
88 // XML populate ComponentLibrary
89 xmlElement.getChildElement("ComponentLibrary", childElement);
90
91 if (!_pComponentLibrary->fromXml(childElement, serializingContext)) {
92
93 return false;
94 }
95
96 // XML populate InstanceDefintion
97 xmlElement.getChildElement("InstanceDefintion", childElement);
98 if (!_pInstanceDefinition->fromXml(childElement, serializingContext)) {
99
100 return false;
101 }
102
103 // Create components
104 _pInstanceDefinition->createInstances(this);
105
106 // Execute mapping to create subsystem mapping entities
107 string strError;
108 if (!mapSubsystemElements(strError)) {
109
110 serializingContext.setError(strError);
111
112 return false;
113 }
114
115 // Endianness
116 _bBigEndian = xmlElement.getAttributeBoolean("Endianness", "Big");
117
118 return true;
119}
120
121// XML configuration settings parsing
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200122bool CSubsystem::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200123{
124 // Fix Endianness
125 configurationAccessContext.setBigEndianSubsystem(_bBigEndian);
126
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200127 return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200128}
129
130
131bool CSubsystem::mapSubsystemElements(string& strError)
132{
133 // Default mapping context
134 _contextStack.push(CMappingContext(_contextMappingKeyArray.size()));
135
136 // Map all instantiated subelements in subsystem
137 uint32_t uiNbChildren = getNbChildren();
138 uint32_t uiChild;
139
140 for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
141
142 CInstanceConfigurableElement* pInstanceConfigurableChildElement = static_cast<CInstanceConfigurableElement*>(getChild(uiChild));
143
144 if (!pInstanceConfigurableChildElement->map(*this, strError)) {
145
146 return false;
147 }
148 }
149 return true;
150}
151
152// Parameter access
Patrick Benavoli065264a2011-11-20 15:46:41 +0100153bool CSubsystem::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200154{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200155 // Deal with Endianness
Patrick Benavoli065264a2011-11-20 15:46:41 +0100156 parameterAccessContext.setBigEndianSubsystem(_bBigEndian);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200157
Patrick Benavoli065264a2011-11-20 15:46:41 +0100158 return base::accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200159}
160
161void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const
162{
Patrick Benavoli065264a2011-11-20 15:46:41 +0100163 CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200164
165 // Deal with Endianness
Patrick Benavoli065264a2011-11-20 15:46:41 +0100166 parameterAccessContext.setBigEndianSubsystem(_bBigEndian);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200167
168 return base::logValue(strValue, errorContext);
169}
170
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100171// Used for simulation and virtual subsystems
Patrick Benavoli68a91282011-08-31 11:23:23 +0200172void CSubsystem::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
173{
174 // Deal with Endianness
175 parameterAccessContext.setBigEndianSubsystem(_bBigEndian);
176
177 base::setDefaultValues(parameterAccessContext);
178}
179
180// Belonging subsystem
181const CSubsystem* CSubsystem::getBelongingSubsystem() const
182{
183 return this;
184}
185
186// Subsystem context mapping keys publication
187void CSubsystem::addContextMappingKey(const string& strMappingKey)
188{
189 _contextMappingKeyArray.push_back(strMappingKey);
190}
191
192// Subsystem object creator publication (strong reference)
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200193void CSubsystem::addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200194{
195 _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator);
196}
197
198// Mapping generic context handling
199bool CSubsystem::handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError)
200{
201 // Feed context with found mapping data
202 uint32_t uiItem;
203
204 for (uiItem = 0; uiItem < _contextMappingKeyArray.size(); uiItem++) {
205
206 string strKey = _contextMappingKeyArray[uiItem];
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200207 const string* pStrValue;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200208
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200209 if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200210 // Assign item to context
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200211 if (!context.setItem(uiItem, pStrValue)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200212
213 getMappingError(strError, strKey, "Already set", pInstanceConfigurableElement);
214
215 return false;
216 }
217 }
218 }
219 return true;
220}
221
222// Creation handling
223bool CSubsystem::handleSubsystemObjectCreation(CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError)
224{
225 uint32_t uiItem;
226
227 for (uiItem = 0; uiItem < _subsystemObjectCreatorArray.size(); uiItem++) {
228
229 const CSubsystemObjectCreator* pSubsystemObjectCreator = _subsystemObjectCreatorArray[uiItem];
230
231 // Mapping key
232 string strKey = pSubsystemObjectCreator->getMappingKey();
233 // Object id
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200234 const string* pStrValue;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200235
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200236 if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200237
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100238 // First check context consistency (required ancestors must have been set prior to object creation)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200239 uint32_t uiAncestorKey;
240 uint32_t uiAncestorMask = pSubsystemObjectCreator->getAncestorMask();
241
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200242 for (uiAncestorKey = 0; uiAncestorKey < _contextMappingKeyArray.size(); uiAncestorKey++) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200243
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200244 if (!((1 << uiAncestorKey) & uiAncestorMask)) {
245 // Ancestor not required
246 continue;
247 }
248 // Check ancestor was provided
Patrick Benavoli68a91282011-08-31 11:23:23 +0200249 if (!context.iSet(uiAncestorKey)) {
250
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200251 getMappingError(strError, strKey, _contextMappingKeyArray[uiAncestorKey] + " not set", pInstanceConfigurableElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200252
253 return false;
254 }
255 }
256
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200257 // Then check configurable element size is correct
258 if (pInstanceConfigurableElement->getFootPrint() > pSubsystemObjectCreator->getMaxConfigurableElementSize()) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200259
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100260 string strSizeError = "Size should not exceed " + pSubsystemObjectCreator->getMaxConfigurableElementSize();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200261
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200262 getMappingError(strError, strKey, strSizeError, pInstanceConfigurableElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200263
264 return false;
265 }
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200266
267 // Do create object and keep its track
268 _subsystemObjectList.push_back(pSubsystemObjectCreator->objectCreate(*pStrValue, pInstanceConfigurableElement, context));
Patrick Benavoli68a91282011-08-31 11:23:23 +0200269
270 // Done
271 return true;
272 }
273 }
274 getMappingError(strError, "Mapping key", "Not found", pInstanceConfigurableElement);
275
276 return false;
277}
278
279// Generic error handling from derived subsystem classes
280void CSubsystem::getMappingError(string& strError, const string& strKey, const string& strMessage, const CInstanceConfigurableElement* pInstanceConfigurableElement)
281{
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100282 strError = getName() + " " + getKind() + " mapping:\n" + strKey + " error: \"" + strMessage + "\" for element " + pInstanceConfigurableElement->getPath();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200283}
284
285// From IMapper
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100286bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, string& strError)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200287{
288 // Get current context
289 CMappingContext context = _contextStack.top();
290
291 switch(pInstanceConfigurableElement->getType()) {
292
293 case CInstanceConfigurableElement::EComponent:
294
295 if (!handleMappingContext(pInstanceConfigurableElement, context, strError)) {
296
297 return false;
298 }
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100299
300 // Push context
301 _contextStack.push(context);
302
303 // Keep diving
304 bKeepDiving = true;
305
306 return true;
307
Patrick Benavoli68a91282011-08-31 11:23:23 +0200308 case CInstanceConfigurableElement::EParameterBlock:
309 case CInstanceConfigurableElement::EBitParameterBlock:
310 case CInstanceConfigurableElement::EParameter:
Patrick Benavoli1352ae52011-10-21 16:48:04 +0200311 case CInstanceConfigurableElement::EStringParameter:
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100312
Patrick Benavoli68a91282011-08-31 11:23:23 +0200313 if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, strError)) {
314
315 return false;
316 }
Patrick Benavolid3a86bf2011-11-07 19:33:30 +0100317
318 // Done
319 bKeepDiving = false;
320
321 return true;
322
Patrick Benavoli68a91282011-08-31 11:23:23 +0200323 default:
324 assert(0);
325 return false;
326 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200327}
328
329void CSubsystem::mapEnd()
330{
331 // Unstack context
332 _contextStack.pop();
333}