blob: b87811f9f7249f5045df435c36b5b3c1ba506b03 [file] [log] [blame]
Frederic Boisnard6cae0ec2013-05-23 18:48:58 +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
Frederic Boisnard6cae0ec2013-05-23 18:48:58 +0200154void CConfigurableElement::getListOfElementsWithMapping(
155 list<const CConfigurableElement*>& configurableElementPath) const
156{
157 // Check parent
158 const CElement* pParent = getParent();
159 if (isOfConfigurableElementType(pParent)) {
160
161 const CConfigurableElement* pConfigurableElement =
162 static_cast<const CConfigurableElement*>(pParent);
163
164 pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
165 }
166}
167
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100168// Used for simulation and virtual subsystems
Patrick Benavoli68a91282011-08-31 11:23:23 +0200169void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
170{
171 // Propagate to children
172 uint32_t uiIndex;
173 uint32_t uiNbChildren = getNbChildren();
174
175 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
176
177 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
178
179 pConfigurableElement->setDefaultValues(parameterAccessContext);
180 }
181}
182
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200183// Element properties
184void CConfigurableElement::showProperties(string& strResult) const
185{
186 base::showProperties(strResult);
187
188 strResult += "Total size: " + getFootprintAsString() + "\n";
189}
190
Patrick Benavoli68a91282011-08-31 11:23:23 +0200191// Offset
192void CConfigurableElement::setOffset(uint32_t uiOffset)
193{
194 // Assign offset locally
195 _uiOffset = uiOffset;
196
197 // Propagate to children
198 uint32_t uiIndex;
199 uint32_t uiNbChildren = getNbChildren();
200
201 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
202
203 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
204
205 pConfigurableElement->setOffset(uiOffset);
206
207 uiOffset += pConfigurableElement->getFootPrint();
208 }
209}
210
211uint32_t CConfigurableElement::getOffset() const
212{
213 return _uiOffset;
214}
215
216// Memory
217uint32_t CConfigurableElement::getFootPrint() const
218{
219 uint32_t uiSize = 0;
220 uint32_t uiIndex;
221 uint32_t uiNbChildren = getNbChildren();
222
223 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
224
225 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
226
227 uiSize += pConfigurableElement->getFootPrint();
228 }
229
230 return uiSize;
231}
232
233// Browse parent path to find syncer
234ISyncer* CConfigurableElement::getSyncer() const
235{
236 // Check parent
237 const CElement* pParent = getParent();
238
239 if (isOfConfigurableElementType(pParent)) {
240
241 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
242 }
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200243 return NULL;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200244}
245
246// Syncer set (me, ascendant or descendant ones)
247void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
248{
249 // Try me or ascendants
250 ISyncer* pMineOrAscendantSyncer = getSyncer();
251
252 if (pMineOrAscendantSyncer) {
253
254 // Provide found syncer object
255 syncerSet += pMineOrAscendantSyncer;
256
257 // Done
258 return;
259 }
260 // Fetch descendant ones
261 fillSyncerSetFromDescendant(syncerSet);
262}
263
264// Syncer set (descendant)
265void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
266{
267 // Dig
268 uint32_t uiIndex;
269 uint32_t uiNbChildren = getNbChildren();
270
271 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
272
273 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
274
275 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
276 }
277}
278
279// Configurable domain association
280void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
281{
282 _configurableDomainList.push_back(pConfigurableDomain);
283}
284
285void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
286{
287 _configurableDomainList.remove(pConfigurableDomain);
288}
289
290// Belonging domain
291bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
292{
293 if (containsConfigurableDomain(pConfigurableDomain)) {
294
295 return true;
296 }
297 return belongsToDomainAscending(pConfigurableDomain);
298}
299
300// Belonging domains
301void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
302{
303 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
304
305 // Check parent
306 const CElement* pParent = getParent();
307
308 if (isOfConfigurableElementType(pParent)) {
309
310 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
311 }
312}
313
314void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
315{
316 // Get belonging domain list
317 list<const CConfigurableDomain*> configurableDomainList;
318
319 getBelongingDomains(configurableDomainList);
320
321 // Fill list
322 listDomains(configurableDomainList, strResult, bVertical);
323}
324
325// Elements with no domains
326void CConfigurableElement::listRogueElements(string& strResult) const
327{
328 strResult = "\n";
329
330 // Get rogue element aggregate list (no associated domain)
331 list<const CConfigurableElement*> rogueElementList;
332
333 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
334
335 configurableElementAggregator.aggegate(this);
336
337 // Build list as string
338 list<const CConfigurableElement*>::const_iterator it;
339
340 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
341
342 const CConfigurableElement* pConfigurableElement = *it;
343
344 strResult += pConfigurableElement->getPath() + "\n";
345 }
346}
347
Patrick Benavoli4bed9212011-10-27 14:18:00 +0200348// Belonging to no domains
349bool CConfigurableElement::isRogue() const
350{
351 return !getBelongingDomainCount();
352}
353
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200354// Footprint as string
355string CConfigurableElement::getFootprintAsString() const
356{
357 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200358 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200359}
360
Patrick Benavoli68a91282011-08-31 11:23:23 +0200361// Matching check for no domain association
362bool CConfigurableElement::hasNoDomainAssociated() const
363{
364 return _configurableDomainList.empty();
365}
366
367// Matching check for no valid associated domains
368bool CConfigurableElement::hasNoValidDomainAssociated() const
369{
370 if (_configurableDomainList.empty()) {
371
372 // No domains associated
373 return true;
374 }
375
376 ConfigurableDomainListConstIterator it;
377
378 // Browse all configurable domains for validity checking
379 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
380
381 const CConfigurableDomain* pConfigurableDomain = *it;
382
383 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
384
385 return false;
386 }
387 }
388
389 return true;
390}
391
392// Owning domains
393void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
394{
395 // Fill list
396 listDomains(_configurableDomainList, strResult, bVertical);
397}
398
399uint32_t CConfigurableElement::getBelongingDomainCount() const
400{
401 // Get belonging domain list
402 list<const CConfigurableDomain*> configurableDomainList;
403
404 getBelongingDomains(configurableDomainList);
405
406 return configurableDomainList.size();
407}
408
409void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
410{
411 if (bVertical && configurableDomainList.empty()) {
412
413 strResult = "\n";
414 }
415
416 // Fill list
417 ConfigurableDomainListConstIterator it;
418 bool bFirst = true;
419
420 // Browse all configurable domains for comparison
421 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
422
423 const CConfigurableDomain* pConfigurableDomain = *it;
424
425 if (!bVertical && !bFirst) {
426
427 strResult += ", ";
428 }
429
430 strResult += pConfigurableDomain->getName();
431
432 if (bVertical) {
433
434 strResult += "\n";
435 } else {
436
437 bFirst = false;
438 }
439 }
440}
441
442bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
443{
444 ConfigurableDomainListConstIterator it;
445
446 // Browse all configurable domains for comparison
447 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
448
449 if (pConfigurableDomain == *it) {
450
451 return true;
452 }
453 }
454 return false;
455}
456
457// Belonging domain ascending search
458bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
459{
460 // Check parent
461 const CElement* pParent = getParent();
462
463 if (isOfConfigurableElementType(pParent)) {
464
465 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
466 }
467 return false;
468}
469
470// Belonging subsystem
471const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
472{
473 const CElement* pParent = getParent();
474
Kevin Rocardace81f82012-12-11 16:19:17 +0100475 // Stop at system class
Patrick Benavoli68a91282011-08-31 11:23:23 +0200476 if (!pParent->getParent()) {
477
478 return NULL;
479 }
480
481 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
482}
483
Patrick Benavoli065264a2011-11-20 15:46:41 +0100484// Check element is a parameter
485bool CConfigurableElement::isParameter() const
486{
487 return false;
488}
489
490
Patrick Benavoli68a91282011-08-31 11:23:23 +0200491// Check parent is still of current type (by structure knowledge)
492bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
493{
494 assert(pParent);
495
496 // Up to system class
497 return !!pParent->getParent();
498}