blob: 29622955e6657535c6dc0786841def3ba0f2260e [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 "ConfigurableElement.h"
26#include "MappingData.h"
27#include "SyncerSet.h"
28#include "ConfigurableDomain.h"
29#include "ConfigurationAccessContext.h"
30#include "ConfigurableElementAggregator.h"
Frédéric Boisnard9620e442012-05-30 16:15:02 +020031#include "AreaConfiguration.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020032#include <assert.h>
33
34#define base CElement
35
36CConfigurableElement::CConfigurableElement(const string& strName) : base(strName), _uiOffset(0)
37{
38}
39
40CConfigurableElement::~CConfigurableElement()
41{
42}
43
44// XML configuration settings parsing
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020045bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020046{
47 uint32_t uiIndex;
48 uint32_t uiNbChildren = getNbChildren();
49
50 if (!configurationAccessContext.serializeOut()) {
51 // Just do basic checks and propagate to children
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020052 CXmlElement::CChildIterator it(xmlConfigurationSettingsElementContent);
Patrick Benavoli68a91282011-08-31 11:23:23 +020053
54 CXmlElement xmlChildConfigurableElementSettingsElement;
55
56 // Propagate to children
57 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
58
59 // Get child
60 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
61
62 if (!it.next(xmlChildConfigurableElementSettingsElement)) {
63
64 // Structure error
65 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
66
67 return false;
68 }
69
70 // Check element type matches in type
71 if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
72
73 // Type error
74 configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
75
76 return false;
77 }
78
79 // Check element type matches in name
80 if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) {
81
82 // Name error
83 configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead");
84
85 return false;
86 }
87
88 // Parse child configurable element's settings
89 if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
90
91 return false;
92 }
93 }
94 // There should remain no configurable element to parse
95 if (it.next(xmlChildConfigurableElementSettingsElement)) {
96
97 // Structure error
98 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
99
100 return false;
101 }
102 } else {
103 // Propagate to children
104 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
105
106 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
107
108 // Create corresponding child element
109 CXmlElement xmlChildConfigurableElementSettingsElement;
110
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200111 xmlConfigurationSettingsElementContent.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200112
113 // Handle element name attribute
114 xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
115
116 // Propagate
117 pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
118 }
119 }
120 // Done
121 return true;
122}
123
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200124// AreaConfiguration creation
125CAreaConfiguration* CConfigurableElement::createAreaConfiguration(const CSyncerSet* pSyncerSet) const
126{
127 return new CAreaConfiguration(this, pSyncerSet);
128}
129
Patrick Benavoli68a91282011-08-31 11:23:23 +0200130// Parameter access
Patrick Benavoli065264a2011-11-20 15:46:41 +0100131bool CConfigurableElement::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200132{
133 string* pStrChildName = pathNavigator.next();
134
135 if (!pStrChildName) {
136
Patrick Benavoli065264a2011-11-20 15:46:41 +0100137 parameterAccessContext.setError("Non accessible element");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200138
139 return false;
140 }
141
142 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
143
144 if (!pChild) {
145
Patrick Benavoli065264a2011-11-20 15:46:41 +0100146 parameterAccessContext.setError("Path not found: " + pathNavigator.getCurrentPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200147
148 return false;
149 }
150
Patrick Benavoli065264a2011-11-20 15:46:41 +0100151 return pChild->accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200152}
153
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100154// Used for simulation and virtual subsystems
Patrick Benavoli68a91282011-08-31 11:23:23 +0200155void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
156{
157 // Propagate to children
158 uint32_t uiIndex;
159 uint32_t uiNbChildren = getNbChildren();
160
161 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
162
163 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
164
165 pConfigurableElement->setDefaultValues(parameterAccessContext);
166 }
167}
168
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200169// Element properties
170void CConfigurableElement::showProperties(string& strResult) const
171{
172 base::showProperties(strResult);
173
174 strResult += "Total size: " + getFootprintAsString() + "\n";
175}
176
Patrick Benavoli68a91282011-08-31 11:23:23 +0200177// Offset
178void CConfigurableElement::setOffset(uint32_t uiOffset)
179{
180 // Assign offset locally
181 _uiOffset = uiOffset;
182
183 // Propagate to children
184 uint32_t uiIndex;
185 uint32_t uiNbChildren = getNbChildren();
186
187 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
188
189 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
190
191 pConfigurableElement->setOffset(uiOffset);
192
193 uiOffset += pConfigurableElement->getFootPrint();
194 }
195}
196
197uint32_t CConfigurableElement::getOffset() const
198{
199 return _uiOffset;
200}
201
202// Memory
203uint32_t CConfigurableElement::getFootPrint() const
204{
205 uint32_t uiSize = 0;
206 uint32_t uiIndex;
207 uint32_t uiNbChildren = getNbChildren();
208
209 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
210
211 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
212
213 uiSize += pConfigurableElement->getFootPrint();
214 }
215
216 return uiSize;
217}
218
219// Browse parent path to find syncer
220ISyncer* CConfigurableElement::getSyncer() const
221{
222 // Check parent
223 const CElement* pParent = getParent();
224
225 if (isOfConfigurableElementType(pParent)) {
226
227 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
228 }
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200229 return NULL;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200230}
231
232// Syncer set (me, ascendant or descendant ones)
233void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
234{
235 // Try me or ascendants
236 ISyncer* pMineOrAscendantSyncer = getSyncer();
237
238 if (pMineOrAscendantSyncer) {
239
240 // Provide found syncer object
241 syncerSet += pMineOrAscendantSyncer;
242
243 // Done
244 return;
245 }
246 // Fetch descendant ones
247 fillSyncerSetFromDescendant(syncerSet);
248}
249
250// Syncer set (descendant)
251void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
252{
253 // Dig
254 uint32_t uiIndex;
255 uint32_t uiNbChildren = getNbChildren();
256
257 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
258
259 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
260
261 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
262 }
263}
264
265// Configurable domain association
266void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
267{
268 _configurableDomainList.push_back(pConfigurableDomain);
269}
270
271void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
272{
273 _configurableDomainList.remove(pConfigurableDomain);
274}
275
276// Belonging domain
277bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
278{
279 if (containsConfigurableDomain(pConfigurableDomain)) {
280
281 return true;
282 }
283 return belongsToDomainAscending(pConfigurableDomain);
284}
285
286// Belonging domains
287void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
288{
289 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
290
291 // Check parent
292 const CElement* pParent = getParent();
293
294 if (isOfConfigurableElementType(pParent)) {
295
296 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
297 }
298}
299
300void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
301{
302 // Get belonging domain list
303 list<const CConfigurableDomain*> configurableDomainList;
304
305 getBelongingDomains(configurableDomainList);
306
307 // Fill list
308 listDomains(configurableDomainList, strResult, bVertical);
309}
310
311// Elements with no domains
312void CConfigurableElement::listRogueElements(string& strResult) const
313{
314 strResult = "\n";
315
316 // Get rogue element aggregate list (no associated domain)
317 list<const CConfigurableElement*> rogueElementList;
318
319 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
320
321 configurableElementAggregator.aggegate(this);
322
323 // Build list as string
324 list<const CConfigurableElement*>::const_iterator it;
325
326 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
327
328 const CConfigurableElement* pConfigurableElement = *it;
329
330 strResult += pConfigurableElement->getPath() + "\n";
331 }
332}
333
Patrick Benavoli4bed9212011-10-27 14:18:00 +0200334// Belonging to no domains
335bool CConfigurableElement::isRogue() const
336{
337 return !getBelongingDomainCount();
338}
339
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200340// Footprint as string
341string CConfigurableElement::getFootprintAsString() const
342{
343 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200344 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200345}
346
Patrick Benavoli68a91282011-08-31 11:23:23 +0200347// Matching check for no domain association
348bool CConfigurableElement::hasNoDomainAssociated() const
349{
350 return _configurableDomainList.empty();
351}
352
353// Matching check for no valid associated domains
354bool CConfigurableElement::hasNoValidDomainAssociated() const
355{
356 if (_configurableDomainList.empty()) {
357
358 // No domains associated
359 return true;
360 }
361
362 ConfigurableDomainListConstIterator it;
363
364 // Browse all configurable domains for validity checking
365 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
366
367 const CConfigurableDomain* pConfigurableDomain = *it;
368
369 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
370
371 return false;
372 }
373 }
374
375 return true;
376}
377
378// Owning domains
379void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
380{
381 // Fill list
382 listDomains(_configurableDomainList, strResult, bVertical);
383}
384
385uint32_t CConfigurableElement::getBelongingDomainCount() const
386{
387 // Get belonging domain list
388 list<const CConfigurableDomain*> configurableDomainList;
389
390 getBelongingDomains(configurableDomainList);
391
392 return configurableDomainList.size();
393}
394
395void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
396{
397 if (bVertical && configurableDomainList.empty()) {
398
399 strResult = "\n";
400 }
401
402 // Fill list
403 ConfigurableDomainListConstIterator it;
404 bool bFirst = true;
405
406 // Browse all configurable domains for comparison
407 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
408
409 const CConfigurableDomain* pConfigurableDomain = *it;
410
411 if (!bVertical && !bFirst) {
412
413 strResult += ", ";
414 }
415
416 strResult += pConfigurableDomain->getName();
417
418 if (bVertical) {
419
420 strResult += "\n";
421 } else {
422
423 bFirst = false;
424 }
425 }
426}
427
428bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
429{
430 ConfigurableDomainListConstIterator it;
431
432 // Browse all configurable domains for comparison
433 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
434
435 if (pConfigurableDomain == *it) {
436
437 return true;
438 }
439 }
440 return false;
441}
442
443// Belonging domain ascending search
444bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
445{
446 // Check parent
447 const CElement* pParent = getParent();
448
449 if (isOfConfigurableElementType(pParent)) {
450
451 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
452 }
453 return false;
454}
455
456// Belonging subsystem
457const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
458{
459 const CElement* pParent = getParent();
460
Kevin Rocardace81f82012-12-11 16:19:17 +0100461 // Stop at system class
Patrick Benavoli68a91282011-08-31 11:23:23 +0200462 if (!pParent->getParent()) {
463
464 return NULL;
465 }
466
467 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
468}
469
Patrick Benavoli065264a2011-11-20 15:46:41 +0100470// Check element is a parameter
471bool CConfigurableElement::isParameter() const
472{
473 return false;
474}
475
476
Patrick Benavoli68a91282011-08-31 11:23:23 +0200477// Check parent is still of current type (by structure knowledge)
478bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
479{
480 assert(pParent);
481
482 // Up to system class
483 return !!pParent->getParent();
484}