blob: 93acf3fc8424913935deab9a80dd8d7f04eece2b [file] [log] [blame]
Patrick Benavoli68a91282011-08-31 11:23:23 +02001/* <auto_header>
2 * <FILENAME>
3 *
4 * INTEL CONFIDENTIAL
5 * Copyright © 2011 Intel
6 * Corporation All Rights Reserved.
7 *
8 * The source code contained or described herein and all documents related to
9 * the source code ("Material") are owned by Intel Corporation or its suppliers
10 * or licensors. Title to the Material remains with Intel Corporation or its
11 * suppliers and licensors. The Material contains trade secrets and proprietary
12 * and confidential information of Intel or its suppliers and licensors. The
13 * Material is protected by worldwide copyright and trade secret laws and
14 * treaty provisions. No part of the Material may be used, copied, reproduced,
15 * modified, published, uploaded, posted, transmitted, distributed, or
16 * disclosed in any way without Intel’s prior express written permission.
17 *
18 * No license under any patent, copyright, trade secret or other intellectual
19 * property right is granted to or conferred upon you by disclosure or delivery
20 * of the Materials, either expressly, by implication, inducement, estoppel or
21 * otherwise. Any license under such intellectual property rights must be
22 * express and approved by Intel in writing.
23 *
24 * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com)
25 * CREATED: 2011-06-01
26 * UPDATED: 2011-07-27
27 *
28 *
29 * </auto_header>
30 */
31#include "ConfigurableElement.h"
32#include "MappingData.h"
33#include "SyncerSet.h"
34#include "ConfigurableDomain.h"
35#include "ConfigurationAccessContext.h"
36#include "ConfigurableElementAggregator.h"
37#include <assert.h>
38
39#define base CElement
40
41CConfigurableElement::CConfigurableElement(const string& strName) : base(strName), _uiOffset(0)
42{
43}
44
45CConfigurableElement::~CConfigurableElement()
46{
47}
48
49// XML configuration settings parsing
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020050bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020051{
52 uint32_t uiIndex;
53 uint32_t uiNbChildren = getNbChildren();
54
55 if (!configurationAccessContext.serializeOut()) {
56 // Just do basic checks and propagate to children
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020057 CXmlElement::CChildIterator it(xmlConfigurationSettingsElementContent);
Patrick Benavoli68a91282011-08-31 11:23:23 +020058
59 CXmlElement xmlChildConfigurableElementSettingsElement;
60
61 // Propagate to children
62 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
63
64 // Get child
65 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
66
67 if (!it.next(xmlChildConfigurableElementSettingsElement)) {
68
69 // Structure error
70 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
71
72 return false;
73 }
74
75 // Check element type matches in type
76 if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
77
78 // Type error
79 configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
80
81 return false;
82 }
83
84 // Check element type matches in name
85 if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) {
86
87 // Name error
88 configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead");
89
90 return false;
91 }
92
93 // Parse child configurable element's settings
94 if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
95
96 return false;
97 }
98 }
99 // There should remain no configurable element to parse
100 if (it.next(xmlChildConfigurableElementSettingsElement)) {
101
102 // Structure error
103 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
104
105 return false;
106 }
107 } else {
108 // Propagate to children
109 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
110
111 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
112
113 // Create corresponding child element
114 CXmlElement xmlChildConfigurableElementSettingsElement;
115
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200116 xmlConfigurationSettingsElementContent.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200117
118 // Handle element name attribute
119 xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
120
121 // Propagate
122 pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
123 }
124 }
125 // Done
126 return true;
127}
128
Patrick Benavoli68a91282011-08-31 11:23:23 +0200129// Parameter access
Patrick Benavoli065264a2011-11-20 15:46:41 +0100130bool CConfigurableElement::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200131{
132 string* pStrChildName = pathNavigator.next();
133
134 if (!pStrChildName) {
135
Patrick Benavoli065264a2011-11-20 15:46:41 +0100136 parameterAccessContext.setError("Non accessible element");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200137
138 return false;
139 }
140
141 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
142
143 if (!pChild) {
144
Patrick Benavoli065264a2011-11-20 15:46:41 +0100145 parameterAccessContext.setError("Path not found: " + pathNavigator.getCurrentPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200146
147 return false;
148 }
149
Patrick Benavoli065264a2011-11-20 15:46:41 +0100150 return pChild->accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200151}
152
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100153// Used for simulation and virtual subsystems
Patrick Benavoli68a91282011-08-31 11:23:23 +0200154void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
155{
156 // Propagate to children
157 uint32_t uiIndex;
158 uint32_t uiNbChildren = getNbChildren();
159
160 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
161
162 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
163
164 pConfigurableElement->setDefaultValues(parameterAccessContext);
165 }
166}
167
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200168// Element properties
169void CConfigurableElement::showProperties(string& strResult) const
170{
171 base::showProperties(strResult);
172
173 strResult += "Total size: " + getFootprintAsString() + "\n";
174}
175
Patrick Benavoli68a91282011-08-31 11:23:23 +0200176// Offset
177void CConfigurableElement::setOffset(uint32_t uiOffset)
178{
179 // Assign offset locally
180 _uiOffset = uiOffset;
181
182 // Propagate to children
183 uint32_t uiIndex;
184 uint32_t uiNbChildren = getNbChildren();
185
186 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
187
188 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
189
190 pConfigurableElement->setOffset(uiOffset);
191
192 uiOffset += pConfigurableElement->getFootPrint();
193 }
194}
195
196uint32_t CConfigurableElement::getOffset() const
197{
198 return _uiOffset;
199}
200
201// Memory
202uint32_t CConfigurableElement::getFootPrint() const
203{
204 uint32_t uiSize = 0;
205 uint32_t uiIndex;
206 uint32_t uiNbChildren = getNbChildren();
207
208 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
209
210 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
211
212 uiSize += pConfigurableElement->getFootPrint();
213 }
214
215 return uiSize;
216}
217
218// Browse parent path to find syncer
219ISyncer* CConfigurableElement::getSyncer() const
220{
221 // Check parent
222 const CElement* pParent = getParent();
223
224 if (isOfConfigurableElementType(pParent)) {
225
226 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
227 }
228 return false;
229}
230
231// Syncer set (me, ascendant or descendant ones)
232void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
233{
234 // Try me or ascendants
235 ISyncer* pMineOrAscendantSyncer = getSyncer();
236
237 if (pMineOrAscendantSyncer) {
238
239 // Provide found syncer object
240 syncerSet += pMineOrAscendantSyncer;
241
242 // Done
243 return;
244 }
245 // Fetch descendant ones
246 fillSyncerSetFromDescendant(syncerSet);
247}
248
249// Syncer set (descendant)
250void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
251{
252 // Dig
253 uint32_t uiIndex;
254 uint32_t uiNbChildren = getNbChildren();
255
256 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
257
258 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
259
260 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
261 }
262}
263
264// Configurable domain association
265void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
266{
267 _configurableDomainList.push_back(pConfigurableDomain);
268}
269
270void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
271{
272 _configurableDomainList.remove(pConfigurableDomain);
273}
274
275// Belonging domain
276bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
277{
278 if (containsConfigurableDomain(pConfigurableDomain)) {
279
280 return true;
281 }
282 return belongsToDomainAscending(pConfigurableDomain);
283}
284
285// Belonging domains
286void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
287{
288 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
289
290 // Check parent
291 const CElement* pParent = getParent();
292
293 if (isOfConfigurableElementType(pParent)) {
294
295 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
296 }
297}
298
299void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
300{
301 // Get belonging domain list
302 list<const CConfigurableDomain*> configurableDomainList;
303
304 getBelongingDomains(configurableDomainList);
305
306 // Fill list
307 listDomains(configurableDomainList, strResult, bVertical);
308}
309
310// Elements with no domains
311void CConfigurableElement::listRogueElements(string& strResult) const
312{
313 strResult = "\n";
314
315 // Get rogue element aggregate list (no associated domain)
316 list<const CConfigurableElement*> rogueElementList;
317
318 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
319
320 configurableElementAggregator.aggegate(this);
321
322 // Build list as string
323 list<const CConfigurableElement*>::const_iterator it;
324
325 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
326
327 const CConfigurableElement* pConfigurableElement = *it;
328
329 strResult += pConfigurableElement->getPath() + "\n";
330 }
331}
332
Patrick Benavoli4bed9212011-10-27 14:18:00 +0200333// Belonging to no domains
334bool CConfigurableElement::isRogue() const
335{
336 return !getBelongingDomainCount();
337}
338
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200339// Footprint as string
340string CConfigurableElement::getFootprintAsString() const
341{
342 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200343 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200344}
345
Patrick Benavoli68a91282011-08-31 11:23:23 +0200346// Matching check for no domain association
347bool CConfigurableElement::hasNoDomainAssociated() const
348{
349 return _configurableDomainList.empty();
350}
351
352// Matching check for no valid associated domains
353bool CConfigurableElement::hasNoValidDomainAssociated() const
354{
355 if (_configurableDomainList.empty()) {
356
357 // No domains associated
358 return true;
359 }
360
361 ConfigurableDomainListConstIterator it;
362
363 // Browse all configurable domains for validity checking
364 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
365
366 const CConfigurableDomain* pConfigurableDomain = *it;
367
368 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
369
370 return false;
371 }
372 }
373
374 return true;
375}
376
377// Owning domains
378void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
379{
380 // Fill list
381 listDomains(_configurableDomainList, strResult, bVertical);
382}
383
384uint32_t CConfigurableElement::getBelongingDomainCount() const
385{
386 // Get belonging domain list
387 list<const CConfigurableDomain*> configurableDomainList;
388
389 getBelongingDomains(configurableDomainList);
390
391 return configurableDomainList.size();
392}
393
394void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
395{
396 if (bVertical && configurableDomainList.empty()) {
397
398 strResult = "\n";
399 }
400
401 // Fill list
402 ConfigurableDomainListConstIterator it;
403 bool bFirst = true;
404
405 // Browse all configurable domains for comparison
406 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
407
408 const CConfigurableDomain* pConfigurableDomain = *it;
409
410 if (!bVertical && !bFirst) {
411
412 strResult += ", ";
413 }
414
415 strResult += pConfigurableDomain->getName();
416
417 if (bVertical) {
418
419 strResult += "\n";
420 } else {
421
422 bFirst = false;
423 }
424 }
425}
426
427bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
428{
429 ConfigurableDomainListConstIterator it;
430
431 // Browse all configurable domains for comparison
432 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
433
434 if (pConfigurableDomain == *it) {
435
436 return true;
437 }
438 }
439 return false;
440}
441
442// Belonging domain ascending search
443bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
444{
445 // Check parent
446 const CElement* pParent = getParent();
447
448 if (isOfConfigurableElementType(pParent)) {
449
450 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
451 }
452 return false;
453}
454
455// Belonging subsystem
456const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
457{
458 const CElement* pParent = getParent();
459
460 // Stop at sytem class
461 if (!pParent->getParent()) {
462
463 return NULL;
464 }
465
466 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
467}
468
Patrick Benavoli065264a2011-11-20 15:46:41 +0100469// Check element is a parameter
470bool CConfigurableElement::isParameter() const
471{
472 return false;
473}
474
475
Patrick Benavoli68a91282011-08-31 11:23:23 +0200476// Check parent is still of current type (by structure knowledge)
477bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
478{
479 assert(pParent);
480
481 // Up to system class
482 return !!pParent->getParent();
483}