Kevin Rocard | 93250d1 | 2012-07-19 17:48:30 +0200 | [diff] [blame] | 1 | /* |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 2 | * 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 Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 22 | * CREATED: 2011-06-01 |
| 23 | * UPDATED: 2011-07-27 |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 24 | */ |
| 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 | |
| 36 | CSubsystem::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 | |
| 43 | CSubsystem::~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 | |
| 66 | string CSubsystem::getKind() const |
| 67 | { |
| 68 | return "Subsystem"; |
| 69 | } |
| 70 | |
| 71 | // Susbsystem Endianness |
| 72 | bool CSubsystem::isBigEndian() const |
| 73 | { |
| 74 | return _bBigEndian; |
| 75 | } |
| 76 | |
| 77 | // From IXmlSink |
| 78 | bool 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 Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 122 | bool CSubsystem::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 123 | { |
| 124 | // Fix Endianness |
| 125 | configurationAccessContext.setBigEndianSubsystem(_bBigEndian); |
| 126 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 127 | return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | |
| 131 | bool 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 Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 153 | bool CSubsystem::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 154 | { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 155 | // Deal with Endianness |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 156 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 157 | |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 158 | return base::accessValue(pathNavigator, strValue, bSet, parameterAccessContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const |
| 162 | { |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 163 | CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 164 | |
| 165 | // Deal with Endianness |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 166 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 167 | |
| 168 | return base::logValue(strValue, errorContext); |
| 169 | } |
| 170 | |
Patrick Benavoli | 6ccab9d | 2011-11-10 23:21:01 +0100 | [diff] [blame] | 171 | // Used for simulation and virtual subsystems |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 172 | void CSubsystem::setDefaultValues(CParameterAccessContext& parameterAccessContext) const |
| 173 | { |
| 174 | // Deal with Endianness |
| 175 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
| 176 | |
| 177 | base::setDefaultValues(parameterAccessContext); |
| 178 | } |
| 179 | |
| 180 | // Belonging subsystem |
| 181 | const CSubsystem* CSubsystem::getBelongingSubsystem() const |
| 182 | { |
| 183 | return this; |
| 184 | } |
| 185 | |
| 186 | // Subsystem context mapping keys publication |
| 187 | void CSubsystem::addContextMappingKey(const string& strMappingKey) |
| 188 | { |
| 189 | _contextMappingKeyArray.push_back(strMappingKey); |
| 190 | } |
| 191 | |
| 192 | // Subsystem object creator publication (strong reference) |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 193 | void CSubsystem::addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 194 | { |
| 195 | _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator); |
| 196 | } |
| 197 | |
| 198 | // Mapping generic context handling |
| 199 | bool 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 Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 207 | const string* pStrValue; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 208 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 209 | if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 210 | // Assign item to context |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 211 | if (!context.setItem(uiItem, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 212 | |
| 213 | getMappingError(strError, strKey, "Already set", pInstanceConfigurableElement); |
| 214 | |
| 215 | return false; |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | return true; |
| 220 | } |
| 221 | |
| 222 | // Creation handling |
| 223 | bool 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 Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 234 | const string* pStrValue; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 235 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 236 | if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 237 | |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 238 | // First check context consistency (required ancestors must have been set prior to object creation) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 239 | uint32_t uiAncestorKey; |
| 240 | uint32_t uiAncestorMask = pSubsystemObjectCreator->getAncestorMask(); |
| 241 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 242 | for (uiAncestorKey = 0; uiAncestorKey < _contextMappingKeyArray.size(); uiAncestorKey++) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 243 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 244 | if (!((1 << uiAncestorKey) & uiAncestorMask)) { |
| 245 | // Ancestor not required |
| 246 | continue; |
| 247 | } |
| 248 | // Check ancestor was provided |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 249 | if (!context.iSet(uiAncestorKey)) { |
| 250 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 251 | getMappingError(strError, strKey, _contextMappingKeyArray[uiAncestorKey] + " not set", pInstanceConfigurableElement); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 252 | |
| 253 | return false; |
| 254 | } |
| 255 | } |
| 256 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 257 | // Then check configurable element size is correct |
| 258 | if (pInstanceConfigurableElement->getFootPrint() > pSubsystemObjectCreator->getMaxConfigurableElementSize()) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 259 | |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 260 | string strSizeError = "Size should not exceed " + pSubsystemObjectCreator->getMaxConfigurableElementSize(); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 261 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 262 | getMappingError(strError, strKey, strSizeError, pInstanceConfigurableElement); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 263 | |
| 264 | return false; |
| 265 | } |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 266 | |
| 267 | // Do create object and keep its track |
| 268 | _subsystemObjectList.push_back(pSubsystemObjectCreator->objectCreate(*pStrValue, pInstanceConfigurableElement, context)); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 269 | |
| 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 |
| 280 | void CSubsystem::getMappingError(string& strError, const string& strKey, const string& strMessage, const CInstanceConfigurableElement* pInstanceConfigurableElement) |
| 281 | { |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 282 | strError = getName() + " " + getKind() + " mapping:\n" + strKey + " error: \"" + strMessage + "\" for element " + pInstanceConfigurableElement->getPath(); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | // From IMapper |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 286 | bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, string& strError) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 287 | { |
| 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 Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 299 | |
| 300 | // Push context |
| 301 | _contextStack.push(context); |
| 302 | |
| 303 | // Keep diving |
| 304 | bKeepDiving = true; |
| 305 | |
| 306 | return true; |
| 307 | |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 308 | case CInstanceConfigurableElement::EParameterBlock: |
| 309 | case CInstanceConfigurableElement::EBitParameterBlock: |
| 310 | case CInstanceConfigurableElement::EParameter: |
Patrick Benavoli | 1352ae5 | 2011-10-21 16:48:04 +0200 | [diff] [blame] | 311 | case CInstanceConfigurableElement::EStringParameter: |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 312 | |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 313 | if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, strError)) { |
| 314 | |
| 315 | return false; |
| 316 | } |
Patrick Benavoli | d3a86bf | 2011-11-07 19:33:30 +0100 | [diff] [blame] | 317 | |
| 318 | // Done |
| 319 | bKeepDiving = false; |
| 320 | |
| 321 | return true; |
| 322 | |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 323 | default: |
| 324 | assert(0); |
| 325 | return false; |
| 326 | } |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 327 | } |
| 328 | |
| 329 | void CSubsystem::mapEnd() |
| 330 | { |
| 331 | // Unstack context |
| 332 | _contextStack.pop(); |
| 333 | } |