]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | /** @file\r |
2 | CollectPCDAction class.\r | |
3 | \r | |
4 | This action class is to collect PCD information from MSA, SPD, FPD xml file.\r | |
5 | This class will be used for wizard and build tools, So it can *not* inherit\r | |
6 | from buildAction or wizardAction.\r | |
7 | \r | |
8 | Copyright (c) 2006, Intel Corporation\r | |
9 | All rights reserved. This program and the accompanying materials\r | |
10 | are licensed and made available under the terms and conditions of the BSD License\r | |
11 | which accompanies this distribution. The full text of the license may be found at\r | |
12 | http://opensource.org/licenses/bsd-license.php\r | |
13 | \r | |
14 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
15 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
16 | \r | |
17 | **/\r | |
18 | package org.tianocore.build.pcd.action;\r | |
19 | \r | |
20 | import java.io.File;\r | |
21 | import java.io.IOException;\r | |
6f7e61a0 | 22 | import java.math.BigInteger;\r |
878ddf1f | 23 | import java.util.ArrayList;\r |
99d2c3c4 | 24 | import java.util.Comparator;\r |
878ddf1f | 25 | import java.util.HashMap;\r |
136adffc | 26 | import java.util.Iterator;\r |
878ddf1f | 27 | import java.util.List;\r |
136adffc | 28 | import java.util.Map;\r |
29 | import java.util.Set;\r | |
878ddf1f | 30 | import java.util.UUID;\r |
136adffc | 31 | import java.util.regex.Matcher;\r |
32 | import java.util.regex.Pattern;\r | |
878ddf1f | 33 | \r |
34 | import org.apache.xmlbeans.XmlException;\r | |
35 | import org.apache.xmlbeans.XmlObject;\r | |
6ff7a41c | 36 | import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r |
8840ad58 | 37 | import org.tianocore.FrameworkModulesDocument;\r |
878ddf1f | 38 | import org.tianocore.ModuleSADocument;\r |
8d82d611 | 39 | import org.tianocore.PcdBuildDefinitionDocument;\r |
6ff7a41c | 40 | import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r |
8d82d611 | 41 | import org.tianocore.PlatformSurfaceAreaDocument;\r |
7629edbc | 42 | import org.tianocore.build.fpd.FpdParserTask;\r |
878ddf1f | 43 | import org.tianocore.build.global.GlobalData;\r |
136adffc | 44 | import org.tianocore.build.id.FpdModuleIdentification;\r |
d14ebb43 | 45 | import org.tianocore.build.id.ModuleIdentification;\r |
46 | import org.tianocore.pcd.action.ActionMessage;\r | |
47 | import org.tianocore.pcd.entity.CommonDefinition;\r | |
48 | import org.tianocore.pcd.entity.DynamicTokenValue;\r | |
49 | import org.tianocore.pcd.entity.MemoryDatabaseManager;\r | |
50 | import org.tianocore.pcd.entity.SkuInstance;\r | |
51 | import org.tianocore.pcd.entity.Token;\r | |
52 | import org.tianocore.pcd.entity.UsageIdentification;\r | |
53 | import org.tianocore.pcd.entity.UsageInstance;\r | |
54 | import org.tianocore.pcd.exception.EntityException;\r | |
1eb73ab5 | 55 | \r |
eece174a | 56 | /** Module Info class is the data structure to hold information got from GlobalData.\r |
57 | */\r | |
8840ad58 | 58 | class ModuleInfo {\r |
eece174a | 59 | ///\r |
60 | /// Module's ID for a <ModuleSA>\r | |
61 | /// \r | |
62 | private FpdModuleIdentification moduleId;\r | |
63 | ///\r | |
64 | /// <PcdBuildDefinition> xmlobject in FPD file for a <ModuleSA>\r | |
65 | /// \r | |
136adffc | 66 | private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;\r |
8840ad58 | 67 | \r |
eece174a | 68 | public ModuleInfo (FpdModuleIdentification moduleId, XmlObject pcdDef) {\r |
69 | this.moduleId = moduleId;\r | |
70 | this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();\r | |
136adffc | 71 | }\r |
eece174a | 72 | \r |
136adffc | 73 | public FpdModuleIdentification getModuleId (){\r |
eece174a | 74 | return moduleId;\r |
136adffc | 75 | }\r |
eece174a | 76 | \r |
136adffc | 77 | public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){\r |
eece174a | 78 | return pcdBuildDef;\r |
8840ad58 | 79 | }\r |
80 | }\r | |
81 | \r | |
878ddf1f | 82 | /** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r |
83 | This class will be used for wizard and build tools, So it can *not* inherit\r | |
84 | from buildAction or UIAction.\r | |
85 | **/\r | |
86 | public class CollectPCDAction {\r | |
eece174a | 87 | ///\r |
878ddf1f | 88 | /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.\r |
eece174a | 89 | /// \r |
878ddf1f | 90 | private MemoryDatabaseManager dbManager;\r |
eece174a | 91 | ///\r |
878ddf1f | 92 | /// Workspacepath hold the workspace information.\r |
eece174a | 93 | /// \r |
878ddf1f | 94 | private String workspacePath;\r |
eece174a | 95 | ///\r |
878ddf1f | 96 | /// FPD file is the root file. \r |
eece174a | 97 | /// \r |
878ddf1f | 98 | private String fpdFilePath;\r |
eece174a | 99 | ///\r |
878ddf1f | 100 | /// Message level for CollectPCDAction.\r |
eece174a | 101 | /// \r |
878ddf1f | 102 | private int originalMessageLevel;\r |
eece174a | 103 | ///\r |
8840ad58 | 104 | /// Cache the fpd docment instance for private usage.\r |
eece174a | 105 | /// \r |
136adffc | 106 | private PlatformSurfaceAreaDocument fpdDocInstance;\r |
eece174a | 107 | ///\r |
136adffc | 108 | /// xmlObject name\r |
eece174a | 109 | /// \r |
136adffc | 110 | private static String xmlObjectName = "PcdBuildDefinition"; \r |
111 | \r | |
878ddf1f | 112 | /**\r |
113 | Set WorkspacePath parameter for this action class.\r | |
114 | \r | |
115 | @param workspacePath parameter for this action\r | |
116 | **/\r | |
117 | public void setWorkspacePath(String workspacePath) {\r | |
118 | this.workspacePath = workspacePath;\r | |
119 | }\r | |
120 | \r | |
121 | /**\r | |
122 | Set action message level for CollectPcdAction tool.\r | |
123 | \r | |
124 | The message should be restored when this action exit.\r | |
125 | \r | |
126 | @param actionMessageLevel parameter for this action\r | |
127 | **/\r | |
128 | public void setActionMessageLevel(int actionMessageLevel) {\r | |
129 | originalMessageLevel = ActionMessage.messageLevel;\r | |
130 | ActionMessage.messageLevel = actionMessageLevel;\r | |
131 | }\r | |
132 | \r | |
133 | /**\r | |
134 | Set FPDFileName parameter for this action class.\r | |
135 | \r | |
136 | @param fpdFilePath fpd file path\r | |
137 | **/\r | |
138 | public void setFPDFilePath(String fpdFilePath) {\r | |
139 | this.fpdFilePath = fpdFilePath;\r | |
140 | }\r | |
141 | \r | |
142 | /**\r | |
143 | Common function interface for outer.\r | |
144 | \r | |
145 | @param workspacePath The path of workspace of current build or analysis.\r | |
146 | @param fpdFilePath The fpd file path of current build or analysis.\r | |
147 | @param messageLevel The message level for this Action.\r | |
148 | \r | |
149 | @throws Exception The exception of this function. Because it can *not* be predict\r | |
150 | where the action class will be used. So only Exception can be throw.\r | |
151 | \r | |
152 | **/\r | |
153 | public void perform(String workspacePath, String fpdFilePath, \r | |
154 | int messageLevel) throws Exception {\r | |
155 | setWorkspacePath(workspacePath);\r | |
156 | setFPDFilePath(fpdFilePath);\r | |
157 | setActionMessageLevel(messageLevel);\r | |
158 | checkParameter();\r | |
159 | execute();\r | |
160 | ActionMessage.messageLevel = originalMessageLevel;\r | |
161 | }\r | |
162 | \r | |
163 | /**\r | |
164 | Core execution function for this action class.\r | |
165 | \r | |
166 | This function work flows will be:\r | |
8840ad58 | 167 | 1) Collect and prepocess PCD information from FPD file, all PCD\r |
168 | information will be stored into memory database.\r | |
169 | 2) Generate 3 strings for\r | |
170 | a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r | |
171 | b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r | |
172 | c) DXE PCD Database (C structure) for PCD Service DXE.\r | |
99d2c3c4 | 173 | \r |
878ddf1f | 174 | \r |
175 | @throws EntityException Exception indicate failed to execute this action.\r | |
176 | \r | |
177 | **/\r | |
136adffc | 178 | public void execute() throws EntityException {\r |
8840ad58 | 179 | //\r |
180 | // Get memoryDatabaseManager instance from GlobalData.\r | |
181 | // The memoryDatabaseManager should be initialized for whatever build\r | |
182 | // tools or wizard tools\r | |
183 | //\r | |
184 | if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r | |
185 | throw new EntityException("The instance of PCD memory database manager is null");\r | |
186 | }\r | |
878ddf1f | 187 | \r |
188 | //\r | |
189 | // Collect all PCD information defined in FPD file.\r | |
190 | // Evenry token defind in FPD will be created as an token into \r | |
191 | // memory database.\r | |
192 | //\r | |
8840ad58 | 193 | createTokenInDBFromFPD();\r |
99d2c3c4 | 194 | \r |
195 | //\r | |
eece174a | 196 | // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r |
32648c62 | 197 | //\r |
198 | genPcdDatabaseSourceCode ();\r | |
199 | \r | |
878ddf1f | 200 | }\r |
201 | \r | |
32648c62 | 202 | /**\r |
203 | This function generates source code for PCD Database.\r | |
204 | \r | |
205 | @param void\r | |
206 | @throws EntityException If the token does *not* exist in memory database.\r | |
99d2c3c4 | 207 | \r |
32648c62 | 208 | **/\r |
8840ad58 | 209 | private void genPcdDatabaseSourceCode()\r |
210 | throws EntityException {\r | |
eece174a | 211 | String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();\r |
99d2c3c4 | 212 | \r |
32648c62 | 213 | ArrayList<Token> alPei = new ArrayList<Token> ();\r |
214 | ArrayList<Token> alDxe = new ArrayList<Token> ();\r | |
99d2c3c4 | 215 | \r |
32648c62 | 216 | dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);\r |
99d2c3c4 | 217 | PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r |
1eb73ab5 | 218 | pcdPeiDatabase.genCode();\r |
eece174a | 219 | MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() + \r |
220 | PcdDatabase.getPcdPeiDatabaseDefinitions();\r | |
58f1099f | 221 | MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r |
99d2c3c4 | 222 | \r |
eece174a | 223 | PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());\r |
1eb73ab5 | 224 | pcdDxeDatabase.genCode();\r |
eece174a | 225 | MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() + \r |
226 | PcdDatabase.getPcdDxeDatabaseDefinitions();\r | |
58f1099f | 227 | MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r |
32648c62 | 228 | }\r |
229 | \r | |
230 | /**\r | |
8840ad58 | 231 | Get component array from FPD.\r |
878ddf1f | 232 | \r |
8840ad58 | 233 | This function maybe provided by some Global class.\r |
878ddf1f | 234 | \r |
8840ad58 | 235 | @return List<ModuleInfo> the component array.\r |
878ddf1f | 236 | \r |
8840ad58 | 237 | */\r |
238 | private List<ModuleInfo> getComponentsFromFPD() \r | |
878ddf1f | 239 | throws EntityException {\r |
eece174a | 240 | List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();\r |
241 | FrameworkModulesDocument.FrameworkModules fModules = null;\r | |
242 | ModuleSADocument.ModuleSA[] modules = null;\r | |
243 | Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;\r | |
878ddf1f | 244 | \r |
eece174a | 245 | pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();\r |
246 | if (pcdBuildDefinitions == null) {\r | |
247 | return null;\r | |
878ddf1f | 248 | }\r |
249 | \r | |
eece174a | 250 | //\r |
251 | // Loop map to retrieve all PCD build definition and Module id \r | |
252 | // \r | |
253 | Iterator item = pcdBuildDefinitions.keySet().iterator();\r | |
136adffc | 254 | while (item.hasNext()){\r |
eece174a | 255 | FpdModuleIdentification id = (FpdModuleIdentification) item.next();\r |
256 | allModules.add(new ModuleInfo(id, pcdBuildDefinitions.get(id))); \r | |
136adffc | 257 | }\r |
8840ad58 | 258 | \r |
259 | return allModules;\r | |
878ddf1f | 260 | }\r |
261 | \r | |
262 | /**\r | |
263 | Create token instance object into memory database, the token information\r | |
264 | comes for FPD file. Normally, FPD file will contain all token platform \r | |
265 | informations.\r | |
878ddf1f | 266 | \r |
267 | @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.\r | |
268 | \r | |
269 | @throws EntityException Failed to parse FPD xml file.\r | |
270 | \r | |
271 | **/\r | |
8840ad58 | 272 | private void createTokenInDBFromFPD() \r |
878ddf1f | 273 | throws EntityException {\r |
8840ad58 | 274 | int index = 0;\r |
275 | int index2 = 0;\r | |
276 | int pcdIndex = 0;\r | |
6ff7a41c | 277 | List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r |
278 | PcdBuildDefinition.PcdData pcdBuildData = null;\r | |
8840ad58 | 279 | Token token = null;\r |
8840ad58 | 280 | List<ModuleInfo> modules = null;\r |
281 | String primaryKey = null;\r | |
8840ad58 | 282 | String exceptionString = null;\r |
283 | UsageInstance usageInstance = null;\r | |
284 | String primaryKey1 = null;\r | |
285 | String primaryKey2 = null;\r | |
286 | boolean isDuplicate = false;\r | |
6ff7a41c | 287 | Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r |
288 | Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r | |
548ce97a | 289 | long tokenNumber = 0;\r |
6ff7a41c | 290 | String moduleName = null;\r |
291 | String datum = null;\r | |
292 | int maxDatumSize = 0;\r | |
548ce97a | 293 | String[] tokenSpaceStrRet = null;\r |
d14ebb43 | 294 | UsageIdentification usageId = null;\r |
295 | ModuleIdentification moduleId = null;\r | |
548ce97a | 296 | \r |
878ddf1f | 297 | //\r |
6ff7a41c | 298 | // ----------------------------------------------\r |
299 | // 1), Get all <ModuleSA> from FPD file.\r | |
300 | // ----------------------------------------------\r | |
878ddf1f | 301 | // \r |
8840ad58 | 302 | modules = getComponentsFromFPD();\r |
878ddf1f | 303 | \r |
8840ad58 | 304 | if (modules == null) {\r |
7db4ab70 | 305 | throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r |
878ddf1f | 306 | }\r |
307 | \r | |
308 | //\r | |
6ff7a41c | 309 | // -------------------------------------------------------------------\r |
310 | // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r | |
311 | // -------------------------------------------------------------------\r | |
8840ad58 | 312 | // \r |
313 | for (index = 0; index < modules.size(); index ++) {\r | |
6ff7a41c | 314 | //\r |
315 | // It is legal for a module does not contains ANY pcd build definitions.\r | |
316 | // \r | |
136adffc | 317 | if (modules.get(index).getPcdBuildDef() == null) {\r |
8840ad58 | 318 | continue;\r |
6ff7a41c | 319 | }\r |
320 | \r | |
136adffc | 321 | pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();\r |
6ff7a41c | 322 | \r |
136adffc | 323 | moduleName = modules.get(index).getModuleId().getModule().getName();\r |
878ddf1f | 324 | \r |
878ddf1f | 325 | //\r |
6ff7a41c | 326 | // ----------------------------------------------------------------------\r |
327 | // 2.1), Loop all Pcd entry for a module and add it into memory database.\r | |
328 | // ----------------------------------------------------------------------\r | |
8840ad58 | 329 | // \r |
330 | for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {\r | |
331 | pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r | |
548ce97a | 332 | \r |
333 | try {\r | |
334 | tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r | |
335 | } catch ( Exception e ) {\r | |
336 | throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r | |
337 | }\r | |
338 | \r | |
339 | if (tokenSpaceStrRet == null) {\r | |
340 | throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r | |
341 | } \r | |
342 | \r | |
eece174a | 343 | primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r |
6ff7a41c | 344 | pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r |
345 | datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r | |
51da9e80 | 346 | tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r |
6c4dc226 | 347 | if (pcdBuildData.getValue() != null) {\r |
348 | datum = pcdBuildData.getValue().toString();\r | |
349 | } else {\r | |
350 | datum = null;\r | |
351 | }\r | |
6ff7a41c | 352 | maxDatumSize = pcdBuildData.getMaxDatumSize();\r |
8840ad58 | 353 | \r |
bab72a57 | 354 | if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r |
355 | (datumType != Token.DATUM_TYPE.BOOLEAN)){\r | |
356 | exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r | |
357 | "datum type of this PCD entry is not BOOLEAN!",\r | |
358 | pcdBuildData.getCName(),\r | |
359 | moduleName);\r | |
360 | throw new EntityException(exceptionString);\r | |
361 | }\r | |
362 | \r | |
6ff7a41c | 363 | //\r |
364 | // -------------------------------------------------------------------------------------------\r | |
365 | // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r | |
366 | // -------------------------------------------------------------------------------------------\r | |
367 | // \r | |
368 | if (!Token.isDynamic(pcdType)) {\r | |
369 | //\r | |
370 | // Value is required.\r | |
371 | // \r | |
372 | if (datum == null) {\r | |
7db4ab70 | 373 | exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r |
6ff7a41c | 374 | pcdBuildData.getCName(),\r |
375 | moduleName);\r | |
376 | throw new EntityException(exceptionString);\r | |
377 | }\r | |
378 | \r | |
379 | //\r | |
380 | // Check whether the datum size is matched datum type.\r | |
381 | // \r | |
6f7e61a0 | 382 | if ((exceptionString = verifyDatum(pcdBuildData.getCName(), \r |
383 | moduleName,\r | |
384 | datum,\r | |
385 | datumType,\r | |
386 | maxDatumSize)) != null) {\r | |
6ff7a41c | 387 | throw new EntityException(exceptionString);\r |
388 | }\r | |
389 | }\r | |
8840ad58 | 390 | \r |
6ff7a41c | 391 | //\r |
392 | // ---------------------------------------------------------------------------------\r | |
393 | // 2.1.2), Create token or update token information for current anaylized PCD data.\r | |
394 | // ---------------------------------------------------------------------------------\r | |
395 | // \r | |
8840ad58 | 396 | if (dbManager.isTokenInDatabase(primaryKey)) {\r |
397 | //\r | |
398 | // If the token is already exist in database, do some necessary checking\r | |
399 | // and add a usage instance into this token in database\r | |
400 | // \r | |
401 | token = dbManager.getTokenByKey(primaryKey);\r | |
6ff7a41c | 402 | \r |
403 | //\r | |
404 | // checking for DatumType, DatumType should be unique for one PCD used in different\r | |
405 | // modules.\r | |
406 | // \r | |
407 | if (token.datumType != datumType) {\r | |
7db4ab70 | 408 | exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",\r |
6ff7a41c | 409 | pcdBuildData.getCName(), \r |
410 | pcdBuildData.getDatumType().toString(), \r | |
411 | Token.getStringOfdatumType(token.datumType));\r | |
412 | throw new EntityException(exceptionString);\r | |
413 | }\r | |
8840ad58 | 414 | \r |
878ddf1f | 415 | //\r |
6ff7a41c | 416 | // Check token number is valid\r |
8840ad58 | 417 | // \r |
6ff7a41c | 418 | if (tokenNumber != token.tokenNumber) {\r |
7db4ab70 | 419 | exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",\r |
6ff7a41c | 420 | pcdBuildData.getCName(),\r |
421 | moduleName);\r | |
8840ad58 | 422 | throw new EntityException(exceptionString);\r |
423 | }\r | |
424 | \r | |
878ddf1f | 425 | //\r |
6ff7a41c | 426 | // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r |
8840ad58 | 427 | // \r |
6ff7a41c | 428 | if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r |
7db4ab70 | 429 | exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r |
6ff7a41c | 430 | "is different with others module's",\r |
431 | token.cName,\r | |
432 | moduleName);\r | |
8840ad58 | 433 | throw new EntityException(exceptionString);\r |
434 | }\r | |
6ff7a41c | 435 | \r |
436 | if (token.isDynamicPCD) {\r | |
437 | //\r | |
438 | // Check datum is equal the datum in dynamic information.\r | |
439 | // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r | |
440 | // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r | |
441 | // \r | |
442 | if (!token.isSkuEnable() && \r | |
7db4ab70 | 443 | (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r |
444 | (datum != null)) {\r | |
445 | if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r | |
446 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r | |
6ff7a41c | 447 | "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r |
7db4ab70 | 448 | "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r |
6ff7a41c | 449 | token.cName,\r |
450 | moduleName);\r | |
7db4ab70 | 451 | throw new EntityException(exceptionString);\r |
6ff7a41c | 452 | }\r |
453 | }\r | |
7db4ab70 | 454 | \r |
455 | if ((maxDatumSize != 0) &&\r | |
456 | (maxDatumSize != token.datumSize)){\r | |
457 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r | |
458 | "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r | |
459 | token.cName,\r | |
460 | moduleName,\r | |
461 | maxDatumSize,\r | |
462 | token.datumSize);\r | |
463 | throw new EntityException(exceptionString);\r | |
464 | }\r | |
6ff7a41c | 465 | }\r |
466 | \r | |
8840ad58 | 467 | } else {\r |
468 | //\r | |
469 | // If the token is not in database, create a new token instance and add\r | |
470 | // a usage instance into this token in database.\r | |
471 | // \r | |
548ce97a | 472 | try {\r |
473 | tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r | |
474 | } catch (Exception e) {\r | |
475 | throw new EntityException("Fail to get token space guid for token " + token.cName);\r | |
476 | }\r | |
477 | \r | |
478 | if (tokenSpaceStrRet == null) {\r | |
479 | throw new EntityException("Fail to get token space guid for token " + token.cName);\r | |
480 | }\r | |
481 | \r | |
eece174a | 482 | token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r |
6ff7a41c | 483 | \r |
484 | token.datumType = datumType;\r | |
485 | token.tokenNumber = tokenNumber;\r | |
486 | token.isDynamicPCD = Token.isDynamic(pcdType);\r | |
487 | token.datumSize = maxDatumSize;\r | |
488 | \r | |
489 | if (token.isDynamicPCD) {\r | |
490 | //\r | |
491 | // For Dynamic and Dynamic Ex type, need find the dynamic information\r | |
492 | // in <DynamicPcdBuildDefinition> section in FPD file.\r | |
493 | // \r | |
494 | updateDynamicInformation(moduleName, \r | |
495 | token,\r | |
496 | datum,\r | |
497 | maxDatumSize);\r | |
8840ad58 | 498 | }\r |
6ff7a41c | 499 | \r |
8840ad58 | 500 | dbManager.addTokenToDatabase(primaryKey, token);\r |
878ddf1f | 501 | }\r |
878ddf1f | 502 | \r |
878ddf1f | 503 | //\r |
6ff7a41c | 504 | // -----------------------------------------------------------------------------------\r |
505 | // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r | |
506 | // -----------------------------------------------------------------------------------\r | |
507 | // \r | |
508 | token.updateSupportPcdType(pcdType);\r | |
509 | \r | |
510 | //\r | |
511 | // ------------------------------------------------\r | |
512 | // 2.1.4), Create an usage instance for this token.\r | |
513 | // ------------------------------------------------\r | |
8840ad58 | 514 | // \r |
d14ebb43 | 515 | moduleId = modules.get(index).getModuleId().getModule();\r |
516 | usageId = new UsageIdentification (moduleId.getName(), \r | |
517 | moduleId.getGuid(), \r | |
518 | moduleId.getPackage().getName(), \r | |
519 | moduleId.getPackage().getGuid(), \r | |
520 | modules.get(index).getModuleId().getArch(),\r | |
521 | moduleId.getVersion(),\r | |
522 | moduleId.getModuleType());\r | |
8840ad58 | 523 | usageInstance = new UsageInstance(token, \r |
d14ebb43 | 524 | usageId,\r |
6ff7a41c | 525 | pcdType,\r |
6ff7a41c | 526 | datum,\r |
527 | maxDatumSize);\r | |
8840ad58 | 528 | token.addUsageInstance(usageInstance);\r |
878ddf1f | 529 | }\r |
878ddf1f | 530 | }\r |
8d82d611 | 531 | \r |
532 | //\r | |
533 | // ------------------------------------------------\r | |
534 | // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r | |
535 | // ------------------------------------------------\r | |
536 | // \r | |
537 | List<Token> tokenArray = getUnreferencedDynamicPcd();\r | |
538 | if (tokenArray != null) {\r | |
539 | for (index = 0; index < tokenArray.size(); index ++) {\r | |
540 | dbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(), \r | |
541 | tokenArray.get(index));\r | |
542 | }\r | |
543 | }\r | |
544 | }\r | |
545 | \r | |
546 | private List<Token> getUnreferencedDynamicPcd () throws EntityException {\r | |
78d0508a | 547 | List<Token> tokenArray = new ArrayList<Token>();\r |
8d82d611 | 548 | Token token = null;\r |
549 | DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r | |
550 | List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r | |
551 | DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = null;\r | |
552 | List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r | |
553 | Token.PCD_TYPE pcdType;\r | |
554 | SkuInstance skuInstance = null;\r | |
555 | String primaryKey = null;\r | |
556 | boolean hasSkuId0 = false;\r | |
557 | int index, offset, index2;\r | |
558 | String temp;\r | |
559 | String exceptionString;\r | |
560 | String hiiDefaultValue;\r | |
561 | String tokenSpaceStrRet[];\r | |
562 | String variableGuidString[];\r | |
563 | \r | |
564 | //\r | |
eece174a | 565 | // Open fpd document to get <DynamicPcdBuildDefinition> Section.\r |
566 | // BUGBUG: the function should be move GlobalData in furture.\r | |
8d82d611 | 567 | // \r |
568 | if (fpdDocInstance == null) {\r | |
569 | try {\r | |
570 | fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r | |
571 | } catch(IOException ioE) {\r | |
572 | throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r | |
573 | } catch(XmlException xmlE) {\r | |
574 | throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r | |
575 | }\r | |
576 | }\r | |
577 | \r | |
578 | dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r | |
579 | if (dynamicPcdBuildDefinitions == null) {\r | |
580 | return null;\r | |
581 | }\r | |
582 | \r | |
583 | dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r | |
584 | for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2 ++) {\r | |
585 | pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r | |
586 | try {\r | |
587 | tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r | |
588 | } catch ( Exception e ) {\r | |
589 | throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r | |
590 | }\r | |
591 | \r | |
592 | if (tokenSpaceStrRet == null) {\r | |
593 | throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r | |
594 | } \r | |
595 | \r | |
596 | primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r | |
eece174a | 597 | tokenSpaceStrRet[1]);\r |
8d82d611 | 598 | \r |
599 | if (dbManager.isTokenInDatabase(primaryKey)) {\r | |
600 | continue;\r | |
601 | }\r | |
602 | \r | |
603 | pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r | |
604 | if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r | |
605 | throw new EntityException (String.format("[FPD file error] It not allowed for DYNAMIC PCD %s who is no used by any module",\r | |
606 | pcdBuildData.getCName()));\r | |
607 | }\r | |
608 | \r | |
609 | //\r | |
610 | // Create new token for unreference dynamic PCD token\r | |
611 | // \r | |
eece174a | 612 | token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r |
8d82d611 | 613 | token.datumSize = pcdBuildData.getMaxDatumSize();\r |
614 | \r | |
615 | \r | |
616 | token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r | |
617 | token.tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r | |
618 | token.dynamicExTokenNumber = token.tokenNumber;\r | |
619 | token.isDynamicPCD = true; \r | |
620 | token.updateSupportPcdType(pcdType);\r | |
621 | \r | |
622 | exceptionString = verifyDatum(token.cName, \r | |
623 | null,\r | |
624 | null, \r | |
625 | token.datumType, \r | |
626 | token.datumSize);\r | |
627 | if (exceptionString != null) {\r | |
628 | throw new EntityException(exceptionString);\r | |
629 | }\r | |
630 | \r | |
631 | skuInfoList = pcdBuildData.getSkuInfoList();\r | |
632 | \r | |
633 | //\r | |
634 | // Loop all sku data \r | |
635 | // \r | |
636 | for (index = 0; index < skuInfoList.size(); index ++) {\r | |
637 | skuInstance = new SkuInstance();\r | |
638 | //\r | |
639 | // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r | |
640 | // \r | |
641 | temp = skuInfoList.get(index).getSkuId().toString();\r | |
642 | skuInstance.id = Integer.decode(temp);\r | |
643 | if (skuInstance.id == 0) {\r | |
644 | hasSkuId0 = true;\r | |
645 | }\r | |
646 | //\r | |
647 | // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r | |
648 | // \r | |
649 | if (skuInfoList.get(index).getValue() != null) {\r | |
650 | skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r | |
651 | if ((exceptionString = verifyDatum(token.cName, \r | |
652 | null, \r | |
653 | skuInfoList.get(index).getValue().toString(), \r | |
654 | token.datumType, \r | |
655 | token.datumSize)) != null) {\r | |
656 | throw new EntityException(exceptionString);\r | |
657 | }\r | |
658 | \r | |
659 | token.skuData.add(skuInstance);\r | |
660 | \r | |
661 | continue;\r | |
662 | }\r | |
663 | \r | |
664 | //\r | |
665 | // Judge whether is HII group case.\r | |
666 | // \r | |
667 | if (skuInfoList.get(index).getVariableName() != null) {\r | |
668 | exceptionString = null;\r | |
669 | if (skuInfoList.get(index).getVariableGuid() == null) {\r | |
670 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r | |
671 | "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r | |
672 | token.cName,\r | |
673 | index);\r | |
674 | if (exceptionString != null) {\r | |
675 | throw new EntityException(exceptionString);\r | |
676 | } \r | |
677 | }\r | |
678 | \r | |
679 | if (skuInfoList.get(index).getVariableOffset() == null) {\r | |
680 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r | |
681 | "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r | |
682 | token.cName,\r | |
683 | index);\r | |
684 | if (exceptionString != null) {\r | |
685 | throw new EntityException(exceptionString);\r | |
686 | }\r | |
687 | }\r | |
688 | \r | |
689 | if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r | |
690 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r | |
691 | "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r | |
692 | token.cName,\r | |
693 | index);\r | |
694 | if (exceptionString != null) {\r | |
695 | throw new EntityException(exceptionString);\r | |
696 | }\r | |
697 | }\r | |
698 | \r | |
699 | if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r | |
700 | hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r | |
701 | } else {\r | |
702 | hiiDefaultValue = null;\r | |
703 | }\r | |
704 | \r | |
705 | if ((exceptionString = verifyDatum(token.cName, \r | |
706 | null, \r | |
707 | hiiDefaultValue, \r | |
708 | token.datumType, \r | |
709 | token.datumSize)) != null) {\r | |
710 | throw new EntityException(exceptionString);\r | |
711 | }\r | |
712 | \r | |
713 | offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r | |
714 | if (offset > 0xFFFF) {\r | |
715 | throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r | |
716 | "exceed 64K, it is not allowed!",\r | |
717 | token.cName,\r | |
718 | index));\r | |
719 | }\r | |
720 | \r | |
721 | //\r | |
722 | // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r | |
723 | // \r | |
724 | variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r | |
725 | if (variableGuidString == null) {\r | |
726 | throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r | |
727 | token.cName, \r | |
728 | skuInfoList.get(index).getVariableGuid().toString()));\r | |
729 | }\r | |
730 | String variableStr = skuInfoList.get(index).getVariableName();\r | |
731 | Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r | |
732 | Matcher matcher = pattern.matcher(variableStr);\r | |
733 | List<String> varNameList = new ArrayList<String>();\r | |
734 | while (matcher.find()){\r | |
735 | String str = variableStr.substring(matcher.start(),matcher.end());\r | |
736 | varNameList.add(str);\r | |
737 | }\r | |
738 | \r | |
739 | skuInstance.value.setHiiData(varNameList,\r | |
740 | translateSchemaStringToUUID(variableGuidString[1]),\r | |
741 | skuInfoList.get(index).getVariableOffset(),\r | |
742 | skuInfoList.get(index).getHiiDefaultValue().toString());\r | |
743 | token.skuData.add(skuInstance);\r | |
744 | continue;\r | |
745 | }\r | |
746 | \r | |
747 | if (skuInfoList.get(index).getVpdOffset() != null) {\r | |
748 | skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r | |
749 | token.skuData.add(skuInstance);\r | |
750 | continue;\r | |
751 | }\r | |
752 | \r | |
753 | exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r | |
754 | "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r | |
755 | token.cName);\r | |
756 | throw new EntityException(exceptionString);\r | |
757 | }\r | |
758 | \r | |
759 | if (!hasSkuId0) {\r | |
760 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r | |
761 | "no sku id = 0 data, which is required for every dynamic PCD",\r | |
762 | token.cName);\r | |
763 | throw new EntityException(exceptionString);\r | |
764 | }\r | |
765 | \r | |
766 | tokenArray.add(token);\r | |
767 | }\r | |
768 | \r | |
769 | return tokenArray;\r | |
878ddf1f | 770 | }\r |
771 | \r | |
6f7e61a0 | 772 | /**\r |
773 | Verify the datum value according its datum size and datum type, this\r | |
774 | function maybe moved to FPD verification tools in future.\r | |
775 | \r | |
776 | @param cName\r | |
777 | @param moduleName\r | |
778 | @param datum\r | |
779 | @param datumType\r | |
780 | @param maxDatumSize\r | |
781 | \r | |
782 | @return String\r | |
783 | */\r | |
784 | /***/\r | |
785 | public String verifyDatum(String cName,\r | |
786 | String moduleName,\r | |
787 | String datum, \r | |
788 | Token.DATUM_TYPE datumType, \r | |
789 | int maxDatumSize) {\r | |
790 | String exceptionString = null;\r | |
791 | int value;\r | |
792 | BigInteger value64;\r | |
793 | String subStr;\r | |
f63ef4b2 | 794 | int index;\r |
6f7e61a0 | 795 | \r |
796 | if (moduleName == null) {\r | |
797 | moduleName = "section <DynamicPcdBuildDefinitions>";\r | |
798 | } else {\r | |
799 | moduleName = "module " + moduleName;\r | |
800 | }\r | |
801 | \r | |
802 | if (maxDatumSize == 0) {\r | |
803 | exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r | |
804 | cName,\r | |
805 | moduleName);\r | |
806 | return exceptionString;\r | |
807 | }\r | |
808 | \r | |
809 | switch (datumType) {\r | |
810 | case UINT8:\r | |
811 | if (maxDatumSize != 1) {\r | |
812 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
813 | "is UINT8, but datum size is %d, they are not matched!",\r | |
814 | cName,\r | |
815 | moduleName,\r | |
816 | maxDatumSize);\r | |
817 | return exceptionString;\r | |
818 | }\r | |
819 | \r | |
820 | if (datum != null) {\r | |
821 | try {\r | |
822 | value = Integer.decode(datum);\r | |
823 | } catch (NumberFormatException nfeExp) {\r | |
824 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r | |
825 | "digital format of UINT8",\r | |
826 | cName,\r | |
827 | moduleName);\r | |
828 | return exceptionString;\r | |
829 | }\r | |
830 | if (value > 0xFF) {\r | |
831 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r | |
832 | " the max size of UINT8 - 0xFF",\r | |
833 | cName, \r | |
834 | moduleName,\r | |
835 | datum);\r | |
836 | return exceptionString;\r | |
837 | }\r | |
838 | }\r | |
839 | break;\r | |
840 | case UINT16:\r | |
841 | if (maxDatumSize != 2) {\r | |
842 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
843 | "is UINT16, but datum size is %d, they are not matched!",\r | |
844 | cName,\r | |
845 | moduleName,\r | |
846 | maxDatumSize);\r | |
847 | return exceptionString;\r | |
848 | }\r | |
849 | if (datum != null) {\r | |
850 | try {\r | |
851 | value = Integer.decode(datum);\r | |
852 | } catch (NumberFormatException nfeExp) {\r | |
853 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r | |
854 | "not valid digital of UINT16",\r | |
855 | cName,\r | |
856 | moduleName);\r | |
857 | return exceptionString;\r | |
858 | }\r | |
859 | if (value > 0xFFFF) {\r | |
860 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r | |
861 | "which exceed the range of UINT16 - 0xFFFF",\r | |
862 | cName, \r | |
863 | moduleName,\r | |
864 | datum);\r | |
865 | return exceptionString;\r | |
866 | }\r | |
867 | }\r | |
868 | break;\r | |
869 | case UINT32:\r | |
870 | if (maxDatumSize != 4) {\r | |
871 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
872 | "is UINT32, but datum size is %d, they are not matched!",\r | |
873 | cName,\r | |
874 | moduleName,\r | |
875 | maxDatumSize);\r | |
876 | return exceptionString;\r | |
877 | }\r | |
878 | \r | |
879 | if (datum != null) {\r | |
880 | try {\r | |
881 | if (datum.length() > 2) {\r | |
882 | if ((datum.charAt(0) == '0') && \r | |
883 | ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r | |
884 | subStr = datum.substring(2, datum.length());\r | |
885 | value64 = new BigInteger(subStr, 16);\r | |
886 | } else {\r | |
887 | value64 = new BigInteger(datum);\r | |
888 | }\r | |
889 | } else {\r | |
890 | value64 = new BigInteger(datum);\r | |
891 | }\r | |
892 | } catch (NumberFormatException nfeExp) {\r | |
893 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r | |
894 | "valid digital of UINT32",\r | |
895 | cName,\r | |
896 | moduleName);\r | |
897 | return exceptionString;\r | |
898 | }\r | |
899 | \r | |
900 | if (value64.bitLength() > 32) {\r | |
901 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r | |
902 | "exceed the range of UINT32 - 0xFFFFFFFF",\r | |
903 | cName, \r | |
904 | moduleName,\r | |
905 | datum);\r | |
906 | return exceptionString;\r | |
907 | }\r | |
908 | }\r | |
909 | break;\r | |
910 | case UINT64:\r | |
911 | if (maxDatumSize != 8) {\r | |
912 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
913 | "is UINT64, but datum size is %d, they are not matched!",\r | |
914 | cName,\r | |
915 | moduleName,\r | |
916 | maxDatumSize);\r | |
917 | return exceptionString;\r | |
918 | }\r | |
919 | \r | |
920 | if (datum != null) {\r | |
921 | try {\r | |
922 | if (datum.length() > 2) {\r | |
923 | if ((datum.charAt(0) == '0') && \r | |
924 | ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r | |
925 | subStr = datum.substring(2, datum.length());\r | |
926 | value64 = new BigInteger(subStr, 16);\r | |
927 | } else {\r | |
928 | value64 = new BigInteger(datum);\r | |
929 | }\r | |
930 | } else {\r | |
931 | value64 = new BigInteger(datum);\r | |
932 | }\r | |
933 | } catch (NumberFormatException nfeExp) {\r | |
934 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r | |
935 | " digital of UINT64",\r | |
936 | cName,\r | |
937 | moduleName);\r | |
938 | return exceptionString;\r | |
939 | }\r | |
940 | \r | |
941 | if (value64.bitLength() > 64) {\r | |
942 | exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r | |
943 | "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r | |
944 | cName, \r | |
945 | moduleName,\r | |
946 | datum);\r | |
947 | return exceptionString;\r | |
948 | }\r | |
949 | }\r | |
950 | break;\r | |
951 | case BOOLEAN:\r | |
952 | if (maxDatumSize != 1) {\r | |
953 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
954 | "is BOOLEAN, but datum size is %d, they are not matched!",\r | |
955 | cName,\r | |
956 | moduleName,\r | |
957 | maxDatumSize);\r | |
958 | return exceptionString;\r | |
959 | }\r | |
960 | \r | |
961 | if (datum != null) {\r | |
962 | if (!(datum.equalsIgnoreCase("TRUE") ||\r | |
963 | datum.equalsIgnoreCase("FALSE"))) {\r | |
964 | exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r | |
965 | "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r | |
966 | cName,\r | |
967 | moduleName);\r | |
968 | return exceptionString;\r | |
969 | }\r | |
970 | \r | |
971 | }\r | |
972 | break;\r | |
973 | case POINTER:\r | |
974 | if (datum == null) {\r | |
975 | break;\r | |
976 | }\r | |
977 | \r | |
978 | char ch = datum.charAt(0);\r | |
979 | int start, end;\r | |
980 | String strValue;\r | |
981 | //\r | |
982 | // For void* type PCD, only three datum is support:\r | |
983 | // 1) Unicode: string with start char is "L"\r | |
984 | // 2) Ansci: String start char is ""\r | |
985 | // 3) byte array: String start char "{"\r | |
986 | // \r | |
987 | if (ch == 'L') {\r | |
988 | start = datum.indexOf('\"');\r | |
989 | end = datum.lastIndexOf('\"');\r | |
990 | if ((start > end) || \r | |
991 | (end > datum.length())||\r | |
992 | ((start == end) && (datum.length() > 0))) {\r | |
f63ef4b2 | 993 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r |
6f7e61a0 | 994 | "a UNICODE string because start with L\", but format maybe"+\r |
995 | "is not right, correct UNICODE string is L\"...\"!",\r | |
996 | cName,\r | |
997 | moduleName);\r | |
998 | return exceptionString;\r | |
999 | }\r | |
1000 | \r | |
1001 | strValue = datum.substring(start + 1, end);\r | |
1002 | if ((strValue.length() * 2) > maxDatumSize) {\r | |
f63ef4b2 | 1003 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r |
6f7e61a0 | 1004 | "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r |
1005 | cName,\r | |
1006 | moduleName,\r | |
1007 | strValue.length() * 2, \r | |
1008 | maxDatumSize);\r | |
1009 | return exceptionString;\r | |
1010 | }\r | |
1011 | } else if (ch == '\"'){\r | |
1012 | start = datum.indexOf('\"');\r | |
1013 | end = datum.lastIndexOf('\"');\r | |
1014 | if ((start > end) || \r | |
1015 | (end > datum.length())||\r | |
1016 | ((start == end) && (datum.length() > 0))) {\r | |
f63ef4b2 | 1017 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r |
6f7e61a0 | 1018 | "a ANSCII string because start with \", but format maybe"+\r |
1019 | "is not right, correct ANSIC string is \"...\"!",\r | |
1020 | cName,\r | |
1021 | moduleName);\r | |
1022 | return exceptionString;\r | |
1023 | }\r | |
1024 | strValue = datum.substring(start + 1, end);\r | |
1025 | if ((strValue.length()) > maxDatumSize) {\r | |
f63ef4b2 | 1026 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r |
6f7e61a0 | 1027 | "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r |
1028 | cName,\r | |
1029 | moduleName,\r | |
1030 | strValue.length(),\r | |
1031 | maxDatumSize);\r | |
1032 | return exceptionString;\r | |
1033 | }\r | |
1034 | } else if (ch =='{') {\r | |
1035 | String[] strValueArray;\r | |
1036 | \r | |
1037 | start = datum.indexOf('{');\r | |
1038 | end = datum.lastIndexOf('}');\r | |
f63ef4b2 | 1039 | strValue = datum.substring(start + 1, end);\r |
1040 | strValue = strValue.trim();\r | |
1041 | if (strValue.length() == 0) {\r | |
6ab88a7c | 1042 | exceptionString = String.format ("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r |
1043 | "it is byte array in fact, but '{}' is not valid for NULL datam but"+\r | |
1044 | " need use '{0}'",\r | |
1045 | cName,\r | |
1046 | moduleName);\r | |
1047 | return exceptionString;\r | |
f63ef4b2 | 1048 | }\r |
6f7e61a0 | 1049 | strValueArray = strValue.split(",");\r |
f63ef4b2 | 1050 | for (index = 0; index < strValueArray.length; index ++) {\r |
1051 | try{\r | |
2435723a | 1052 | value = Integer.decode(strValueArray[index].trim());\r |
f63ef4b2 | 1053 | } catch (NumberFormatException nfeEx) {\r |
1054 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r | |
1055 | "it is byte array in fact. For every byte in array should be a valid"+\r | |
1056 | "byte digital, but element %s is not a valid byte digital!",\r | |
1057 | cName,\r | |
1058 | moduleName,\r | |
1059 | strValueArray[index]);\r | |
1060 | return exceptionString;\r | |
1061 | }\r | |
1062 | if (value > 0xFF) {\r | |
1063 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r | |
1064 | "it is byte array in fact. But the element of %s exceed the byte range",\r | |
1065 | cName,\r | |
1066 | moduleName,\r | |
1067 | strValueArray[index]);\r | |
1068 | return exceptionString;\r | |
1069 | }\r | |
1070 | }\r | |
1071 | \r | |
6f7e61a0 | 1072 | if (strValueArray.length > maxDatumSize) {\r |
f63ef4b2 | 1073 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r |
6f7e61a0 | 1074 | "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r |
1075 | cName,\r | |
1076 | moduleName,\r | |
1077 | strValueArray.length,\r | |
1078 | maxDatumSize);\r | |
1079 | return exceptionString;\r | |
1080 | }\r | |
1081 | } else {\r | |
f63ef4b2 | 1082 | exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+\r |
6f7e61a0 | 1083 | "1) UNICODE string: like L\"xxxx\";\r\n"+\r |
1084 | "2) ANSIC string: like \"xxx\";\r\n"+\r | |
1085 | "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r | |
1086 | "But the datum in seems does not following above format!",\r | |
1087 | cName, \r | |
1088 | moduleName);\r | |
1089 | return exceptionString;\r | |
1090 | }\r | |
1091 | break;\r | |
1092 | default:\r | |
1093 | exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r | |
1094 | "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r | |
1095 | cName,\r | |
1096 | moduleName);\r | |
1097 | return exceptionString;\r | |
1098 | }\r | |
1099 | return null;\r | |
1100 | }\r | |
1101 | \r | |
878ddf1f | 1102 | /**\r |
6ff7a41c | 1103 | Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r |
8840ad58 | 1104 | \r |
6ff7a41c | 1105 | This function should be implemented in GlobalData in future.\r |
8840ad58 | 1106 | \r |
6ff7a41c | 1107 | @param token The token instance which has hold module's PCD information\r |
1108 | @param moduleName The name of module who will use this Dynamic PCD.\r | |
8840ad58 | 1109 | \r |
6ff7a41c | 1110 | @return DynamicPcdBuildDefinitions.PcdBuildData\r |
1111 | */\r | |
1112 | /***/\r | |
1113 | private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,\r | |
1114 | String moduleName)\r | |
878ddf1f | 1115 | throws EntityException {\r |
6ff7a41c | 1116 | int index = 0;\r |
1117 | String exceptionString = null;\r | |
1118 | String dynamicPrimaryKey = null;\r | |
1119 | DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r | |
1120 | List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r | |
548ce97a | 1121 | String[] tokenSpaceStrRet = null;\r |
878ddf1f | 1122 | \r |
3d52de13 | 1123 | //\r |
8840ad58 | 1124 | // If FPD document is not be opened, open and initialize it.\r |
eece174a | 1125 | // BUGBUG: The code should be moved into GlobalData in future.\r |
8840ad58 | 1126 | // \r |
1127 | if (fpdDocInstance == null) {\r | |
1128 | try {\r | |
136adffc | 1129 | fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r |
8840ad58 | 1130 | } catch(IOException ioE) {\r |
1131 | throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r | |
1132 | } catch(XmlException xmlE) {\r | |
1133 | throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r | |
1134 | }\r | |
3d52de13 | 1135 | }\r |
136adffc | 1136 | \r |
1137 | dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r | |
6ff7a41c | 1138 | if (dynamicPcdBuildDefinitions == null) {\r |
7db4ab70 | 1139 | exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r |
6ff7a41c | 1140 | "PCD entry %s in module %s!",\r |
1141 | token.cName,\r | |
1142 | moduleName);\r | |
1143 | throw new EntityException(exceptionString);\r | |
3d52de13 | 1144 | }\r |
8840ad58 | 1145 | \r |
6ff7a41c | 1146 | dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r |
1147 | for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r | |
136adffc | 1148 | //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];\r |
1149 | String tokenSpaceGuidString = null;\r | |
548ce97a | 1150 | try {\r |
1151 | tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r | |
1152 | } catch (Exception e) {\r | |
1153 | throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r | |
1154 | }\r | |
1155 | \r | |
1156 | if (tokenSpaceStrRet == null) {\r | |
1157 | throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r | |
1158 | }\r | |
1159 | \r | |
6ff7a41c | 1160 | dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r |
eece174a | 1161 | tokenSpaceStrRet[1]);\r |
6ff7a41c | 1162 | if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r |
1163 | return dynamicPcdBuildDataArray.get(index);\r | |
1164 | }\r | |
8840ad58 | 1165 | }\r |
1166 | \r | |
6ff7a41c | 1167 | return null;\r |
1168 | }\r | |
1169 | \r | |
6ff7a41c | 1170 | /**\r |
1171 | Update dynamic information for PCD entry.\r | |
1172 | \r | |
1173 | Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r | |
1174 | FPD file.\r | |
1175 | \r | |
1176 | @param moduleName The name of the module who use this PCD\r | |
1177 | @param token The token instance\r | |
1178 | @param datum The <datum> in module's PCD information\r | |
1179 | @param maxDatumSize The <maxDatumSize> in module's PCD information\r | |
1180 | \r | |
1181 | @return Token\r | |
1182 | */\r | |
1183 | private Token updateDynamicInformation(String moduleName, \r | |
1184 | Token token,\r | |
1185 | String datum,\r | |
1186 | int maxDatumSize) \r | |
1187 | throws EntityException {\r | |
1188 | int index = 0;\r | |
1189 | int offset;\r | |
1190 | String exceptionString = null;\r | |
1191 | DynamicTokenValue dynamicValue;\r | |
1192 | SkuInstance skuInstance = null;\r | |
1193 | String temp;\r | |
1194 | boolean hasSkuId0 = false;\r | |
38ee8d9e | 1195 | Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r |
51da9e80 | 1196 | long tokenNumber = 0;\r |
6c4dc226 | 1197 | String hiiDefaultValue = null;\r |
cd0170f5 | 1198 | String[] variableGuidString = null;\r |
6ff7a41c | 1199 | \r |
1200 | List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r | |
1201 | DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r | |
1202 | \r | |
1203 | dynamicInfo = getDynamicInfoFromFPD(token, moduleName);\r | |
1204 | if (dynamicInfo == null) {\r | |
7db4ab70 | 1205 | exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r |
6ff7a41c | 1206 | "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r |
1207 | "in FPD file, but it is required!",\r | |
1208 | token.cName,\r | |
1209 | moduleName);\r | |
1210 | throw new EntityException(exceptionString);\r | |
1211 | }\r | |
878ddf1f | 1212 | \r |
7db4ab70 | 1213 | token.datumSize = dynamicInfo.getMaxDatumSize();\r |
1214 | \r | |
6f7e61a0 | 1215 | exceptionString = verifyDatum(token.cName, \r |
1216 | moduleName,\r | |
1217 | null, \r | |
1218 | token.datumType, \r | |
1219 | token.datumSize);\r | |
7db4ab70 | 1220 | if (exceptionString != null) {\r |
1221 | throw new EntityException(exceptionString);\r | |
1222 | }\r | |
1223 | \r | |
1224 | if ((maxDatumSize != 0) && \r | |
1225 | (maxDatumSize != token.datumSize)) {\r | |
1226 | exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r | |
1227 | "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r | |
1228 | token.cName,\r | |
1229 | moduleName, \r | |
1230 | maxDatumSize,\r | |
1231 | dynamicInfo.getMaxDatumSize());\r | |
1232 | throw new EntityException(exceptionString);\r | |
1233 | }\r | |
51da9e80 | 1234 | tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r |
38ee8d9e | 1235 | if (tokenNumber != token.tokenNumber) {\r |
1236 | exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r | |
1237 | "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r | |
1238 | token.cName,\r | |
1239 | moduleName,\r | |
1240 | token.tokenNumber,\r | |
1241 | tokenNumber);\r | |
1242 | throw new EntityException(exceptionString);\r | |
1243 | }\r | |
1244 | \r | |
1245 | pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r | |
601f9e37 | 1246 | token.dynamicExTokenNumber = tokenNumber;\r |
7db4ab70 | 1247 | \r |
6ff7a41c | 1248 | skuInfoList = dynamicInfo.getSkuInfoList();\r |
878ddf1f | 1249 | \r |
6ff7a41c | 1250 | //\r |
1251 | // Loop all sku data \r | |
1252 | // \r | |
1253 | for (index = 0; index < skuInfoList.size(); index ++) {\r | |
1254 | skuInstance = new SkuInstance();\r | |
1255 | //\r | |
1256 | // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r | |
1257 | // \r | |
1258 | temp = skuInfoList.get(index).getSkuId().toString();\r | |
1259 | skuInstance.id = Integer.decode(temp);\r | |
6ff7a41c | 1260 | if (skuInstance.id == 0) {\r |
1261 | hasSkuId0 = true;\r | |
1262 | }\r | |
1263 | //\r | |
1264 | // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r | |
1265 | // \r | |
1266 | if (skuInfoList.get(index).getValue() != null) {\r | |
6c4dc226 | 1267 | skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r |
6f7e61a0 | 1268 | if ((exceptionString = verifyDatum(token.cName, \r |
1269 | null, \r | |
6c4dc226 | 1270 | skuInfoList.get(index).getValue().toString(), \r |
6f7e61a0 | 1271 | token.datumType, \r |
1272 | token.datumSize)) != null) {\r | |
1273 | throw new EntityException(exceptionString);\r | |
1274 | }\r | |
1275 | \r | |
6ff7a41c | 1276 | token.skuData.add(skuInstance);\r |
8840ad58 | 1277 | \r |
878ddf1f | 1278 | //\r |
6ff7a41c | 1279 | // Judege wether is same of datum between module's information\r |
1280 | // and dynamic information.\r | |
8840ad58 | 1281 | // \r |
6ff7a41c | 1282 | if (datum != null) {\r |
1283 | if ((skuInstance.id == 0) &&\r | |
6c4dc226 | 1284 | !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r |
6f7e61a0 | 1285 | exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r |
7db4ab70 | 1286 | "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r |
1287 | " or you could not define value for a dynamic PCD in every <ModuleSA>!"; \r | |
8840ad58 | 1288 | throw new EntityException(exceptionString);\r |
1289 | }\r | |
6ff7a41c | 1290 | }\r |
1291 | continue;\r | |
1292 | }\r | |
8840ad58 | 1293 | \r |
6ff7a41c | 1294 | //\r |
1295 | // Judge whether is HII group case.\r | |
1296 | // \r | |
1297 | if (skuInfoList.get(index).getVariableName() != null) {\r | |
1298 | exceptionString = null;\r | |
1299 | if (skuInfoList.get(index).getVariableGuid() == null) {\r | |
7db4ab70 | 1300 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r |
6ff7a41c | 1301 | "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r |
1302 | token.cName,\r | |
1303 | index);\r | |
cd0170f5 | 1304 | if (exceptionString != null) {\r |
1305 | throw new EntityException(exceptionString);\r | |
1306 | } \r | |
6ff7a41c | 1307 | }\r |
1308 | \r | |
1309 | if (skuInfoList.get(index).getVariableOffset() == null) {\r | |
7db4ab70 | 1310 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r |
6ff7a41c | 1311 | "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r |
1312 | token.cName,\r | |
1313 | index);\r | |
cd0170f5 | 1314 | if (exceptionString != null) {\r |
1315 | throw new EntityException(exceptionString);\r | |
1316 | }\r | |
6ff7a41c | 1317 | }\r |
1318 | \r | |
1319 | if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r | |
7db4ab70 | 1320 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r |
6ff7a41c | 1321 | "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r |
1322 | token.cName,\r | |
1323 | index);\r | |
cd0170f5 | 1324 | if (exceptionString != null) {\r |
1325 | throw new EntityException(exceptionString);\r | |
1326 | }\r | |
878ddf1f | 1327 | }\r |
6ff7a41c | 1328 | \r |
6c4dc226 | 1329 | if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r |
1330 | hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r | |
1331 | } else {\r | |
1332 | hiiDefaultValue = null;\r | |
1333 | }\r | |
6f7e61a0 | 1334 | \r |
1335 | if ((exceptionString = verifyDatum(token.cName, \r | |
1336 | null, \r | |
6c4dc226 | 1337 | hiiDefaultValue, \r |
6f7e61a0 | 1338 | token.datumType, \r |
1339 | token.datumSize)) != null) {\r | |
1340 | throw new EntityException(exceptionString);\r | |
1341 | }\r | |
1342 | \r | |
6ff7a41c | 1343 | offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r |
1344 | if (offset > 0xFFFF) {\r | |
7db4ab70 | 1345 | throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r |
6ff7a41c | 1346 | "exceed 64K, it is not allowed!",\r |
1347 | token.cName,\r | |
1348 | index));\r | |
1349 | }\r | |
1350 | \r | |
cd0170f5 | 1351 | //\r |
1352 | // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r | |
1353 | // \r | |
136adffc | 1354 | variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r |
cd0170f5 | 1355 | if (variableGuidString == null) {\r |
1356 | throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r | |
1357 | token.cName, \r | |
1358 | skuInfoList.get(index).getVariableGuid().toString()));\r | |
1359 | }\r | |
136adffc | 1360 | String variableStr = skuInfoList.get(index).getVariableName();\r |
1361 | Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r | |
1362 | Matcher matcher = pattern.matcher(variableStr);\r | |
1363 | List<String> varNameList = new ArrayList<String>();\r | |
1364 | while (matcher.find()){\r | |
1365 | String str = variableStr.substring(matcher.start(),matcher.end());\r | |
1366 | varNameList.add(str);\r | |
1367 | }\r | |
1368 | \r | |
1369 | skuInstance.value.setHiiData(varNameList,\r | |
cd0170f5 | 1370 | translateSchemaStringToUUID(variableGuidString[1]),\r |
6ff7a41c | 1371 | skuInfoList.get(index).getVariableOffset(),\r |
6c4dc226 | 1372 | skuInfoList.get(index).getHiiDefaultValue().toString());\r |
6ff7a41c | 1373 | token.skuData.add(skuInstance);\r |
1374 | continue;\r | |
878ddf1f | 1375 | }\r |
6ff7a41c | 1376 | \r |
1377 | if (skuInfoList.get(index).getVpdOffset() != null) {\r | |
1378 | skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r | |
1379 | token.skuData.add(skuInstance);\r | |
1380 | continue;\r | |
1381 | }\r | |
1382 | \r | |
7db4ab70 | 1383 | exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r |
6ff7a41c | 1384 | "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r |
1385 | token.cName);\r | |
8840ad58 | 1386 | throw new EntityException(exceptionString);\r |
1387 | }\r | |
1388 | \r | |
6ff7a41c | 1389 | if (!hasSkuId0) {\r |
7db4ab70 | 1390 | exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r |
6ff7a41c | 1391 | "no sku id = 0 data, which is required for every dynamic PCD",\r |
1392 | token.cName);\r | |
7db4ab70 | 1393 | throw new EntityException(exceptionString);\r |
6ff7a41c | 1394 | }\r |
1395 | \r | |
8840ad58 | 1396 | return token;\r |
1397 | }\r | |
1398 | \r | |
1399 | /**\r | |
1400 | Translate the schema string to UUID instance.\r | |
1401 | \r | |
1402 | In schema, the string of UUID is defined as following two types string:\r | |
1403 | 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r | |
1404 | )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r | |
1405 | \r | |
1406 | 2) GuidNamingConvention: pattern =\r | |
1407 | [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r | |
1408 | \r | |
1409 | This function will convert string and create uuid instance.\r | |
1410 | \r | |
1411 | @param uuidString UUID string in XML file\r | |
1412 | \r | |
1413 | @return UUID UUID instance\r | |
1414 | **/\r | |
1415 | private UUID translateSchemaStringToUUID(String uuidString) \r | |
1416 | throws EntityException {\r | |
1417 | String temp;\r | |
1418 | String[] splitStringArray;\r | |
1419 | int index;\r | |
1420 | int chIndex;\r | |
1421 | int chLen;\r | |
1422 | \r | |
1423 | if (uuidString == null) {\r | |
1424 | return null;\r | |
1425 | }\r | |
1426 | \r | |
1427 | if (uuidString.length() == 0) {\r | |
1428 | return null;\r | |
1429 | }\r | |
1430 | \r | |
6ff7a41c | 1431 | if (uuidString.equals("0") ||\r |
1432 | uuidString.equalsIgnoreCase("0x0")) {\r | |
1433 | return new UUID(0, 0);\r | |
1434 | }\r | |
1435 | \r | |
cd0170f5 | 1436 | uuidString = uuidString.replaceAll("\\{", "");\r |
1437 | uuidString = uuidString.replaceAll("\\}", "");\r | |
1438 | \r | |
8840ad58 | 1439 | //\r |
1440 | // If the UUID schema string is GuidArrayType type then need translate \r | |
1441 | // to GuidNamingConvention type at first.\r | |
1442 | // \r | |
1443 | if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r | |
1444 | splitStringArray = uuidString.split("," );\r | |
1445 | if (splitStringArray.length != 11) {\r | |
7db4ab70 | 1446 | throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r |
8840ad58 | 1447 | }\r |
1448 | \r | |
1449 | //\r | |
1450 | // Remove blank space from these string and remove header string "0x"\r | |
1451 | // \r | |
1452 | for (index = 0; index < 11; index ++) {\r | |
1453 | splitStringArray[index] = splitStringArray[index].trim();\r | |
1454 | splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r | |
1455 | }\r | |
1456 | \r | |
1457 | //\r | |
1458 | // Add heading '0' to normalize the string length\r | |
1459 | // \r | |
1460 | for (index = 3; index < 11; index ++) {\r | |
1461 | chLen = splitStringArray[index].length();\r | |
1462 | for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r | |
1463 | splitStringArray[index] = "0" + splitStringArray[index];\r | |
1464 | }\r | |
1465 | }\r | |
1466 | \r | |
1467 | //\r | |
1468 | // construct the final GuidNamingConvention string\r | |
1469 | // \r | |
1470 | temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r | |
1471 | splitStringArray[0],\r | |
1472 | splitStringArray[1],\r | |
1473 | splitStringArray[2],\r | |
1474 | splitStringArray[3],\r | |
1475 | splitStringArray[4],\r | |
1476 | splitStringArray[5],\r | |
1477 | splitStringArray[6],\r | |
1478 | splitStringArray[7],\r | |
1479 | splitStringArray[8],\r | |
1480 | splitStringArray[9],\r | |
1481 | splitStringArray[10]);\r | |
1482 | uuidString = temp;\r | |
1483 | }\r | |
1484 | \r | |
1485 | return UUID.fromString(uuidString);\r | |
878ddf1f | 1486 | }\r |
1487 | \r | |
1488 | /**\r | |
1489 | check parameter for this action.\r | |
1490 | \r | |
1491 | @throws EntityException Bad parameter.\r | |
1492 | **/\r | |
1493 | private void checkParameter() throws EntityException {\r | |
1494 | File file = null;\r | |
1495 | \r | |
1496 | if((fpdFilePath == null) ||(workspacePath == null)) {\r | |
1497 | throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r | |
1498 | }\r | |
1499 | \r | |
1500 | if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r | |
1501 | throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r | |
1502 | }\r | |
1503 | \r | |
1504 | file = new File(workspacePath);\r | |
1505 | if(!file.exists()) {\r | |
1506 | throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r | |
1507 | }\r | |
1508 | \r | |
1509 | file = new File(fpdFilePath);\r | |
1510 | \r | |
1511 | if(!file.exists()) {\r | |
1512 | throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r | |
1513 | }\r | |
1514 | }\r | |
1515 | \r | |
1516 | /**\r | |
1517 | Test case function\r | |
1518 | \r | |
1519 | @param argv parameter from command line\r | |
1520 | **/\r | |
1521 | public static void main(String argv[]) throws EntityException {\r | |
1522 | CollectPCDAction ca = new CollectPCDAction();\r | |
1de04b4f | 1523 | String projectDir = "x:/edk2";\r |
1524 | ca.setWorkspacePath(projectDir);\r | |
1525 | ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r | |
878ddf1f | 1526 | ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r |
7629edbc | 1527 | GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r |
1de04b4f | 1528 | projectDir,\r |
7629edbc | 1529 | "tools_def.txt");\r |
1de04b4f | 1530 | System.out.println("After initInfo!");\r |
7629edbc | 1531 | FpdParserTask fpt = new FpdParserTask();\r |
1de04b4f | 1532 | fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r |
7629edbc | 1533 | ca.execute();\r |
878ddf1f | 1534 | }\r |
1535 | }\r |