]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
Add in support for MaxSize and CurrentSize for PCD entry.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
CommitLineData
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
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13 \r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18package org.tianocore.build.pcd.action;\r
19\r
6ff7a41c 20import java.io.BufferedReader; \r
878ddf1f 21import java.io.File;\r
99d2c3c4 22import java.io.FileReader;\r
878ddf1f 23import java.io.IOException;\r
6f7e61a0 24import java.math.BigInteger;\r
878ddf1f 25import java.util.ArrayList;\r
99d2c3c4 26import java.util.Comparator;\r
878ddf1f 27import java.util.HashMap;\r
136adffc 28import java.util.Iterator;\r
878ddf1f 29import java.util.List;\r
136adffc 30import java.util.Map;\r
31import java.util.Set;\r
878ddf1f 32import java.util.UUID;\r
136adffc 33import java.util.regex.Matcher;\r
34import java.util.regex.Pattern;\r
878ddf1f 35\r
36import org.apache.xmlbeans.XmlException;\r
37import org.apache.xmlbeans.XmlObject;\r
6ff7a41c 38import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
8840ad58 39import org.tianocore.FrameworkModulesDocument;\r
878ddf1f 40import org.tianocore.ModuleSADocument;\r
8d82d611 41import org.tianocore.PcdBuildDefinitionDocument;\r
6ff7a41c 42import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
8d82d611 43import org.tianocore.PlatformSurfaceAreaDocument;\r
136adffc 44import org.tianocore.build.autogen.CommonDefinition;\r
7629edbc 45import org.tianocore.build.fpd.FpdParserTask;\r
878ddf1f 46import org.tianocore.build.global.GlobalData;\r
136adffc 47import org.tianocore.build.id.FpdModuleIdentification;\r
878ddf1f 48import org.tianocore.build.pcd.action.ActionMessage;\r
6ff7a41c 49import org.tianocore.build.pcd.entity.DynamicTokenValue;\r
878ddf1f 50import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
51import org.tianocore.build.pcd.entity.SkuInstance;\r
52import org.tianocore.build.pcd.entity.Token;\r
53import org.tianocore.build.pcd.entity.UsageInstance;\r
54import org.tianocore.build.pcd.exception.EntityException;\r
1eb73ab5 55\r
56/**\r
57 CStructTypeDeclaration \r
58 \r
59 This class is used to store the declaration string, such as\r
60 "UINT32 PcdPlatformFlashBaseAddress", of \r
61 each memember in the C structure, which is a standard C language\r
62 feature used to implement a simple and efficient database for\r
63 dynamic(ex) type PCD entry.\r
64**/\r
878ddf1f 65\r
58f1099f 66class CStructTypeDeclaration {\r
67 String key;\r
68 int alignmentSize;\r
69 String cCode;\r
70 boolean initTable;\r
71 \r
72 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {\r
73 this.key = key;\r
74 this.alignmentSize = alignmentSize;\r
75 this.cCode = cCode;\r
76 this.initTable = initTable;\r
77 }\r
78}\r
79\r
1eb73ab5 80/**\r
81 StringTable \r
82 \r
83 This class is used to store the String in a PCD database.\r
84 \r
85**/\r
99d2c3c4 86class StringTable {\r
87 private ArrayList<String> al; \r
32648c62 88 private ArrayList<String> alComments;\r
99d2c3c4 89 private String phase;\r
90 int len; \r
99d2c3c4 91\r
92 public StringTable (String phase) {\r
93 this.phase = phase;\r
94 al = new ArrayList<String>();\r
32648c62 95 alComments = new ArrayList<String>();\r
99d2c3c4 96 len = 0;\r
99d2c3c4 97 }\r
98\r
99 public String getSizeMacro () {\r
100 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());\r
101 }\r
102\r
103 private int getSize () {\r
32648c62 104 //\r
105 // We have at least one Unicode Character in the table.\r
106 //\r
99d2c3c4 107 return len == 0 ? 1 : len;\r
108 }\r
109\r
99d2c3c4 110 public String getExistanceMacro () {\r
111 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
112 }\r
58f1099f 113 \r
1eb73ab5 114 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {\r
58f1099f 115 final String stringTable = "StringTable";\r
116 final String tab = "\t";\r
117 final String newLine = "\r\n";\r
118 final String commaNewLine = ",\r\n";\r
119 \r
120 CStructTypeDeclaration decl;\r
121\r
122 String cDeclCode = "";\r
123 String cInstCode = "";\r
124\r
125 //\r
126 // If we have a empty StringTable\r
127 //\r
128 if (al.size() == 0) {\r
3534cbb7 129 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine; \r
58f1099f 130 decl = new CStructTypeDeclaration (\r
131 stringTable,\r
132 2,\r
133 cDeclCode,\r
134 true\r
135 ); \r
136 declaList.add(decl);\r
137\r
3534cbb7 138 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";\r
58f1099f 139 instTable.put(stringTable, cInstCode);\r
140 } else {\r
141\r
142 //\r
143 // If there is any String in the StringTable\r
144 //\r
145 for (int i = 0; i < al.size(); i++) {\r
146 String str = al.get(i);\r
147 String stringTableName;\r
148 \r
149 if (i == 0) {\r
150 //\r
151 // StringTable is a well-known name in the PCD DXE driver\r
152 //\r
153 stringTableName = stringTable;\r
154 \r
155 } else {\r
156 stringTableName = String.format("%s_%d", stringTable, i);\r
157 cDeclCode += tab;\r
158 }\r
1eb73ab5 159 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", \r
160 stringTableName, str.length() + 1, \r
161 alComments.get(i)) \r
162 + newLine;\r
58f1099f 163 \r
164 if (i == 0) {\r
165 cInstCode = "/* StringTable */" + newLine;\r
166 }\r
1eb73ab5 167 \r
58f1099f 168 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));\r
169 if (i != al.size() - 1) {\r
170 cInstCode += commaNewLine;\r
171 }\r
172 }\r
173 \r
174 decl = new CStructTypeDeclaration (\r
175 stringTable,\r
176 2,\r
177 cDeclCode,\r
178 true\r
179 ); \r
180 declaList.add(decl);\r
181 \r
182 instTable.put(stringTable, cInstCode);\r
183 }\r
184 }\r
99d2c3c4 185\r
58f1099f 186 public int add (String inputStr, Token token) {\r
99d2c3c4 187 int i;\r
58f1099f 188 int pos;\r
99d2c3c4 189\r
58f1099f 190 String str = inputStr;\r
191 \r
192 //\r
193 // The input can be two types:\r
194 // "L\"Bootmode\"" or "Bootmode". \r
195 // We drop the L\" and \" for the first type. \r
196 if (str.startsWith("L\"") && str.endsWith("\"")) {\r
197 str = str.substring(2, str.length() - 1);\r
198 }\r
199 //\r
200 // Check if StringTable has this String already.\r
201 // If so, return the current pos.\r
202 //\r
203 for (i = 0, pos = 0; i < al.size(); i++) {\r
204 String s = al.get(i);;\r
205\r
206 if (str.equals(s)) {\r
207 return pos;\r
208 }\r
209 pos = s.length() + 1;\r
58f1099f 210 }\r
211 \r
99d2c3c4 212 i = len;\r
213 //\r
214 // Include the NULL character at the end of String\r
215 //\r
216 len += str.length() + 1; \r
217 al.add(str);\r
32648c62 218 alComments.add(token.getPrimaryKeyString());\r
99d2c3c4 219\r
220 return i;\r
221 }\r
222}\r
223\r
1eb73ab5 224/**\r
225 SizeTable \r
226 \r
227 This class is used to store the Size information for\r
228 POINTER TYPE PCD entry in a PCD database.\r
229\r
230**/\r
99d2c3c4 231class SizeTable {\r
1de04b4f 232 private ArrayList<ArrayList<Integer>> al;\r
32648c62 233 private ArrayList<String> alComments;\r
99d2c3c4 234 private int len;\r
1de04b4f 235 private String phase;\r
58f1099f 236 \r
99d2c3c4 237 public SizeTable (String phase) {\r
1de04b4f 238 al = new ArrayList<ArrayList<Integer>>();\r
32648c62 239 alComments = new ArrayList<String>();\r
99d2c3c4 240 len = 0;\r
1de04b4f 241 this.phase = phase;\r
242 }\r
243\r
244 public String getSizeMacro () {\r
245 return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());\r
246 }\r
247 \r
248 private int getSize() {\r
249 return len == 0 ? 1 : len;\r
58f1099f 250 }\r
251\r
1eb73ab5 252 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
58f1099f 253 final String name = "SizeTable";\r
254 \r
255 CStructTypeDeclaration decl;\r
256 String cCode;\r
257\r
258 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase); \r
259 decl = new CStructTypeDeclaration (\r
260 name,\r
261 2,\r
262 cCode,\r
263 true\r
264 ); \r
265 declaList.add(decl);\r
266\r
267\r
268 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
269 instTable.put(name, cCode);\r
99d2c3c4 270 }\r
271\r
1eb73ab5 272 private ArrayList<String> getInstantiation () {\r
1de04b4f 273 final String comma = ",";\r
32648c62 274 ArrayList<String> Output = new ArrayList<String>();\r
99d2c3c4 275\r
276 Output.add("/* SizeTable */");\r
277 Output.add("{");\r
32648c62 278 if (al.size() == 0) {\r
3534cbb7 279 Output.add("\t0");\r
32648c62 280 } else {\r
281 for (int index = 0; index < al.size(); index++) {\r
1de04b4f 282 ArrayList<Integer> ial = al.get(index);\r
283 \r
284 String str = "\t";\r
285 \r
286 for (int index2 = 0; index2 < ial.size(); index2++) {\r
287 str += " " + ial.get(index2).toString();\r
288 if (index2 != ial.size() - 1) {\r
289 str += comma;\r
290 }\r
291 }\r
32648c62 292\r
1de04b4f 293 str += " /* " + alComments.get(index) + " */"; \r
294 \r
32648c62 295 if (index != (al.size() - 1)) {\r
1de04b4f 296 str += comma;\r
32648c62 297 }\r
298\r
32648c62 299 Output.add(str);\r
32648c62 300 \r
301 }\r
302 }\r
303 Output.add("}");\r
99d2c3c4 304\r
305 return Output;\r
306 }\r
307\r
1de04b4f 308 public void add (Token token) {\r
99d2c3c4 309\r
1de04b4f 310 //\r
311 // We only have size information for POINTER type PCD entry.\r
312 //\r
313 if (token.datumType != Token.DATUM_TYPE.POINTER) {\r
314 return;\r
315 }\r
316 \r
317 ArrayList<Integer> ial = token.getPointerTypeSize();\r
318 \r
319 len+= ial.size(); \r
320\r
321 al.add(ial);\r
32648c62 322 alComments.add(token.getPrimaryKeyString());\r
99d2c3c4 323\r
1de04b4f 324 return;\r
99d2c3c4 325 }\r
4acf8ce7 326 \r
99d2c3c4 327}\r
328\r
1eb73ab5 329/**\r
330 GuidTable \r
331 \r
332 This class is used to store the GUIDs in a PCD database.\r
333**/\r
99d2c3c4 334class GuidTable {\r
335 private ArrayList<UUID> al;\r
32648c62 336 private ArrayList<String> alComments;\r
99d2c3c4 337 private String phase;\r
338 private int len;\r
32648c62 339 private int bodyLineNum;\r
99d2c3c4 340\r
341 public GuidTable (String phase) {\r
342 this.phase = phase;\r
343 al = new ArrayList<UUID>();\r
32648c62 344 alComments = new ArrayList<String>();\r
99d2c3c4 345 len = 0;\r
32648c62 346 bodyLineNum = 0;\r
99d2c3c4 347 }\r
348\r
349 public String getSizeMacro () {\r
350 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());\r
351 }\r
352\r
353 private int getSize () {\r
354 return (al.size() == 0)? 1 : al.size();\r
355 }\r
356\r
357 public String getExistanceMacro () {\r
358 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
359 }\r
360\r
1eb73ab5 361 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
58f1099f 362 final String name = "GuidTable";\r
363 \r
364 CStructTypeDeclaration decl;\r
365 String cCode = "";\r
366\r
367 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase); \r
368 decl = new CStructTypeDeclaration (\r
369 name,\r
1de04b4f 370 4,\r
58f1099f 371 cCode,\r
372 true\r
373 ); \r
374 declaList.add(decl);\r
375\r
376\r
377 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
378 instTable.put(name, cCode);\r
379 }\r
380\r
32648c62 381 private String getUuidCString (UUID uuid) {\r
382 String[] guidStrArray;\r
383\r
384 guidStrArray =(uuid.toString()).split("-");\r
385\r
3534cbb7 386 return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",\r
32648c62 387 guidStrArray[0],\r
388 guidStrArray[1],\r
389 guidStrArray[2],\r
390 (guidStrArray[3].substring(0, 2)),\r
391 (guidStrArray[3].substring(2, 4)),\r
392 (guidStrArray[4].substring(0, 2)),\r
393 (guidStrArray[4].substring(2, 4)),\r
394 (guidStrArray[4].substring(4, 6)),\r
395 (guidStrArray[4].substring(6, 8)),\r
396 (guidStrArray[4].substring(8, 10)),\r
397 (guidStrArray[4].substring(10, 12))\r
398 );\r
399 }\r
99d2c3c4 400\r
1eb73ab5 401 private ArrayList<String> getInstantiation () {\r
32648c62 402 ArrayList<String> Output = new ArrayList<String>();\r
99d2c3c4 403\r
404 Output.add("/* GuidTable */");\r
405 Output.add("{");\r
136adffc 406\r
32648c62 407 if (al.size() == 0) {\r
3534cbb7 408 Output.add("\t" + getUuidCString(new UUID(0, 0)));\r
32648c62 409 }\r
99d2c3c4 410 \r
58f1099f 411 for (int i = 0; i < al.size(); i++) {\r
412 String str = "\t" + getUuidCString(al.get(i));\r
99d2c3c4 413\r
58f1099f 414 str += "/* " + alComments.get(i) + " */";\r
415 if (i != (al.size() - 1)) {\r
32648c62 416 str += ",";\r
417 }\r
99d2c3c4 418 Output.add(str);\r
32648c62 419 bodyLineNum++;\r
99d2c3c4 420\r
421 }\r
32648c62 422 Output.add("}");\r
99d2c3c4 423\r
424 return Output;\r
425 }\r
426\r
99d2c3c4 427 public int add (UUID uuid, String name) {\r
99d2c3c4 428 //\r
58f1099f 429 // Check if GuidTable has this entry already.\r
430 // If so, return the GuidTable index.\r
99d2c3c4 431 //\r
58f1099f 432 for (int i = 0; i < al.size(); i++) {\r
433 if (al.get(i).equals(uuid)) {\r
434 return i;\r
435 }\r
436 }\r
437 \r
99d2c3c4 438 len++; \r
439 al.add(uuid);\r
58f1099f 440 alComments.add(name);\r
99d2c3c4 441\r
58f1099f 442 //\r
443 // Return the previous Table Index\r
444 //\r
445 return len - 1;\r
99d2c3c4 446 }\r
447\r
99d2c3c4 448}\r
449\r
1eb73ab5 450/**\r
451 SkuIdTable \r
452 \r
453 This class is used to store the SKU IDs in a PCD database.\r
454\r
455**/\r
99d2c3c4 456class SkuIdTable {\r
457 private ArrayList<Integer[]> al;\r
32648c62 458 private ArrayList<String> alComment;\r
99d2c3c4 459 private String phase;\r
460 private int len;\r
99d2c3c4 461\r
462 public SkuIdTable (String phase) {\r
463 this.phase = phase;\r
464 al = new ArrayList<Integer[]>();\r
32648c62 465 alComment = new ArrayList<String>();\r
99d2c3c4 466 len = 0;\r
467 }\r
468\r
469 public String getSizeMacro () {\r
470 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());\r
471 }\r
472\r
473 private int getSize () {\r
58f1099f 474 return (len == 0)? 1 : len;\r
99d2c3c4 475 }\r
476\r
477 public String getExistanceMacro () {\r
478 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
479 }\r
480\r
1eb73ab5 481 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
58f1099f 482 final String name = "SkuIdTable";\r
483 \r
484 CStructTypeDeclaration decl;\r
485 String cCode = "";\r
486\r
487 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase); \r
488 decl = new CStructTypeDeclaration (\r
489 name,\r
490 1,\r
491 cCode,\r
492 true\r
493 ); \r
494 declaList.add(decl);\r
495\r
496\r
497 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
498 instTable.put(name, cCode);\r
499\r
500 //\r
501 // SystemSkuId is in PEI phase PCD Database\r
502 //\r
503 if (phase.equalsIgnoreCase("PEI")) {\r
504 decl = new CStructTypeDeclaration (\r
505 "SystemSkuId",\r
506 1,\r
3534cbb7 507 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),\r
58f1099f 508 true\r
509 );\r
510 declaList.add(decl);\r
511 \r
512 instTable.put("SystemSkuId", "0");\r
513 }\r
514\r
515 }\r
516\r
1eb73ab5 517 private ArrayList<String> getInstantiation () {\r
32648c62 518 ArrayList<String> Output = new ArrayList<String> ();\r
99d2c3c4 519\r
520 Output.add("/* SkuIdTable */");\r
521 Output.add("{");\r
99d2c3c4 522\r
32648c62 523 if (al.size() == 0) {\r
58f1099f 524 Output.add("\t0");\r
32648c62 525 }\r
99d2c3c4 526 \r
527 for (int index = 0; index < al.size(); index++) {\r
32648c62 528 String str;\r
99d2c3c4 529\r
32648c62 530 str = "/* " + alComment.get(index) + "*/ ";\r
531 str += "/* MaxSku */ ";\r
99d2c3c4 532\r
533\r
32648c62 534 Integer[] ia = al.get(index);\r
99d2c3c4 535\r
58f1099f 536 str += "\t" + ia[0].toString() + ", ";\r
32648c62 537 for (int index2 = 1; index2 < ia.length; index2++) {\r
538 str += ia[index2].toString();\r
58f1099f 539 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {\r
32648c62 540 str += ", ";\r
541 }\r
542 }\r
99d2c3c4 543\r
544 Output.add(str);\r
99d2c3c4 545\r
546 }\r
547\r
32648c62 548 Output.add("}");\r
99d2c3c4 549\r
550 return Output;\r
551 }\r
552\r
553 public int add (Token token) {\r
554\r
32648c62 555 int index;\r
58f1099f 556 int pos;\r
557 \r
558 //\r
559 // Check if this SKU_ID Array is already in the table\r
560 //\r
561 pos = 0;\r
562 for (Object o: al) {\r
563 Integer [] s = (Integer[]) o;\r
564 boolean different = false;\r
565 if (s[0] == token.getSkuIdCount()) {\r
566 for (index = 1; index < s.length; index++) {\r
567 if (s[index] != token.skuData.get(index-1).id) {\r
568 different = true;\r
569 break;\r
570 }\r
571 }\r
572 } else {\r
573 different = true;\r
574 }\r
575 if (different) {\r
576 pos += s[0] + 1;\r
577 } else {\r
578 return pos;\r
579 }\r
580 }\r
99d2c3c4 581\r
6ff7a41c 582 Integer [] skuIds = new Integer[token.skuData.size() + 1];\r
583 skuIds[0] = new Integer(token.skuData.size());\r
32648c62 584 for (index = 1; index < skuIds.length; index++) {\r
585 skuIds[index] = new Integer(token.skuData.get(index - 1).id);\r
586 }\r
99d2c3c4 587\r
588 index = len;\r
589\r
590 len += skuIds.length; \r
591 al.add(skuIds);\r
32648c62 592 alComment.add(token.getPrimaryKeyString());\r
99d2c3c4 593\r
594 return index;\r
595 }\r
596\r
99d2c3c4 597}\r
598\r
599class LocalTokenNumberTable {\r
600 private ArrayList<String> al;\r
32648c62 601 private ArrayList<String> alComment;\r
99d2c3c4 602 private String phase;\r
603 private int len;\r
99d2c3c4 604\r
605 public LocalTokenNumberTable (String phase) {\r
606 this.phase = phase;\r
607 al = new ArrayList<String>();\r
32648c62 608 alComment = new ArrayList<String>();\r
99d2c3c4 609\r
610 len = 0;\r
611 }\r
612\r
613 public String getSizeMacro () {\r
3496595d 614 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())\r
615 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());\r
99d2c3c4 616 }\r
617\r
618 public int getSize () {\r
619 return (al.size() == 0)? 1 : al.size();\r
620 }\r
621\r
622 public String getExistanceMacro () {\r
623 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
624 }\r
625\r
1eb73ab5 626 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
58f1099f 627 final String name = "LocalTokenNumberTable";\r
628 \r
629 CStructTypeDeclaration decl;\r
630 String cCode = "";\r
631\r
632 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase); \r
633 decl = new CStructTypeDeclaration (\r
634 name,\r
635 4,\r
636 cCode,\r
637 true\r
638 ); \r
639 declaList.add(decl);\r
640\r
641 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
642 instTable.put(name, cCode);\r
643 }\r
644\r
1eb73ab5 645 private ArrayList<String> getInstantiation () {\r
32648c62 646 ArrayList<String> output = new ArrayList<String>();\r
99d2c3c4 647\r
648 output.add("/* LocalTokenNumberTable */");\r
649 output.add("{");\r
99d2c3c4 650\r
32648c62 651 if (al.size() == 0) {\r
3534cbb7 652 output.add("\t0");\r
32648c62 653 }\r
99d2c3c4 654 \r
655 for (int index = 0; index < al.size(); index++) {\r
32648c62 656 String str;\r
99d2c3c4 657\r
58f1099f 658 str = "\t" + (String)al.get(index);\r
99d2c3c4 659\r
32648c62 660 str += " /* " + alComment.get(index) + " */ ";\r
99d2c3c4 661\r
662\r
32648c62 663 if (index != (al.size() - 1)) {\r
664 str += ",";\r
665 }\r
99d2c3c4 666\r
667 output.add(str);\r
668\r
669 }\r
670\r
32648c62 671 output.add("}");\r
99d2c3c4 672\r
673 return output;\r
674 }\r
675\r
676 public int add (Token token) {\r
677 int index = len;\r
32648c62 678 String str;\r
99d2c3c4 679\r
680 len++; \r
681\r
32648c62 682 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());\r
99d2c3c4 683\r
f63ef4b2 684 if (token.isUnicodeStringType()) {\r
32648c62 685 str += " | PCD_TYPE_STRING";\r
686 }\r
99d2c3c4 687\r
6ff7a41c 688 if (token.isSkuEnable()) {\r
32648c62 689 str += " | PCD_TYPE_SKU_ENABLED";\r
690 }\r
99d2c3c4 691\r
6ff7a41c 692 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
32648c62 693 str += " | PCD_TYPE_HII";\r
694 }\r
99d2c3c4 695\r
6ff7a41c 696 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
32648c62 697 str += " | PCD_TYPE_VPD";\r
698 }\r
699 \r
1de04b4f 700 switch (token.datumType) {\r
701 case UINT8:\r
702 case BOOLEAN:\r
703 str += " | PCD_DATUM_TYPE_UINT8";\r
704 break;\r
705 case UINT16:\r
706 str += " | PCD_DATUM_TYPE_UINT16";\r
707 break;\r
708 case UINT32:\r
709 str += " | PCD_DATUM_TYPE_UINT32";\r
710 break;\r
711 case UINT64:\r
712 str += " | PCD_DATUM_TYPE_UINT64";\r
713 break;\r
714 case POINTER:\r
715 str += " | PCD_DATUM_TYPE_POINTER";\r
716 break;\r
717 }\r
718 \r
99d2c3c4 719 al.add(str);\r
32648c62 720 alComment.add(token.getPrimaryKeyString());\r
99d2c3c4 721\r
722 return index;\r
723 }\r
724}\r
725\r
1eb73ab5 726/**\r
727 ExMapTable \r
728 \r
729 This class is used to store the table of mapping information\r
730 between DynamicEX ID pair(Guid, TokenNumber) and\r
731 the local token number assigned by PcdDatabase class.\r
732**/\r
99d2c3c4 733class ExMapTable {\r
734\r
1eb73ab5 735 /**\r
736 ExTriplet \r
737 \r
738 This class is used to store the mapping information\r
739 between DynamicEX ID pair(Guid, TokenNumber) and\r
740 the local token number assigned by PcdDatabase class.\r
741 **/\r
32648c62 742 class ExTriplet {\r
743 public Integer guidTableIdx;\r
744 public Long exTokenNumber;\r
745 public Long localTokenIdx;\r
746 \r
747 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {\r
748 this.guidTableIdx = new Integer(guidTableIdx);\r
749 this.exTokenNumber = new Long(exTokenNumber);\r
750 this.localTokenIdx = new Long(localTokenIdx);\r
751 }\r
752 }\r
99d2c3c4 753\r
754 private ArrayList<ExTriplet> al;\r
32648c62 755 private ArrayList<String> alComment;\r
99d2c3c4 756 private String phase;\r
757 private int len;\r
32648c62 758 private int bodyLineNum;\r
58f1099f 759 \r
99d2c3c4 760 public ExMapTable (String phase) {\r
761 this.phase = phase;\r
762 al = new ArrayList<ExTriplet>();\r
32648c62 763 alComment = new ArrayList<String>();\r
32648c62 764 bodyLineNum = 0;\r
99d2c3c4 765 len = 0;\r
766 }\r
767\r
768 public String getSizeMacro () {\r
769 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())\r
32648c62 770 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());\r
99d2c3c4 771 }\r
772\r
99d2c3c4 773 public String getExistanceMacro () {\r
774 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
775 }\r
776\r
1eb73ab5 777 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
58f1099f 778 final String exMapTableName = "ExMapTable";\r
779 \r
780 sortTable();\r
781 \r
782 CStructTypeDeclaration decl;\r
783 String cCode = "";\r
784\r
785 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase); \r
786 decl = new CStructTypeDeclaration (\r
787 exMapTableName,\r
788 4,\r
789 cCode,\r
790 true\r
791 ); \r
792 declaList.add(decl);\r
793\r
794\r
795 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
796 instTable.put(exMapTableName, cCode);\r
797 }\r
798 \r
1eb73ab5 799 private ArrayList<String> getInstantiation () {\r
32648c62 800 ArrayList<String> Output = new ArrayList<String>();\r
99d2c3c4 801\r
802 Output.add("/* ExMapTable */");\r
803 Output.add("{");\r
32648c62 804 if (al.size() == 0) {\r
58f1099f 805 Output.add("\t{0, 0, 0}");\r
32648c62 806 }\r
99d2c3c4 807 \r
32648c62 808 int index;\r
99d2c3c4 809 for (index = 0; index < al.size(); index++) {\r
32648c62 810 String str;\r
99d2c3c4 811\r
32648c62 812 ExTriplet e = (ExTriplet)al.get(index);\r
99d2c3c4 813\r
58f1099f 814 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";\r
32648c62 815 str += e.localTokenIdx.toString() + ", ";\r
816 str += e.guidTableIdx.toString();\r
99d2c3c4 817\r
58f1099f 818 str += "}" + " /* " + alComment.get(index) + " */" ;\r
99d2c3c4 819\r
32648c62 820 if (index != al.size() - 1) {\r
821 str += ",";\r
822 }\r
99d2c3c4 823\r
824 Output.add(str);\r
32648c62 825 bodyLineNum++;\r
99d2c3c4 826\r
827 }\r
828\r
32648c62 829 Output.add("}");\r
99d2c3c4 830\r
831 return Output;\r
832 }\r
833\r
834 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {\r
835 int index = len;\r
836\r
837 len++; \r
838 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));\r
32648c62 839 alComment.add(name);\r
99d2c3c4 840\r
841 return index;\r
842 }\r
843\r
1eb73ab5 844 private int getTableLen () {\r
32648c62 845 return al.size() == 0 ? 1 : al.size();\r
846 }\r
99d2c3c4 847\r
58f1099f 848 //\r
849 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in\r
850 // PCD PEIM/Driver, we need to sort the ExMapTable according to the\r
851 // following order:\r
852 // 1) ExGuid\r
853 // 2) ExTokenNumber\r
854 // \r
855 class ExTripletComp implements Comparator<ExTriplet> {\r
856 public int compare (ExTriplet a, ExTriplet b) {\r
857 if (a.guidTableIdx == b.guidTableIdx ) {\r
1eb73ab5 858 //\r
859 // exTokenNumber is long, we can't use simple substraction.\r
860 //\r
58f1099f 861 if (a.exTokenNumber > b.exTokenNumber) {\r
862 return 1;\r
1eb73ab5 863 } else if (a.exTokenNumber == b.exTokenNumber) {\r
58f1099f 864 return 0;\r
1eb73ab5 865 } else {\r
866 return -1;\r
58f1099f 867 }\r
868 }\r
869 \r
870 return a.guidTableIdx - b.guidTableIdx;\r
871 }\r
872 }\r
873\r
874 private void sortTable () {\r
875 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();\r
876 java.util.Collections.sort(al, comparator);\r
877 }\r
99d2c3c4 878}\r
879\r
1eb73ab5 880/**\r
881 PcdDatabase \r
882 \r
883 This class is used to generate C code for Autogen.h and Autogen.c of\r
884 a PCD service DXE driver and PCD service PEIM.\r
885**/\r
99d2c3c4 886class PcdDatabase {\r
887\r
58f1099f 888 private final static int SkuHeadAlignmentSize = 4;\r
889 private final String newLine = "\r\n";\r
890 private final String commaNewLine = ",\r\n";\r
891 private final String tab = "\t";\r
3534cbb7 892 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
893 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
894 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
895 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
1de04b4f 896 public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";\r
3534cbb7 897 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
99d2c3c4 898\r
899\r
900 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";\r
32648c62 901 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";\r
58f1099f 902 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n"; \r
3496595d 903 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";\r
904 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";\r
1de04b4f 905 public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";\r
99d2c3c4 906 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";\r
907 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";\r
908\r
909\r
910 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n"; \r
911 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";\r
912 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";\r
913 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";\r
914 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";\r
915\r
32648c62 916 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";\r
58f1099f 917 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";\r
32648c62 918 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";\r
58f1099f 919 \r
920 private final static String skuDataTableTemplate = "SkuDataTable";\r
921\r
99d2c3c4 922\r
32648c62 923 private StringTable stringTable;\r
924 private GuidTable guidTable;\r
925 private LocalTokenNumberTable localTokenNumberTable;\r
926 private SkuIdTable skuIdTable;\r
927 private SizeTable sizeTable;\r
928 private ExMapTable exMapTable;\r
99d2c3c4 929\r
32648c62 930 private ArrayList<Token> alTokens;\r
931 private String phase;\r
932 private int assignedTokenNumber;\r
4acf8ce7 933 \r
58f1099f 934 //\r
935 // Use two class global variable to store\r
936 // temperary \r
937 //\r
938 private String privateGlobalName;\r
939 private String privateGlobalCCode;\r
4acf8ce7 940 //\r
941 // After Major changes done to the PCD\r
942 // database generation class PcdDatabase\r
943 // Please increment the version and please\r
944 // also update the version number in PCD\r
945 // service PEIM and DXE driver accordingly.\r
946 //\r
58f1099f 947 private final int version = 2;\r
99d2c3c4 948\r
32648c62 949 private String hString;\r
950 private String cString;\r
99d2c3c4 951\r
1eb73ab5 952 /**\r
953 Constructor for PcdDatabase class. \r
954 \r
955 <p>We have two PCD dynamic(ex) database for the Framework implementation. One\r
956 for PEI phase and the other for DXE phase. </p>\r
957 \r
958 @param alTokens A ArrayList of Dynamic(EX) PCD entry.\r
959 @param exePhase The phase to generate PCD database for: valid input\r
960 is "PEI" or "DXE".\r
961 @param startLen The starting Local Token Number for the PCD database. For\r
962 PEI phase, the starting Local Token Number starts from 0.\r
963 For DXE phase, the starting Local Token Number starts\r
964 from the total number of PCD entry of PEI phase.\r
965 @return void\r
966 **/\r
32648c62 967 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {\r
968 phase = exePhase;\r
969\r
970 stringTable = new StringTable(phase);\r
971 guidTable = new GuidTable(phase);\r
972 localTokenNumberTable = new LocalTokenNumberTable(phase);\r
973 skuIdTable = new SkuIdTable(phase);\r
974 sizeTable = new SizeTable(phase);\r
975 exMapTable = new ExMapTable(phase); \r
976\r
1eb73ab5 977 //\r
978 // Local token number 0 is reserved for INVALID_TOKEN_NUMBER.\r
979 // So we will increment 1 for the startLen passed from the \r
980 // constructor.\r
981 //\r
58f1099f 982 assignedTokenNumber = startLen + 1;\r
32648c62 983 this.alTokens = alTokens;\r
984 }\r
985\r
58f1099f 986 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {\r
987 for (int i = 0; i < alTokens.size(); i++) {\r
988 Token t = (Token)alTokens.get(i);\r
989 if (t.isDynamicEx()) {\r
990 exTokens.add(t);\r
991 } else {\r
992 nexTokens.add(t);\r
993 }\r
994 }\r
995\r
996 return;\r
997 }\r
998\r
58f1099f 999 private int getDataTypeAlignmentSize (Token token) {\r
1000 switch (token.datumType) {\r
1001 case UINT8:\r
1002 return 1;\r
1003 case UINT16:\r
1004 return 2;\r
1005 case UINT32:\r
1006 return 4;\r
1007 case UINT64:\r
1008 return 8;\r
1009 case POINTER:\r
1010 return 1;\r
1011 case BOOLEAN:\r
1012 return 1;\r
1013 default:\r
1014 return 1;\r
1015 }\r
1016 }\r
1017 \r
bb5545b6 1018 private int getHiiPtrTypeAlignmentSize(Token token) {\r
1019 switch (token.datumType) {\r
1020 case UINT8:\r
1021 return 1;\r
1022 case UINT16:\r
1023 return 2;\r
1024 case UINT32:\r
1025 return 4;\r
1026 case UINT64:\r
1027 return 8;\r
1028 case POINTER:\r
1029 if (token.isHiiEnable()) {\r
1030 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1031 return 2;\r
1032 }\r
1033 }\r
1034 return 1;\r
1035 case BOOLEAN:\r
1036 return 1;\r
1037 default:\r
1038 return 1;\r
1039 }\r
1040 }\r
1041 \r
32648c62 1042 private int getAlignmentSize (Token token) {\r
6ff7a41c 1043 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
32648c62 1044 return 2;\r
1045 }\r
1046\r
6ff7a41c 1047 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
32648c62 1048 return 4;\r
1049 }\r
1050\r
f63ef4b2 1051 if (token.isUnicodeStringType()) {\r
32648c62 1052 return 2;\r
1053 }\r
58f1099f 1054 \r
1055 return getDataTypeAlignmentSize(token);\r
32648c62 1056 }\r
1057\r
1058 public String getCString () {\r
1059 return cString;\r
1060 }\r
1061\r
1062 public String getHString () {\r
1063 return hString;\r
1064 }\r
58f1099f 1065 \r
1066 private void genCodeWorker(Token t,\r
1067 ArrayList<CStructTypeDeclaration> declaList,\r
1068 HashMap<String, String> instTable, String phase)\r
1069 throws EntityException {\r
1070\r
1071 CStructTypeDeclaration decl;\r
1072\r
1073 //\r
1074 // Insert SKU_HEAD if isSkuEnable is true\r
1075 //\r
1076 if (t.isSkuEnable()) {\r
1077 int tableIdx;\r
1078 tableIdx = skuIdTable.add(t);\r
1079 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
1080 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
1081 declaList.add(decl);\r
1082 instTable.put(t.getPrimaryKeyString(),\r
1083 getSkuEnabledTypeInstantiaion(t, tableIdx));\r
1084 }\r
1085\r
1086 //\r
1087 // Insert PCD_ENTRY declaration and instantiation\r
1088 //\r
1089 getCDeclarationString(t);\r
1090\r
1091 decl = new CStructTypeDeclaration(privateGlobalName,\r
1092 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
1093 declaList.add(decl);\r
1094\r
1095 if (t.hasDefaultValue()) {\r
1096 instTable.put(privateGlobalName, \r
1097 getTypeInstantiation(t, declaList, instTable, phase)\r
1098 );\r
1099 }\r
1100\r
1101 }\r
1102\r
1eb73ab5 1103 private void ProcessTokens (List<Token> tokens, \r
58f1099f 1104 ArrayList<CStructTypeDeclaration> cStructDeclList,\r
1105 HashMap<String, String> cStructInstTable,\r
1106 String phase\r
1107 ) \r
1108 throws EntityException {\r
1109 \r
1110 for (int idx = 0; idx < tokens.size(); idx++) {\r
1111 Token t = tokens.get(idx);\r
1112 \r
1113 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
1114 \r
1115 sizeTable.add(t);\r
1116 localTokenNumberTable.add(t);\r
1117 t.tokenNumber = assignedTokenNumber++;\r
1118 \r
1119 //\r
1120 // Add a mapping if this dynamic PCD entry is a EX type\r
1121 //\r
1122 if (t.isDynamicEx()) {\r
51da9e80 1123 exMapTable.add((int)t.tokenNumber, \r
58f1099f 1124 t.dynamicExTokenNumber, \r
1125 guidTable.add(t.tokenSpaceName, t.getPrimaryKeyString()), \r
1126 t.getPrimaryKeyString()\r
1127 );\r
1128 }\r
1129 }\r
1130\r
1131 }\r
1132 \r
1eb73ab5 1133 public void genCode () throws EntityException {\r
58f1099f 1134 \r
1135 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
1136 HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
1137 \r
1138 List<Token> nexTokens = new ArrayList<Token> ();\r
1139 List<Token> exTokens = new ArrayList<Token> ();\r
1140\r
1141 getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
1142\r
1143 //\r
1144 // We have to process Non-Ex type PCD entry first. The reason is\r
1145 // that our optimization assumes that the Token Number of Non-Ex \r
1146 // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
1147 // \r
1148 // EX type token number starts from the last Non-EX PCD entry and\r
1149 // grows continously upwards.\r
1150 //\r
1eb73ab5 1151 ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);\r
1152 ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);\r
58f1099f 1153 \r
1eb73ab5 1154 stringTable.genCode(cStructDeclList, cStructInstTable);\r
1155 skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1156 exMapTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1157 localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1158 sizeTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1159 guidTable.genCode(cStructDeclList, cStructInstTable, phase);\r
58f1099f 1160 \r
1161 hString = genCMacroCode ();\r
1162 \r
1163 HashMap <String, String> result;\r
1164 \r
1165 result = genCStructCode(cStructDeclList, \r
1166 cStructInstTable, \r
1167 phase\r
1168 );\r
1169 \r
1170 hString += result.get("initDeclStr");\r
1171 hString += result.get("uninitDeclStr");\r
1172 \r
1173 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
1174 \r
1175 cString = newLine + newLine + result.get("initInstStr");\r
1176 \r
1177 }\r
1178 \r
1179 private String genCMacroCode () {\r
1180 String macroStr = "";\r
1181\r
1182 //\r
1183 // Generate size info Macro for all Tables\r
1184 //\r
1185 macroStr += guidTable.getSizeMacro();\r
1186 macroStr += stringTable.getSizeMacro();\r
1187 macroStr += skuIdTable.getSizeMacro();\r
1188 macroStr += localTokenNumberTable.getSizeMacro();\r
1189 macroStr += exMapTable.getSizeMacro();\r
1de04b4f 1190 macroStr += sizeTable.getSizeMacro();\r
58f1099f 1191\r
1192 //\r
1193 // Generate existance info Macro for all Tables\r
1194 //\r
1195 macroStr += guidTable.getExistanceMacro();\r
1196 macroStr += stringTable.getExistanceMacro();\r
1197 macroStr += skuIdTable.getExistanceMacro();\r
1198 macroStr += localTokenNumberTable.getExistanceMacro();\r
1199 macroStr += exMapTable.getExistanceMacro();\r
1200\r
1201 macroStr += newLine;\r
1202 \r
1203 return macroStr;\r
1204 }\r
1205 \r
1206 private HashMap <String, String> genCStructCode(\r
1207 ArrayList<CStructTypeDeclaration> declaList, \r
1208 HashMap<String, String> instTable, \r
1209 String phase\r
1210 ) {\r
1211 \r
1212 int i;\r
1213 HashMap <String, String> result = new HashMap<String, String>();\r
1214 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
1215 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
1216 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
1217 \r
1218 //\r
1219 // Initialize the storage for each alignment\r
1220 //\r
1221 for (i = 8; i > 0; i>>=1) {\r
1222 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
1223 alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
1224 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
1225 }\r
1226 \r
1227 String initDeclStr = "typedef struct {" + newLine;\r
1228 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
1229 String uninitDeclStr = "typedef struct {" + newLine;\r
1230\r
1231 //\r
1232 // Sort all C declaration and instantiation base on Alignment Size \r
1233 //\r
1234 for (Object d : declaList) {\r
1235 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
1236 \r
1237 if (decl.initTable) {\r
1238 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1239 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
1240 } else {\r
1241 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1242 }\r
1243 }\r
1244\r
1245 //\r
1246 // Generate code for every alignment size\r
1247 //\r
10d8dee5 1248 boolean uinitDatabaseEmpty = true;\r
58f1099f 1249 for (int align = 8; align > 0; align >>= 1) {\r
1250 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
1251 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
1252 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
1253 initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
1254 initInstStr += tab + instListBasedOnAlignment.get(i);\r
1255 \r
1256 //\r
1257 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
1258 // has a least one data memember with alignment size of 1. So we can\r
3534cbb7 1259 // remove the last "," in the C structure instantiation string. Luckily,\r
1260 // this is true as both data structure has SKUID_TABLE anyway.\r
58f1099f 1261 //\r
1262 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
1263 initInstStr += newLine;\r
1264 } else {\r
1265 initInstStr += commaNewLine;\r
1266 }\r
1267 }\r
1268 \r
1269 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
10d8dee5 1270 \r
1271 if (declaListBasedOnAlignment.size() != 0) {\r
1272 uinitDatabaseEmpty = false;\r
1273 }\r
1274 \r
58f1099f 1275 for (Object d : declaListBasedOnAlignment) {\r
1276 String s = (String)d;\r
1277 uninitDeclStr += tab + s;\r
1278 }\r
1279 }\r
1280 \r
10d8dee5 1281 if (uinitDatabaseEmpty) {\r
3534cbb7 1282 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
10d8dee5 1283 }\r
1284 \r
58f1099f 1285 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
10d8dee5 1286 initInstStr += "};" + newLine;\r
58f1099f 1287 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
1288 \r
1289 result.put("initDeclStr", initDeclStr);\r
1290 result.put("initInstStr", initInstStr);\r
1291 result.put("uninitDeclStr", uninitDeclStr);\r
1292\r
1293 return result;\r
1294 }\r
99d2c3c4 1295\r
58f1099f 1296 public static String genInstantiationStr (ArrayList<String> alStr) {\r
32648c62 1297 String str = "";\r
1298 for (int i = 0; i< alStr.size(); i++) {\r
58f1099f 1299 if (i != 0) {\r
1300 str += "\t";\r
1301 }\r
1302 str += alStr.get(i);\r
32648c62 1303 if (i != alStr.size() - 1) {\r
1304 str += "\r\n";\r
1305 }\r
1306 }\r
1307\r
1308 return str;\r
1309 }\r
1310\r
32648c62 1311 private String getSkuEnabledTypeDeclaration (Token token) {\r
3534cbb7 1312 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
32648c62 1313 }\r
1314\r
1315 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
1316\r
1317 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
58f1099f 1318 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
32648c62 1319 }\r
1320\r
1eb73ab5 1321 private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {\r
58f1099f 1322 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
1323 }\r
1324\r
58f1099f 1325 private String getCType (Token t) \r
1326 throws EntityException {\r
1327 \r
1328 if (t.isHiiEnable()) {\r
1329 return "VARIABLE_HEAD";\r
1330 }\r
1331 \r
1332 if (t.isVpdEnable()) {\r
1333 return "VPD_HEAD";\r
1334 }\r
1335 \r
1336 if (t.isUnicodeStringType()) {\r
1337 return "STRING_HEAD";\r
1338 }\r
1339 \r
1340 switch (t.datumType) {\r
1341 case UINT64:\r
1342 return "UINT64";\r
1343 case UINT32:\r
1344 return "UINT32";\r
1345 case UINT16:\r
1346 return "UINT16";\r
1347 case UINT8:\r
1348 return "UINT8";\r
1349 case BOOLEAN:\r
1350 return "BOOLEAN";\r
1351 case POINTER:\r
1352 return "UINT8";\r
1353 default:\r
1354 throw new EntityException("Unknown type in getDataTypeCDeclaration");\r
1355 }\r
1356 }\r
1357 \r
1de04b4f 1358 //\r
1359 // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString\r
1360 //\r
58f1099f 1361 private void getCDeclarationString(Token t) \r
1362 throws EntityException {\r
1363 \r
1364 if (t.isSkuEnable()) {\r
1365 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
1366 } else {\r
1367 privateGlobalName = t.getPrimaryKeyString();\r
1368 }\r
32648c62 1369\r
bb5545b6 1370 String type = getCType(t);\r
1de04b4f 1371 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {\r
bb5545b6 1372 int bufferSize;\r
1373 if (t.isASCIIStringType()) {\r
1374 //\r
1375 // Build tool will add a NULL string at the end of the ASCII string\r
1376 //\r
1377 bufferSize = t.datumSize + 1;\r
58f1099f 1378 } else {\r
bb5545b6 1379 bufferSize = t.datumSize;\r
58f1099f 1380 }\r
bb5545b6 1381 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
1382 } else {\r
1383 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
58f1099f 1384 }\r
1385 }\r
1386 \r
1eb73ab5 1387 private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId) \r
bb5545b6 1388 throws EntityException {\r
58f1099f 1389\r
3534cbb7 1390 String typeStr;\r
58f1099f 1391\r
1392 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1393 typeStr = "UINT8";\r
1394 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1395 typeStr = "UINT16";\r
1396 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1397 typeStr = "UINT32";\r
1398 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1399 typeStr = "UINT64";\r
1400 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1401 typeStr = "BOOLEAN";\r
1402 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
bb5545b6 1403 int size;\r
1404 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1405 typeStr = "UINT16";\r
1406 //\r
1407 // Include the NULL charactor\r
1408 //\r
1409 size = token.datumSize / 2 + 1;\r
1410 } else {\r
1411 typeStr = "UINT8";\r
1412 if (token.isHiiDefaultValueASCIIStringType()) {\r
1413 //\r
1414 // Include the NULL charactor\r
1415 //\r
1416 size = token.datumSize + 1;\r
1417 } else {\r
1418 size = token.datumSize;\r
1419 }\r
1420 }\r
1421 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
58f1099f 1422 } else {\r
bb5545b6 1423 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
58f1099f 1424 }\r
1425\r
3534cbb7 1426 return String.format("%-20s%s;\r\n", typeStr, cName);\r
58f1099f 1427 }\r
1428 \r
58f1099f 1429 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
1430 \r
1431 int i;\r
1432\r
1433 String s;\r
1434 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
1435 s += tab + "{" + newLine;\r
1436\r
1437 for (i = 0; i < t.skuData.size(); i++) {\r
bb5545b6 1438 if (t.isUnicodeStringType()) {\r
58f1099f 1439 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
1440 } else if (t.isHiiEnable()) {\r
1441 /* VPD_HEAD definition\r
1442 typedef struct {\r
1443 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r
1444 UINT16 StringIndex; // Offset in String Table in units of UINT16.\r
1445 UINT16 Offset; // Offset in Variable\r
bb5545b6 1446 UINT16 DefaultValueOffset; // Offset of the Default Value\r
58f1099f 1447 } VARIABLE_HEAD ;\r
1448 */\r
1449 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i); \r
1450 \r
1451 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
1452 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
1453 t.skuData.get(i).value.variableOffset,\r
1454 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
1455 );\r
1456 //\r
1457 // We need to support the default value, so we add the declaration and\r
1458 // the instantiation for the default value.\r
1459 //\r
1460 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
bb5545b6 1461 getHiiPtrTypeAlignmentSize(t),\r
1eb73ab5 1462 getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),\r
58f1099f 1463 true\r
1464 ); \r
1465 declaList.add(decl);\r
1eb73ab5 1466 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));\r
58f1099f 1467 } else if (t.isVpdEnable()) {\r
1468 /* typedef struct {\r
1469 UINT32 Offset;\r
1470 } VPD_HEAD;\r
1471 */\r
1472 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
1473 } else {\r
4276d5da 1474 if (t.isByteStreamType()) {\r
1475 //\r
1476 // Byte stream type input has their own "{" "}", so we won't help to insert.\r
1477 //\r
1478 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
1479 } else {\r
1480 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
1481 }\r
58f1099f 1482 }\r
1483 \r
1484 if (i != t.skuData.size() - 1) {\r
1485 s += commaNewLine;\r
1486 } else {\r
1487 s += newLine;\r
1488 }\r
32648c62 1489\r
58f1099f 1490 }\r
1491 \r
1492 s += tab + "}";\r
1493 \r
1494 return s;\r
1495 }\r
1496 \r
99d2c3c4 1497 public static String getPcdDatabaseCommonDefinitions () \r
1498 throws EntityException {\r
1499\r
1500 String retStr = "";\r
1501 try {\r
32648c62 1502 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1503 "Tools" + File.separator + \r
1504 "Conf" + File.separator +\r
1505 "Pcd" + File.separator +\r
1506 "PcdDatabaseCommonDefinitions.sample");\r
99d2c3c4 1507 FileReader reader = new FileReader(file);\r
1508 BufferedReader in = new BufferedReader(reader);\r
1509 String str;\r
1510 while ((str = in.readLine()) != null) {\r
1511 retStr = retStr +"\r\n" + str;\r
1512 }\r
1513 } catch (Exception ex) {\r
1514 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");\r
1515 }\r
1516\r
1517 return retStr;\r
1518 }\r
1519\r
32648c62 1520 public static String getPcdDxeDatabaseDefinitions () \r
1521 throws EntityException {\r
1522\r
1523 String retStr = "";\r
1524 try {\r
1525 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1526 "Tools" + File.separator + \r
1527 "Conf" + File.separator +\r
1528 "Pcd" + File.separator +\r
1529 "PcdDatabaseDxeDefinitions.sample");\r
1530 FileReader reader = new FileReader(file);\r
1531 BufferedReader in = new BufferedReader(reader);\r
1532 String str;\r
1533 while ((str = in.readLine()) != null) {\r
1534 retStr = retStr +"\r\n" + str;\r
1535 }\r
1536 } catch (Exception ex) {\r
1537 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");\r
1538 }\r
1539\r
1540 return retStr;\r
1541 }\r
1542\r
1543 public static String getPcdPeiDatabaseDefinitions () \r
1544 throws EntityException {\r
1545\r
1546 String retStr = "";\r
1547 try {\r
1548 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1549 "Tools" + File.separator + \r
1550 "Conf" + File.separator +\r
1551 "Pcd" + File.separator +\r
1552 "PcdDatabasePeiDefinitions.sample");\r
1553 FileReader reader = new FileReader(file);\r
1554 BufferedReader in = new BufferedReader(reader);\r
1555 String str;\r
1556 while ((str = in.readLine()) != null) {\r
1557 retStr = retStr +"\r\n" + str;\r
1558 }\r
1559 } catch (Exception ex) {\r
1560 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");\r
1561 }\r
1562\r
1563 return retStr;\r
1564 }\r
99d2c3c4 1565\r
1566}\r
1567\r
8840ad58 1568class ModuleInfo {\r
136adffc 1569 private String type;\r
1570 private FpdModuleIdentification moduleId;\r
1571 private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;\r
1572 \r
1573 \r
8840ad58 1574\r
136adffc 1575 public ModuleInfo (FpdModuleIdentification moduleId, String type, XmlObject pcdDef) {\r
1576 this.moduleId = moduleId;\r
8840ad58 1577 this.type = type;\r
136adffc 1578 this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();\r
1579 }\r
1580 public String getModuleType (){\r
1581 return this.type;\r
1582 }\r
1583 public FpdModuleIdentification getModuleId (){\r
1584 return this.moduleId;\r
1585 }\r
1586 public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){\r
1587 return this.pcdBuildDef;\r
8840ad58 1588 }\r
1589}\r
1590\r
878ddf1f 1591/** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
1592 This class will be used for wizard and build tools, So it can *not* inherit\r
1593 from buildAction or UIAction.\r
1594**/\r
1595public class CollectPCDAction {\r
1596 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.\r
1597 private MemoryDatabaseManager dbManager;\r
1598\r
1599 /// Workspacepath hold the workspace information.\r
1600 private String workspacePath;\r
1601\r
1602 /// FPD file is the root file. \r
1603 private String fpdFilePath;\r
1604\r
1605 /// Message level for CollectPCDAction.\r
1606 private int originalMessageLevel;\r
1607\r
8840ad58 1608 /// Cache the fpd docment instance for private usage.\r
136adffc 1609 private PlatformSurfaceAreaDocument fpdDocInstance;\r
1610 \r
1611 /// xmlObject name\r
1612 private static String xmlObjectName = "PcdBuildDefinition"; \r
1613 \r
878ddf1f 1614 /**\r
1615 Set WorkspacePath parameter for this action class.\r
1616\r
1617 @param workspacePath parameter for this action\r
1618 **/\r
1619 public void setWorkspacePath(String workspacePath) {\r
1620 this.workspacePath = workspacePath;\r
1621 }\r
1622\r
1623 /**\r
1624 Set action message level for CollectPcdAction tool.\r
1625\r
1626 The message should be restored when this action exit.\r
1627\r
1628 @param actionMessageLevel parameter for this action\r
1629 **/\r
1630 public void setActionMessageLevel(int actionMessageLevel) {\r
1631 originalMessageLevel = ActionMessage.messageLevel;\r
1632 ActionMessage.messageLevel = actionMessageLevel;\r
1633 }\r
1634\r
1635 /**\r
1636 Set FPDFileName parameter for this action class.\r
1637\r
1638 @param fpdFilePath fpd file path\r
1639 **/\r
1640 public void setFPDFilePath(String fpdFilePath) {\r
1641 this.fpdFilePath = fpdFilePath;\r
1642 }\r
1643\r
1644 /**\r
1645 Common function interface for outer.\r
1646 \r
1647 @param workspacePath The path of workspace of current build or analysis.\r
1648 @param fpdFilePath The fpd file path of current build or analysis.\r
1649 @param messageLevel The message level for this Action.\r
1650 \r
1651 @throws Exception The exception of this function. Because it can *not* be predict\r
1652 where the action class will be used. So only Exception can be throw.\r
1653 \r
1654 **/\r
1655 public void perform(String workspacePath, String fpdFilePath, \r
1656 int messageLevel) throws Exception {\r
1657 setWorkspacePath(workspacePath);\r
1658 setFPDFilePath(fpdFilePath);\r
1659 setActionMessageLevel(messageLevel);\r
1660 checkParameter();\r
1661 execute();\r
1662 ActionMessage.messageLevel = originalMessageLevel;\r
1663 }\r
1664\r
1665 /**\r
1666 Core execution function for this action class.\r
1667 \r
1668 This function work flows will be:\r
8840ad58 1669 1) Collect and prepocess PCD information from FPD file, all PCD\r
1670 information will be stored into memory database.\r
1671 2) Generate 3 strings for\r
1672 a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
1673 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
1674 c) DXE PCD Database (C structure) for PCD Service DXE.\r
99d2c3c4 1675 \r
878ddf1f 1676 \r
1677 @throws EntityException Exception indicate failed to execute this action.\r
1678 \r
1679 **/\r
136adffc 1680 public void execute() throws EntityException {\r
8840ad58 1681 //\r
1682 // Get memoryDatabaseManager instance from GlobalData.\r
1683 // The memoryDatabaseManager should be initialized for whatever build\r
1684 // tools or wizard tools\r
1685 //\r
1686 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
1687 throw new EntityException("The instance of PCD memory database manager is null");\r
1688 }\r
878ddf1f 1689\r
1690 //\r
1691 // Collect all PCD information defined in FPD file.\r
1692 // Evenry token defind in FPD will be created as an token into \r
1693 // memory database.\r
1694 //\r
8840ad58 1695 createTokenInDBFromFPD();\r
99d2c3c4 1696 \r
1697 //\r
1698 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver\r
1699 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
32648c62 1700 //\r
1701 genPcdDatabaseSourceCode ();\r
1702 \r
878ddf1f 1703 }\r
1704\r
32648c62 1705 /**\r
1706 This function generates source code for PCD Database.\r
1707 \r
1708 @param void\r
1709 @throws EntityException If the token does *not* exist in memory database.\r
99d2c3c4 1710\r
32648c62 1711 **/\r
8840ad58 1712 private void genPcdDatabaseSourceCode()\r
1713 throws EntityException {\r
32648c62 1714 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();\r
99d2c3c4 1715\r
32648c62 1716 ArrayList<Token> alPei = new ArrayList<Token> ();\r
1717 ArrayList<Token> alDxe = new ArrayList<Token> ();\r
99d2c3c4 1718\r
32648c62 1719 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
99d2c3c4 1720 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
1eb73ab5 1721 pcdPeiDatabase.genCode();\r
58f1099f 1722 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()\r
32648c62 1723 + PcdDatabase.getPcdPeiDatabaseDefinitions();\r
58f1099f 1724 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
99d2c3c4 1725\r
1726 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe, \r
32648c62 1727 "DXE",\r
1728 alPei.size()\r
1729 );\r
1eb73ab5 1730 pcdDxeDatabase.genCode();\r
58f1099f 1731 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString()\r
32648c62 1732 + PcdDatabase.getPcdDxeDatabaseDefinitions();\r
58f1099f 1733 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
32648c62 1734 }\r
1735\r
1736 /**\r
8840ad58 1737 Get component array from FPD.\r
878ddf1f 1738 \r
8840ad58 1739 This function maybe provided by some Global class.\r
878ddf1f 1740 \r
8840ad58 1741 @return List<ModuleInfo> the component array.\r
878ddf1f 1742 \r
8840ad58 1743 */\r
1744 private List<ModuleInfo> getComponentsFromFPD() \r
878ddf1f 1745 throws EntityException {\r
8840ad58 1746 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();\r
1747 ModuleInfo current = null;\r
1748 int index = 0;\r
8840ad58 1749 FrameworkModulesDocument.FrameworkModules fModules = null;\r
03b1a72d 1750 ModuleSADocument.ModuleSA[] modules = null;\r
1751 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();\r
878ddf1f 1752\r
8840ad58 1753 if (fpdDocInstance == null) {\r
1754 try {\r
136adffc 1755 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
8840ad58 1756 } catch(IOException ioE) {\r
1757 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
1758 } catch(XmlException xmlE) {\r
1759 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
1760 }\r
878ddf1f 1761\r
878ddf1f 1762 }\r
1763\r
136adffc 1764 Map<FpdModuleIdentification,XmlObject>pcdBuildDef = GlobalData.getFpdModuleSaXmlObject(CollectPCDAction.xmlObjectName);\r
1765 Set<FpdModuleIdentification> pcdBuildKeySet = pcdBuildDef.keySet();\r
1766 Iterator item = pcdBuildKeySet.iterator();\r
1767 while (item.hasNext()){\r
e39bb31c 1768 FpdModuleIdentification id = (FpdModuleIdentification)item.next();\r
1769 allModules.add(new ModuleInfo(id, id.getModule().getModuleType(),pcdBuildDef.get(id))); \r
136adffc 1770 }\r
8840ad58 1771 \r
1772 return allModules;\r
878ddf1f 1773 }\r
1774\r
1775 /**\r
1776 Create token instance object into memory database, the token information\r
1777 comes for FPD file. Normally, FPD file will contain all token platform \r
1778 informations.\r
878ddf1f 1779 \r
1780 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.\r
1781 \r
1782 @throws EntityException Failed to parse FPD xml file.\r
1783 \r
1784 **/\r
8840ad58 1785 private void createTokenInDBFromFPD() \r
878ddf1f 1786 throws EntityException {\r
8840ad58 1787 int index = 0;\r
1788 int index2 = 0;\r
1789 int pcdIndex = 0;\r
6ff7a41c 1790 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
1791 PcdBuildDefinition.PcdData pcdBuildData = null;\r
8840ad58 1792 Token token = null;\r
8840ad58 1793 List<ModuleInfo> modules = null;\r
1794 String primaryKey = null;\r
8840ad58 1795 String exceptionString = null;\r
1796 UsageInstance usageInstance = null;\r
1797 String primaryKey1 = null;\r
1798 String primaryKey2 = null;\r
1799 boolean isDuplicate = false;\r
6ff7a41c 1800 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
1801 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
548ce97a 1802 long tokenNumber = 0;\r
6ff7a41c 1803 String moduleName = null;\r
1804 String datum = null;\r
1805 int maxDatumSize = 0;\r
548ce97a 1806 String[] tokenSpaceStrRet = null;\r
1807\r
878ddf1f 1808 //\r
6ff7a41c 1809 // ----------------------------------------------\r
1810 // 1), Get all <ModuleSA> from FPD file.\r
1811 // ----------------------------------------------\r
878ddf1f 1812 // \r
8840ad58 1813 modules = getComponentsFromFPD();\r
878ddf1f 1814\r
8840ad58 1815 if (modules == null) {\r
7db4ab70 1816 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
878ddf1f 1817 }\r
1818\r
1819 //\r
6ff7a41c 1820 // -------------------------------------------------------------------\r
1821 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
1822 // -------------------------------------------------------------------\r
8840ad58 1823 // \r
1824 for (index = 0; index < modules.size(); index ++) {\r
1825 isDuplicate = false;\r
1826 for (index2 = 0; index2 < index; index2 ++) {\r
1827 //\r
1828 // BUGBUG: For transition schema, we can *not* get module's version from \r
1829 // <ModuleSAs>, It is work around code.\r
1830 // \r
136adffc 1831 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).getModuleId().getModule().getName(), \r
1832 null,\r
833b1541 1833 null,\r
1834 null, \r
136adffc 1835 modules.get(index).getModuleId().getArch(),\r
8840ad58 1836 null);\r
136adffc 1837 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).getModuleId().getModule().getName(), \r
833b1541 1838 null, \r
1839 null, \r
1840 null, \r
136adffc 1841 modules.get(index2).getModuleId().getArch(), \r
8840ad58 1842 null);\r
1843 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {\r
1844 isDuplicate = true;\r
1845 break;\r
1846 }\r
1847 }\r
878ddf1f 1848\r
8840ad58 1849 if (isDuplicate) {\r
1850 continue;\r
1851 }\r
878ddf1f 1852\r
6ff7a41c 1853 //\r
1854 // It is legal for a module does not contains ANY pcd build definitions.\r
1855 // \r
136adffc 1856 if (modules.get(index).getPcdBuildDef() == null) {\r
8840ad58 1857 continue;\r
6ff7a41c 1858 }\r
1859 \r
136adffc 1860 pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();\r
6ff7a41c 1861\r
136adffc 1862 moduleName = modules.get(index).getModuleId().getModule().getName();\r
878ddf1f 1863\r
878ddf1f 1864 //\r
6ff7a41c 1865 // ----------------------------------------------------------------------\r
1866 // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
1867 // ----------------------------------------------------------------------\r
8840ad58 1868 // \r
1869 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {\r
1870 pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
548ce97a 1871 \r
1872 try {\r
1873 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
1874 } catch ( Exception e ) {\r
1875 throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
1876 }\r
1877\r
1878 if (tokenSpaceStrRet == null) {\r
1879 throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
1880 } \r
1881\r
8840ad58 1882 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
548ce97a 1883 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 1884 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
1885 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
51da9e80 1886 tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
6c4dc226 1887 if (pcdBuildData.getValue() != null) {\r
1888 datum = pcdBuildData.getValue().toString();\r
1889 } else {\r
1890 datum = null;\r
1891 }\r
6ff7a41c 1892 maxDatumSize = pcdBuildData.getMaxDatumSize();\r
8840ad58 1893\r
bab72a57 1894 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r
1895 (datumType != Token.DATUM_TYPE.BOOLEAN)){\r
1896 exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
1897 "datum type of this PCD entry is not BOOLEAN!",\r
1898 pcdBuildData.getCName(),\r
1899 moduleName);\r
1900 throw new EntityException(exceptionString);\r
1901 }\r
1902\r
6ff7a41c 1903 //\r
1904 // -------------------------------------------------------------------------------------------\r
1905 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
1906 // -------------------------------------------------------------------------------------------\r
1907 // \r
1908 if (!Token.isDynamic(pcdType)) {\r
1909 //\r
1910 // Value is required.\r
1911 // \r
1912 if (datum == null) {\r
7db4ab70 1913 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r
6ff7a41c 1914 pcdBuildData.getCName(),\r
1915 moduleName);\r
1916 throw new EntityException(exceptionString);\r
1917 }\r
1918\r
1919 //\r
1920 // Check whether the datum size is matched datum type.\r
1921 // \r
6f7e61a0 1922 if ((exceptionString = verifyDatum(pcdBuildData.getCName(), \r
1923 moduleName,\r
1924 datum,\r
1925 datumType,\r
1926 maxDatumSize)) != null) {\r
6ff7a41c 1927 throw new EntityException(exceptionString);\r
1928 }\r
1929 }\r
8840ad58 1930\r
6ff7a41c 1931 //\r
1932 // ---------------------------------------------------------------------------------\r
1933 // 2.1.2), Create token or update token information for current anaylized PCD data.\r
1934 // ---------------------------------------------------------------------------------\r
1935 // \r
8840ad58 1936 if (dbManager.isTokenInDatabase(primaryKey)) {\r
1937 //\r
1938 // If the token is already exist in database, do some necessary checking\r
1939 // and add a usage instance into this token in database\r
1940 // \r
1941 token = dbManager.getTokenByKey(primaryKey);\r
6ff7a41c 1942 \r
1943 //\r
1944 // checking for DatumType, DatumType should be unique for one PCD used in different\r
1945 // modules.\r
1946 // \r
1947 if (token.datumType != datumType) {\r
7db4ab70 1948 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 1949 pcdBuildData.getCName(), \r
1950 pcdBuildData.getDatumType().toString(), \r
1951 Token.getStringOfdatumType(token.datumType));\r
1952 throw new EntityException(exceptionString);\r
1953 }\r
8840ad58 1954\r
878ddf1f 1955 //\r
6ff7a41c 1956 // Check token number is valid\r
8840ad58 1957 // \r
6ff7a41c 1958 if (tokenNumber != token.tokenNumber) {\r
7db4ab70 1959 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 1960 pcdBuildData.getCName(),\r
1961 moduleName);\r
8840ad58 1962 throw new EntityException(exceptionString);\r
1963 }\r
1964\r
878ddf1f 1965 //\r
6ff7a41c 1966 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
8840ad58 1967 // \r
6ff7a41c 1968 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
7db4ab70 1969 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
6ff7a41c 1970 "is different with others module's",\r
1971 token.cName,\r
1972 moduleName);\r
8840ad58 1973 throw new EntityException(exceptionString);\r
1974 }\r
6ff7a41c 1975\r
1976 if (token.isDynamicPCD) {\r
1977 //\r
1978 // Check datum is equal the datum in dynamic information.\r
1979 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
1980 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
1981 // \r
1982 if (!token.isSkuEnable() && \r
7db4ab70 1983 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
1984 (datum != null)) {\r
1985 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
1986 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
6ff7a41c 1987 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
7db4ab70 1988 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
6ff7a41c 1989 token.cName,\r
1990 moduleName);\r
7db4ab70 1991 throw new EntityException(exceptionString);\r
6ff7a41c 1992 }\r
1993 }\r
7db4ab70 1994\r
1995 if ((maxDatumSize != 0) &&\r
1996 (maxDatumSize != token.datumSize)){\r
1997 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r
1998 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
1999 token.cName,\r
2000 moduleName,\r
2001 maxDatumSize,\r
2002 token.datumSize);\r
2003 throw new EntityException(exceptionString);\r
2004 }\r
6ff7a41c 2005 }\r
2006 \r
8840ad58 2007 } else {\r
2008 //\r
2009 // If the token is not in database, create a new token instance and add\r
2010 // a usage instance into this token in database.\r
2011 // \r
548ce97a 2012 try {\r
2013 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
2014 } catch (Exception e) {\r
2015 throw new EntityException("Fail to get token space guid for token " + token.cName);\r
2016 }\r
2017\r
2018 if (tokenSpaceStrRet == null) {\r
2019 throw new EntityException("Fail to get token space guid for token " + token.cName);\r
2020 }\r
2021\r
8840ad58 2022 token = new Token(pcdBuildData.getCName(), \r
548ce97a 2023 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 2024 \r
2025 token.datumType = datumType;\r
2026 token.tokenNumber = tokenNumber;\r
2027 token.isDynamicPCD = Token.isDynamic(pcdType);\r
2028 token.datumSize = maxDatumSize;\r
2029 \r
2030 if (token.isDynamicPCD) {\r
2031 //\r
2032 // For Dynamic and Dynamic Ex type, need find the dynamic information\r
2033 // in <DynamicPcdBuildDefinition> section in FPD file.\r
2034 // \r
2035 updateDynamicInformation(moduleName, \r
2036 token,\r
2037 datum,\r
2038 maxDatumSize);\r
8840ad58 2039 }\r
6ff7a41c 2040 \r
8840ad58 2041 dbManager.addTokenToDatabase(primaryKey, token);\r
878ddf1f 2042 }\r
878ddf1f 2043\r
878ddf1f 2044 //\r
6ff7a41c 2045 // -----------------------------------------------------------------------------------\r
2046 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
2047 // -----------------------------------------------------------------------------------\r
2048 // \r
2049 token.updateSupportPcdType(pcdType);\r
2050\r
2051 //\r
2052 // ------------------------------------------------\r
2053 // 2.1.4), Create an usage instance for this token.\r
2054 // ------------------------------------------------\r
8840ad58 2055 // \r
2056 usageInstance = new UsageInstance(token, \r
6ff7a41c 2057 moduleName, \r
833b1541 2058 null,\r
2059 null,\r
2060 null,\r
136adffc 2061 CommonDefinition.getModuleType(modules.get(index).getModuleType()), \r
6ff7a41c 2062 pcdType,\r
136adffc 2063 modules.get(index).getModuleId().getArch(), \r
8840ad58 2064 null,\r
6ff7a41c 2065 datum,\r
2066 maxDatumSize);\r
8840ad58 2067 token.addUsageInstance(usageInstance);\r
878ddf1f 2068 }\r
878ddf1f 2069 }\r
8d82d611 2070\r
2071 //\r
2072 // ------------------------------------------------\r
2073 // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r
2074 // ------------------------------------------------\r
2075 // \r
2076 List<Token> tokenArray = getUnreferencedDynamicPcd();\r
2077 if (tokenArray != null) {\r
2078 for (index = 0; index < tokenArray.size(); index ++) {\r
2079 dbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(), \r
2080 tokenArray.get(index));\r
2081 }\r
2082 }\r
2083 }\r
2084\r
2085 private List<Token> getUnreferencedDynamicPcd () throws EntityException {\r
78d0508a 2086 List<Token> tokenArray = new ArrayList<Token>();\r
8d82d611 2087 Token token = null;\r
2088 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
2089 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
2090 DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = null;\r
2091 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
2092 Token.PCD_TYPE pcdType;\r
2093 SkuInstance skuInstance = null;\r
2094 String primaryKey = null;\r
2095 boolean hasSkuId0 = false;\r
2096 int index, offset, index2;\r
2097 String temp;\r
2098 String exceptionString;\r
2099 String hiiDefaultValue;\r
2100 String tokenSpaceStrRet[];\r
2101 String variableGuidString[];\r
2102\r
2103 //\r
2104 // If FPD document is not be opened, open and initialize it.\r
2105 // \r
2106 if (fpdDocInstance == null) {\r
2107 try {\r
2108 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
2109 } catch(IOException ioE) {\r
2110 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
2111 } catch(XmlException xmlE) {\r
2112 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
2113 }\r
2114 }\r
2115\r
2116 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
2117 if (dynamicPcdBuildDefinitions == null) {\r
2118 return null;\r
2119 }\r
2120\r
2121 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
2122 for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2 ++) {\r
2123 pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r
2124 try {\r
2125 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
2126 } catch ( Exception e ) {\r
2127 throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
2128 }\r
2129\r
2130 if (tokenSpaceStrRet == null) {\r
2131 throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
2132 } \r
2133\r
2134 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
2135 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
2136\r
2137 if (dbManager.isTokenInDatabase(primaryKey)) {\r
2138 continue;\r
2139 }\r
2140\r
2141 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
2142 if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r
2143 throw new EntityException (String.format("[FPD file error] It not allowed for DYNAMIC PCD %s who is no used by any module",\r
2144 pcdBuildData.getCName()));\r
2145 }\r
2146\r
2147 //\r
2148 // Create new token for unreference dynamic PCD token\r
2149 // \r
2150 token = new Token(pcdBuildData.getCName(), translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
2151 token.datumSize = pcdBuildData.getMaxDatumSize();\r
2152 \r
2153\r
2154 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
2155 token.tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
2156 token.dynamicExTokenNumber = token.tokenNumber;\r
2157 token.isDynamicPCD = true; \r
2158 token.updateSupportPcdType(pcdType);\r
2159\r
2160 exceptionString = verifyDatum(token.cName, \r
2161 null,\r
2162 null, \r
2163 token.datumType, \r
2164 token.datumSize);\r
2165 if (exceptionString != null) {\r
2166 throw new EntityException(exceptionString);\r
2167 }\r
2168\r
2169 skuInfoList = pcdBuildData.getSkuInfoList();\r
2170\r
2171 //\r
2172 // Loop all sku data \r
2173 // \r
2174 for (index = 0; index < skuInfoList.size(); index ++) {\r
2175 skuInstance = new SkuInstance();\r
2176 //\r
2177 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
2178 // \r
2179 temp = skuInfoList.get(index).getSkuId().toString();\r
2180 skuInstance.id = Integer.decode(temp);\r
2181 if (skuInstance.id == 0) {\r
2182 hasSkuId0 = true;\r
2183 }\r
2184 //\r
2185 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
2186 // \r
2187 if (skuInfoList.get(index).getValue() != null) {\r
2188 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
2189 if ((exceptionString = verifyDatum(token.cName, \r
2190 null, \r
2191 skuInfoList.get(index).getValue().toString(), \r
2192 token.datumType, \r
2193 token.datumSize)) != null) {\r
2194 throw new EntityException(exceptionString);\r
2195 }\r
2196\r
2197 token.skuData.add(skuInstance);\r
2198\r
2199 continue;\r
2200 }\r
2201\r
2202 //\r
2203 // Judge whether is HII group case.\r
2204 // \r
2205 if (skuInfoList.get(index).getVariableName() != null) {\r
2206 exceptionString = null;\r
2207 if (skuInfoList.get(index).getVariableGuid() == null) {\r
2208 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
2209 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
2210 token.cName,\r
2211 index);\r
2212 if (exceptionString != null) {\r
2213 throw new EntityException(exceptionString);\r
2214 } \r
2215 }\r
2216\r
2217 if (skuInfoList.get(index).getVariableOffset() == null) {\r
2218 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
2219 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
2220 token.cName,\r
2221 index);\r
2222 if (exceptionString != null) {\r
2223 throw new EntityException(exceptionString);\r
2224 }\r
2225 }\r
2226\r
2227 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
2228 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
2229 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
2230 token.cName,\r
2231 index);\r
2232 if (exceptionString != null) {\r
2233 throw new EntityException(exceptionString);\r
2234 }\r
2235 }\r
2236\r
2237 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
2238 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
2239 } else {\r
2240 hiiDefaultValue = null;\r
2241 }\r
2242\r
2243 if ((exceptionString = verifyDatum(token.cName, \r
2244 null, \r
2245 hiiDefaultValue, \r
2246 token.datumType, \r
2247 token.datumSize)) != null) {\r
2248 throw new EntityException(exceptionString);\r
2249 }\r
2250\r
2251 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
2252 if (offset > 0xFFFF) {\r
2253 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
2254 "exceed 64K, it is not allowed!",\r
2255 token.cName,\r
2256 index));\r
2257 }\r
2258\r
2259 //\r
2260 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
2261 // \r
2262 variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r
2263 if (variableGuidString == null) {\r
2264 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
2265 token.cName, \r
2266 skuInfoList.get(index).getVariableGuid().toString()));\r
2267 }\r
2268 String variableStr = skuInfoList.get(index).getVariableName();\r
2269 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
2270 Matcher matcher = pattern.matcher(variableStr);\r
2271 List<String> varNameList = new ArrayList<String>();\r
2272 while (matcher.find()){\r
2273 String str = variableStr.substring(matcher.start(),matcher.end());\r
2274 varNameList.add(str);\r
2275 }\r
2276\r
2277 skuInstance.value.setHiiData(varNameList,\r
2278 translateSchemaStringToUUID(variableGuidString[1]),\r
2279 skuInfoList.get(index).getVariableOffset(),\r
2280 skuInfoList.get(index).getHiiDefaultValue().toString());\r
2281 token.skuData.add(skuInstance);\r
2282 continue;\r
2283 }\r
2284\r
2285 if (skuInfoList.get(index).getVpdOffset() != null) {\r
2286 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
2287 token.skuData.add(skuInstance);\r
2288 continue;\r
2289 }\r
2290\r
2291 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
2292 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
2293 token.cName);\r
2294 throw new EntityException(exceptionString);\r
2295 }\r
2296\r
2297 if (!hasSkuId0) {\r
2298 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
2299 "no sku id = 0 data, which is required for every dynamic PCD",\r
2300 token.cName);\r
2301 throw new EntityException(exceptionString);\r
2302 }\r
2303\r
2304 tokenArray.add(token);\r
2305 }\r
2306\r
2307 return tokenArray;\r
878ddf1f 2308 }\r
2309\r
6f7e61a0 2310 /**\r
2311 Verify the datum value according its datum size and datum type, this\r
2312 function maybe moved to FPD verification tools in future.\r
2313 \r
2314 @param cName\r
2315 @param moduleName\r
2316 @param datum\r
2317 @param datumType\r
2318 @param maxDatumSize\r
2319 \r
2320 @return String\r
2321 */\r
2322 /***/\r
2323 public String verifyDatum(String cName,\r
2324 String moduleName,\r
2325 String datum, \r
2326 Token.DATUM_TYPE datumType, \r
2327 int maxDatumSize) {\r
2328 String exceptionString = null;\r
2329 int value;\r
2330 BigInteger value64;\r
2331 String subStr;\r
f63ef4b2 2332 int index;\r
6f7e61a0 2333\r
2334 if (moduleName == null) {\r
2335 moduleName = "section <DynamicPcdBuildDefinitions>";\r
2336 } else {\r
2337 moduleName = "module " + moduleName;\r
2338 }\r
2339\r
2340 if (maxDatumSize == 0) {\r
2341 exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r
2342 cName,\r
2343 moduleName);\r
2344 return exceptionString;\r
2345 }\r
2346\r
2347 switch (datumType) {\r
2348 case UINT8:\r
2349 if (maxDatumSize != 1) {\r
2350 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2351 "is UINT8, but datum size is %d, they are not matched!",\r
2352 cName,\r
2353 moduleName,\r
2354 maxDatumSize);\r
2355 return exceptionString;\r
2356 }\r
2357\r
2358 if (datum != null) {\r
2359 try {\r
2360 value = Integer.decode(datum);\r
2361 } catch (NumberFormatException nfeExp) {\r
2362 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r
2363 "digital format of UINT8",\r
2364 cName,\r
2365 moduleName);\r
2366 return exceptionString;\r
2367 }\r
2368 if (value > 0xFF) {\r
2369 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r
2370 " the max size of UINT8 - 0xFF",\r
2371 cName, \r
2372 moduleName,\r
2373 datum);\r
2374 return exceptionString;\r
2375 }\r
2376 }\r
2377 break;\r
2378 case UINT16:\r
2379 if (maxDatumSize != 2) {\r
2380 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2381 "is UINT16, but datum size is %d, they are not matched!",\r
2382 cName,\r
2383 moduleName,\r
2384 maxDatumSize);\r
2385 return exceptionString;\r
2386 }\r
2387 if (datum != null) {\r
2388 try {\r
2389 value = Integer.decode(datum);\r
2390 } catch (NumberFormatException nfeExp) {\r
2391 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r
2392 "not valid digital of UINT16",\r
2393 cName,\r
2394 moduleName);\r
2395 return exceptionString;\r
2396 }\r
2397 if (value > 0xFFFF) {\r
2398 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
2399 "which exceed the range of UINT16 - 0xFFFF",\r
2400 cName, \r
2401 moduleName,\r
2402 datum);\r
2403 return exceptionString;\r
2404 }\r
2405 }\r
2406 break;\r
2407 case UINT32:\r
2408 if (maxDatumSize != 4) {\r
2409 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2410 "is UINT32, but datum size is %d, they are not matched!",\r
2411 cName,\r
2412 moduleName,\r
2413 maxDatumSize);\r
2414 return exceptionString;\r
2415 }\r
2416\r
2417 if (datum != null) {\r
2418 try {\r
2419 if (datum.length() > 2) {\r
2420 if ((datum.charAt(0) == '0') && \r
2421 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
2422 subStr = datum.substring(2, datum.length());\r
2423 value64 = new BigInteger(subStr, 16);\r
2424 } else {\r
2425 value64 = new BigInteger(datum);\r
2426 }\r
2427 } else {\r
2428 value64 = new BigInteger(datum);\r
2429 }\r
2430 } catch (NumberFormatException nfeExp) {\r
2431 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r
2432 "valid digital of UINT32",\r
2433 cName,\r
2434 moduleName);\r
2435 return exceptionString;\r
2436 }\r
2437\r
2438 if (value64.bitLength() > 32) {\r
2439 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r
2440 "exceed the range of UINT32 - 0xFFFFFFFF",\r
2441 cName, \r
2442 moduleName,\r
2443 datum);\r
2444 return exceptionString;\r
2445 }\r
2446 }\r
2447 break;\r
2448 case UINT64:\r
2449 if (maxDatumSize != 8) {\r
2450 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2451 "is UINT64, but datum size is %d, they are not matched!",\r
2452 cName,\r
2453 moduleName,\r
2454 maxDatumSize);\r
2455 return exceptionString;\r
2456 }\r
2457\r
2458 if (datum != null) {\r
2459 try {\r
2460 if (datum.length() > 2) {\r
2461 if ((datum.charAt(0) == '0') && \r
2462 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
2463 subStr = datum.substring(2, datum.length());\r
2464 value64 = new BigInteger(subStr, 16);\r
2465 } else {\r
2466 value64 = new BigInteger(datum);\r
2467 }\r
2468 } else {\r
2469 value64 = new BigInteger(datum);\r
2470 }\r
2471 } catch (NumberFormatException nfeExp) {\r
2472 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r
2473 " digital of UINT64",\r
2474 cName,\r
2475 moduleName);\r
2476 return exceptionString;\r
2477 }\r
2478\r
2479 if (value64.bitLength() > 64) {\r
2480 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
2481 "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r
2482 cName, \r
2483 moduleName,\r
2484 datum);\r
2485 return exceptionString;\r
2486 }\r
2487 }\r
2488 break;\r
2489 case BOOLEAN:\r
2490 if (maxDatumSize != 1) {\r
2491 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2492 "is BOOLEAN, but datum size is %d, they are not matched!",\r
2493 cName,\r
2494 moduleName,\r
2495 maxDatumSize);\r
2496 return exceptionString;\r
2497 }\r
2498\r
2499 if (datum != null) {\r
2500 if (!(datum.equalsIgnoreCase("TRUE") ||\r
2501 datum.equalsIgnoreCase("FALSE"))) {\r
2502 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2503 "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r
2504 cName,\r
2505 moduleName);\r
2506 return exceptionString;\r
2507 }\r
2508\r
2509 }\r
2510 break;\r
2511 case POINTER:\r
2512 if (datum == null) {\r
2513 break;\r
2514 }\r
2515\r
2516 char ch = datum.charAt(0);\r
2517 int start, end;\r
2518 String strValue;\r
2519 //\r
2520 // For void* type PCD, only three datum is support:\r
2521 // 1) Unicode: string with start char is "L"\r
2522 // 2) Ansci: String start char is ""\r
2523 // 3) byte array: String start char "{"\r
2524 // \r
2525 if (ch == 'L') {\r
2526 start = datum.indexOf('\"');\r
2527 end = datum.lastIndexOf('\"');\r
2528 if ((start > end) || \r
2529 (end > datum.length())||\r
2530 ((start == end) && (datum.length() > 0))) {\r
f63ef4b2 2531 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
6f7e61a0 2532 "a UNICODE string because start with L\", but format maybe"+\r
2533 "is not right, correct UNICODE string is L\"...\"!",\r
2534 cName,\r
2535 moduleName);\r
2536 return exceptionString;\r
2537 }\r
2538\r
2539 strValue = datum.substring(start + 1, end);\r
2540 if ((strValue.length() * 2) > maxDatumSize) {\r
f63ef4b2 2541 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
6f7e61a0 2542 "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r
2543 cName,\r
2544 moduleName,\r
2545 strValue.length() * 2, \r
2546 maxDatumSize);\r
2547 return exceptionString;\r
2548 }\r
2549 } else if (ch == '\"'){\r
2550 start = datum.indexOf('\"');\r
2551 end = datum.lastIndexOf('\"');\r
2552 if ((start > end) || \r
2553 (end > datum.length())||\r
2554 ((start == end) && (datum.length() > 0))) {\r
f63ef4b2 2555 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
6f7e61a0 2556 "a ANSCII string because start with \", but format maybe"+\r
2557 "is not right, correct ANSIC string is \"...\"!",\r
2558 cName,\r
2559 moduleName);\r
2560 return exceptionString;\r
2561 }\r
2562 strValue = datum.substring(start + 1, end);\r
2563 if ((strValue.length()) > maxDatumSize) {\r
f63ef4b2 2564 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
6f7e61a0 2565 "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r
2566 cName,\r
2567 moduleName,\r
2568 strValue.length(),\r
2569 maxDatumSize);\r
2570 return exceptionString;\r
2571 }\r
2572 } else if (ch =='{') {\r
2573 String[] strValueArray;\r
2574\r
2575 start = datum.indexOf('{');\r
2576 end = datum.lastIndexOf('}');\r
f63ef4b2 2577 strValue = datum.substring(start + 1, end);\r
2578 strValue = strValue.trim();\r
2579 if (strValue.length() == 0) {\r
2580 break;\r
2581 }\r
6f7e61a0 2582 strValueArray = strValue.split(",");\r
f63ef4b2 2583 for (index = 0; index < strValueArray.length; index ++) {\r
2584 try{\r
2435723a 2585 value = Integer.decode(strValueArray[index].trim());\r
f63ef4b2 2586 } catch (NumberFormatException nfeEx) {\r
2587 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
2588 "it is byte array in fact. For every byte in array should be a valid"+\r
2589 "byte digital, but element %s is not a valid byte digital!",\r
2590 cName,\r
2591 moduleName,\r
2592 strValueArray[index]);\r
2593 return exceptionString;\r
2594 }\r
2595 if (value > 0xFF) {\r
2596 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r
2597 "it is byte array in fact. But the element of %s exceed the byte range",\r
2598 cName,\r
2599 moduleName,\r
2600 strValueArray[index]);\r
2601 return exceptionString;\r
2602 }\r
2603 }\r
2604\r
6f7e61a0 2605 if (strValueArray.length > maxDatumSize) {\r
f63ef4b2 2606 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r
6f7e61a0 2607 "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r
2608 cName,\r
2609 moduleName,\r
2610 strValueArray.length,\r
2611 maxDatumSize);\r
2612 return exceptionString;\r
2613 }\r
2614 } else {\r
f63ef4b2 2615 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 2616 "1) UNICODE string: like L\"xxxx\";\r\n"+\r
2617 "2) ANSIC string: like \"xxx\";\r\n"+\r
2618 "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r
2619 "But the datum in seems does not following above format!",\r
2620 cName, \r
2621 moduleName);\r
2622 return exceptionString;\r
2623 }\r
2624 break;\r
2625 default:\r
2626 exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r
2627 "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r
2628 cName,\r
2629 moduleName);\r
2630 return exceptionString;\r
2631 }\r
2632 return null;\r
2633 }\r
2634\r
878ddf1f 2635 /**\r
6ff7a41c 2636 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
8840ad58 2637 \r
6ff7a41c 2638 This function should be implemented in GlobalData in future.\r
8840ad58 2639 \r
6ff7a41c 2640 @param token The token instance which has hold module's PCD information\r
2641 @param moduleName The name of module who will use this Dynamic PCD.\r
8840ad58 2642 \r
6ff7a41c 2643 @return DynamicPcdBuildDefinitions.PcdBuildData\r
2644 */\r
2645 /***/\r
2646 private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,\r
2647 String moduleName)\r
878ddf1f 2648 throws EntityException {\r
6ff7a41c 2649 int index = 0;\r
2650 String exceptionString = null;\r
2651 String dynamicPrimaryKey = null;\r
2652 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
2653 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
548ce97a 2654 String[] tokenSpaceStrRet = null;\r
878ddf1f 2655\r
3d52de13 2656 //\r
8840ad58 2657 // If FPD document is not be opened, open and initialize it.\r
2658 // \r
2659 if (fpdDocInstance == null) {\r
2660 try {\r
136adffc 2661 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
8840ad58 2662 } catch(IOException ioE) {\r
2663 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
2664 } catch(XmlException xmlE) {\r
2665 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
2666 }\r
3d52de13 2667 }\r
136adffc 2668 \r
2669 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
6ff7a41c 2670 if (dynamicPcdBuildDefinitions == null) {\r
7db4ab70 2671 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
6ff7a41c 2672 "PCD entry %s in module %s!",\r
2673 token.cName,\r
2674 moduleName);\r
2675 throw new EntityException(exceptionString);\r
3d52de13 2676 }\r
8840ad58 2677\r
6ff7a41c 2678 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
2679 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
136adffc 2680 //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];\r
2681 String tokenSpaceGuidString = null;\r
548ce97a 2682 try {\r
2683 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
2684 } catch (Exception e) {\r
2685 throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
2686 }\r
2687 \r
2688 if (tokenSpaceStrRet == null) {\r
2689 throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
2690 }\r
2691\r
6ff7a41c 2692 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
548ce97a 2693 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 2694 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
2695 return dynamicPcdBuildDataArray.get(index);\r
2696 }\r
8840ad58 2697 }\r
2698\r
6ff7a41c 2699 return null;\r
2700 }\r
2701\r
6ff7a41c 2702 /**\r
2703 Update dynamic information for PCD entry.\r
2704 \r
2705 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
2706 FPD file.\r
2707 \r
2708 @param moduleName The name of the module who use this PCD\r
2709 @param token The token instance\r
2710 @param datum The <datum> in module's PCD information\r
2711 @param maxDatumSize The <maxDatumSize> in module's PCD information\r
2712 \r
2713 @return Token\r
2714 */\r
2715 private Token updateDynamicInformation(String moduleName, \r
2716 Token token,\r
2717 String datum,\r
2718 int maxDatumSize) \r
2719 throws EntityException {\r
2720 int index = 0;\r
2721 int offset;\r
2722 String exceptionString = null;\r
2723 DynamicTokenValue dynamicValue;\r
2724 SkuInstance skuInstance = null;\r
2725 String temp;\r
2726 boolean hasSkuId0 = false;\r
38ee8d9e 2727 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
51da9e80 2728 long tokenNumber = 0;\r
6c4dc226 2729 String hiiDefaultValue = null;\r
cd0170f5 2730 String[] variableGuidString = null;\r
6ff7a41c 2731\r
2732 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
2733 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r
2734\r
2735 dynamicInfo = getDynamicInfoFromFPD(token, moduleName);\r
2736 if (dynamicInfo == null) {\r
7db4ab70 2737 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r
6ff7a41c 2738 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
2739 "in FPD file, but it is required!",\r
2740 token.cName,\r
2741 moduleName);\r
2742 throw new EntityException(exceptionString);\r
2743 }\r
878ddf1f 2744\r
7db4ab70 2745 token.datumSize = dynamicInfo.getMaxDatumSize();\r
2746\r
6f7e61a0 2747 exceptionString = verifyDatum(token.cName, \r
2748 moduleName,\r
2749 null, \r
2750 token.datumType, \r
2751 token.datumSize);\r
7db4ab70 2752 if (exceptionString != null) {\r
2753 throw new EntityException(exceptionString);\r
2754 }\r
2755\r
2756 if ((maxDatumSize != 0) && \r
2757 (maxDatumSize != token.datumSize)) {\r
2758 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r
2759 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
2760 token.cName,\r
2761 moduleName, \r
2762 maxDatumSize,\r
2763 dynamicInfo.getMaxDatumSize());\r
2764 throw new EntityException(exceptionString);\r
2765 }\r
51da9e80 2766 tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
38ee8d9e 2767 if (tokenNumber != token.tokenNumber) {\r
2768 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
2769 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
2770 token.cName,\r
2771 moduleName,\r
2772 token.tokenNumber,\r
2773 tokenNumber);\r
2774 throw new EntityException(exceptionString);\r
2775 }\r
2776\r
2777 pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r
2778 if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
2779 token.dynamicExTokenNumber = tokenNumber;\r
2780 }\r
7db4ab70 2781\r
6ff7a41c 2782 skuInfoList = dynamicInfo.getSkuInfoList();\r
878ddf1f 2783\r
6ff7a41c 2784 //\r
2785 // Loop all sku data \r
2786 // \r
2787 for (index = 0; index < skuInfoList.size(); index ++) {\r
2788 skuInstance = new SkuInstance();\r
2789 //\r
2790 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
2791 // \r
2792 temp = skuInfoList.get(index).getSkuId().toString();\r
2793 skuInstance.id = Integer.decode(temp);\r
6ff7a41c 2794 if (skuInstance.id == 0) {\r
2795 hasSkuId0 = true;\r
2796 }\r
2797 //\r
2798 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
2799 // \r
2800 if (skuInfoList.get(index).getValue() != null) {\r
6c4dc226 2801 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
6f7e61a0 2802 if ((exceptionString = verifyDatum(token.cName, \r
2803 null, \r
6c4dc226 2804 skuInfoList.get(index).getValue().toString(), \r
6f7e61a0 2805 token.datumType, \r
2806 token.datumSize)) != null) {\r
2807 throw new EntityException(exceptionString);\r
2808 }\r
2809\r
6ff7a41c 2810 token.skuData.add(skuInstance);\r
8840ad58 2811\r
878ddf1f 2812 //\r
6ff7a41c 2813 // Judege wether is same of datum between module's information\r
2814 // and dynamic information.\r
8840ad58 2815 // \r
6ff7a41c 2816 if (datum != null) {\r
2817 if ((skuInstance.id == 0) &&\r
6c4dc226 2818 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
6f7e61a0 2819 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
7db4ab70 2820 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
2821 " or you could not define value for a dynamic PCD in every <ModuleSA>!"; \r
8840ad58 2822 throw new EntityException(exceptionString);\r
2823 }\r
6ff7a41c 2824 }\r
2825 continue;\r
2826 }\r
8840ad58 2827\r
6ff7a41c 2828 //\r
2829 // Judge whether is HII group case.\r
2830 // \r
2831 if (skuInfoList.get(index).getVariableName() != null) {\r
2832 exceptionString = null;\r
2833 if (skuInfoList.get(index).getVariableGuid() == null) {\r
7db4ab70 2834 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2835 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
2836 token.cName,\r
2837 index);\r
cd0170f5 2838 if (exceptionString != null) {\r
2839 throw new EntityException(exceptionString);\r
2840 } \r
6ff7a41c 2841 }\r
2842\r
2843 if (skuInfoList.get(index).getVariableOffset() == null) {\r
7db4ab70 2844 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2845 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
2846 token.cName,\r
2847 index);\r
cd0170f5 2848 if (exceptionString != null) {\r
2849 throw new EntityException(exceptionString);\r
2850 }\r
6ff7a41c 2851 }\r
2852\r
2853 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
7db4ab70 2854 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2855 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
2856 token.cName,\r
2857 index);\r
cd0170f5 2858 if (exceptionString != null) {\r
2859 throw new EntityException(exceptionString);\r
2860 }\r
878ddf1f 2861 }\r
6ff7a41c 2862\r
6c4dc226 2863 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
2864 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
2865 } else {\r
2866 hiiDefaultValue = null;\r
2867 }\r
6f7e61a0 2868\r
2869 if ((exceptionString = verifyDatum(token.cName, \r
2870 null, \r
6c4dc226 2871 hiiDefaultValue, \r
6f7e61a0 2872 token.datumType, \r
2873 token.datumSize)) != null) {\r
2874 throw new EntityException(exceptionString);\r
2875 }\r
2876\r
6ff7a41c 2877 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
2878 if (offset > 0xFFFF) {\r
7db4ab70 2879 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
6ff7a41c 2880 "exceed 64K, it is not allowed!",\r
2881 token.cName,\r
2882 index));\r
2883 }\r
2884\r
cd0170f5 2885 //\r
2886 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
2887 // \r
136adffc 2888 variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r
cd0170f5 2889 if (variableGuidString == null) {\r
2890 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
2891 token.cName, \r
2892 skuInfoList.get(index).getVariableGuid().toString()));\r
2893 }\r
136adffc 2894 String variableStr = skuInfoList.get(index).getVariableName();\r
2895 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
2896 Matcher matcher = pattern.matcher(variableStr);\r
2897 List<String> varNameList = new ArrayList<String>();\r
2898 while (matcher.find()){\r
2899 String str = variableStr.substring(matcher.start(),matcher.end());\r
2900 varNameList.add(str);\r
2901 }\r
2902 \r
2903 skuInstance.value.setHiiData(varNameList,\r
cd0170f5 2904 translateSchemaStringToUUID(variableGuidString[1]),\r
6ff7a41c 2905 skuInfoList.get(index).getVariableOffset(),\r
6c4dc226 2906 skuInfoList.get(index).getHiiDefaultValue().toString());\r
6ff7a41c 2907 token.skuData.add(skuInstance);\r
2908 continue;\r
878ddf1f 2909 }\r
6ff7a41c 2910\r
2911 if (skuInfoList.get(index).getVpdOffset() != null) {\r
2912 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
2913 token.skuData.add(skuInstance);\r
2914 continue;\r
2915 }\r
2916\r
7db4ab70 2917 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
6ff7a41c 2918 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
2919 token.cName);\r
8840ad58 2920 throw new EntityException(exceptionString);\r
2921 }\r
2922\r
6ff7a41c 2923 if (!hasSkuId0) {\r
7db4ab70 2924 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
6ff7a41c 2925 "no sku id = 0 data, which is required for every dynamic PCD",\r
2926 token.cName);\r
7db4ab70 2927 throw new EntityException(exceptionString);\r
6ff7a41c 2928 }\r
2929\r
8840ad58 2930 return token;\r
2931 }\r
2932\r
2933 /**\r
2934 Translate the schema string to UUID instance.\r
2935 \r
2936 In schema, the string of UUID is defined as following two types string:\r
2937 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
2938 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
2939 \r
2940 2) GuidNamingConvention: pattern =\r
2941 [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
2942 \r
2943 This function will convert string and create uuid instance.\r
2944 \r
2945 @param uuidString UUID string in XML file\r
2946 \r
2947 @return UUID UUID instance\r
2948 **/\r
2949 private UUID translateSchemaStringToUUID(String uuidString) \r
2950 throws EntityException {\r
2951 String temp;\r
2952 String[] splitStringArray;\r
2953 int index;\r
2954 int chIndex;\r
2955 int chLen;\r
2956\r
2957 if (uuidString == null) {\r
2958 return null;\r
2959 }\r
2960\r
2961 if (uuidString.length() == 0) {\r
2962 return null;\r
2963 }\r
2964\r
6ff7a41c 2965 if (uuidString.equals("0") ||\r
2966 uuidString.equalsIgnoreCase("0x0")) {\r
2967 return new UUID(0, 0);\r
2968 }\r
2969\r
cd0170f5 2970 uuidString = uuidString.replaceAll("\\{", "");\r
2971 uuidString = uuidString.replaceAll("\\}", "");\r
2972\r
8840ad58 2973 //\r
2974 // If the UUID schema string is GuidArrayType type then need translate \r
2975 // to GuidNamingConvention type at first.\r
2976 // \r
2977 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
2978 splitStringArray = uuidString.split("," );\r
2979 if (splitStringArray.length != 11) {\r
7db4ab70 2980 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
8840ad58 2981 }\r
2982\r
2983 //\r
2984 // Remove blank space from these string and remove header string "0x"\r
2985 // \r
2986 for (index = 0; index < 11; index ++) {\r
2987 splitStringArray[index] = splitStringArray[index].trim();\r
2988 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
2989 }\r
2990\r
2991 //\r
2992 // Add heading '0' to normalize the string length\r
2993 // \r
2994 for (index = 3; index < 11; index ++) {\r
2995 chLen = splitStringArray[index].length();\r
2996 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
2997 splitStringArray[index] = "0" + splitStringArray[index];\r
2998 }\r
2999 }\r
3000\r
3001 //\r
3002 // construct the final GuidNamingConvention string\r
3003 // \r
3004 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
3005 splitStringArray[0],\r
3006 splitStringArray[1],\r
3007 splitStringArray[2],\r
3008 splitStringArray[3],\r
3009 splitStringArray[4],\r
3010 splitStringArray[5],\r
3011 splitStringArray[6],\r
3012 splitStringArray[7],\r
3013 splitStringArray[8],\r
3014 splitStringArray[9],\r
3015 splitStringArray[10]);\r
3016 uuidString = temp;\r
3017 }\r
3018\r
3019 return UUID.fromString(uuidString);\r
878ddf1f 3020 }\r
3021\r
3022 /**\r
3023 check parameter for this action.\r
3024 \r
3025 @throws EntityException Bad parameter.\r
3026 **/\r
3027 private void checkParameter() throws EntityException {\r
3028 File file = null;\r
3029\r
3030 if((fpdFilePath == null) ||(workspacePath == null)) {\r
3031 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
3032 }\r
3033\r
3034 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r
3035 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
3036 }\r
3037\r
3038 file = new File(workspacePath);\r
3039 if(!file.exists()) {\r
3040 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r
3041 }\r
3042\r
3043 file = new File(fpdFilePath);\r
3044\r
3045 if(!file.exists()) {\r
3046 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r
3047 }\r
3048 }\r
3049\r
3050 /**\r
3051 Test case function\r
3052\r
3053 @param argv parameter from command line\r
3054 **/\r
3055 public static void main(String argv[]) throws EntityException {\r
3056 CollectPCDAction ca = new CollectPCDAction();\r
1de04b4f 3057 String projectDir = "x:/edk2";\r
3058 ca.setWorkspacePath(projectDir);\r
3059 ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r
878ddf1f 3060 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
7629edbc 3061 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
1de04b4f 3062 projectDir,\r
7629edbc 3063 "tools_def.txt");\r
1de04b4f 3064 System.out.println("After initInfo!");\r
7629edbc 3065 FpdParserTask fpt = new FpdParserTask();\r
1de04b4f 3066 fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r
7629edbc 3067 ca.execute();\r
878ddf1f 3068 }\r
3069}\r