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