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