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