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