]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
Add PcdDxe and PcdPEIM to all-arch for EdkModulePkg-All-Archs.fpd
[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
bb5545b6 1011 private int getHiiPtrTypeAlignmentSize(Token token) {\r
1012 switch (token.datumType) {\r
1013 case UINT8:\r
1014 return 1;\r
1015 case UINT16:\r
1016 return 2;\r
1017 case UINT32:\r
1018 return 4;\r
1019 case UINT64:\r
1020 return 8;\r
1021 case POINTER:\r
1022 if (token.isHiiEnable()) {\r
1023 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1024 return 2;\r
1025 }\r
1026 }\r
1027 return 1;\r
1028 case BOOLEAN:\r
1029 return 1;\r
1030 default:\r
1031 return 1;\r
1032 }\r
1033 }\r
1034 \r
32648c62 1035 private int getAlignmentSize (Token token) {\r
6ff7a41c 1036 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
32648c62 1037 return 2;\r
1038 }\r
1039\r
6ff7a41c 1040 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
32648c62 1041 return 4;\r
1042 }\r
1043\r
f63ef4b2 1044 if (token.isUnicodeStringType()) {\r
32648c62 1045 return 2;\r
1046 }\r
58f1099f 1047 \r
1048 return getDataTypeAlignmentSize(token);\r
32648c62 1049 }\r
1050\r
1051 public String getCString () {\r
1052 return cString;\r
1053 }\r
1054\r
1055 public String getHString () {\r
1056 return hString;\r
1057 }\r
58f1099f 1058 \r
1059 private void genCodeWorker(Token t,\r
1060 ArrayList<CStructTypeDeclaration> declaList,\r
1061 HashMap<String, String> instTable, String phase)\r
1062 throws EntityException {\r
1063\r
1064 CStructTypeDeclaration decl;\r
1065\r
1066 //\r
1067 // Insert SKU_HEAD if isSkuEnable is true\r
1068 //\r
1069 if (t.isSkuEnable()) {\r
1070 int tableIdx;\r
1071 tableIdx = skuIdTable.add(t);\r
1072 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
1073 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
1074 declaList.add(decl);\r
1075 instTable.put(t.getPrimaryKeyString(),\r
1076 getSkuEnabledTypeInstantiaion(t, tableIdx));\r
1077 }\r
1078\r
1079 //\r
1080 // Insert PCD_ENTRY declaration and instantiation\r
1081 //\r
1082 getCDeclarationString(t);\r
1083\r
1084 decl = new CStructTypeDeclaration(privateGlobalName,\r
1085 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
1086 declaList.add(decl);\r
1087\r
1088 if (t.hasDefaultValue()) {\r
1089 instTable.put(privateGlobalName, \r
1090 getTypeInstantiation(t, declaList, instTable, phase)\r
1091 );\r
1092 }\r
1093\r
1094 }\r
1095\r
1096 private void ProcessTokensNew (List<Token> tokens, \r
1097 ArrayList<CStructTypeDeclaration> cStructDeclList,\r
1098 HashMap<String, String> cStructInstTable,\r
1099 String phase\r
1100 ) \r
1101 throws EntityException {\r
1102 \r
1103 for (int idx = 0; idx < tokens.size(); idx++) {\r
1104 Token t = tokens.get(idx);\r
1105 \r
1106 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
1107 \r
1108 sizeTable.add(t);\r
1109 localTokenNumberTable.add(t);\r
1110 t.tokenNumber = assignedTokenNumber++;\r
1111 \r
1112 //\r
1113 // Add a mapping if this dynamic PCD entry is a EX type\r
1114 //\r
1115 if (t.isDynamicEx()) {\r
51da9e80 1116 exMapTable.add((int)t.tokenNumber, \r
58f1099f 1117 t.dynamicExTokenNumber, \r
1118 guidTable.add(t.tokenSpaceName, t.getPrimaryKeyString()), \r
1119 t.getPrimaryKeyString()\r
1120 );\r
1121 }\r
1122 }\r
1123\r
1124 }\r
1125 \r
1126 public void genCodeNew () throws EntityException {\r
1127 \r
1128 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
1129 HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
1130 \r
1131 List<Token> nexTokens = new ArrayList<Token> ();\r
1132 List<Token> exTokens = new ArrayList<Token> ();\r
1133\r
1134 getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
1135\r
1136 //\r
1137 // We have to process Non-Ex type PCD entry first. The reason is\r
1138 // that our optimization assumes that the Token Number of Non-Ex \r
1139 // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
1140 // \r
1141 // EX type token number starts from the last Non-EX PCD entry and\r
1142 // grows continously upwards.\r
1143 //\r
1144 ProcessTokensNew (nexTokens, cStructDeclList, cStructInstTable, phase);\r
1145 ProcessTokensNew (exTokens, cStructDeclList, cStructInstTable, phase);\r
1146 \r
1147 stringTable.genCodeNew(cStructDeclList, cStructInstTable);\r
1148 skuIdTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
1149 exMapTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
1150 localTokenNumberTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
1151 sizeTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
1152 guidTable.genCodeNew(cStructDeclList, cStructInstTable, phase);\r
1153 \r
1154 hString = genCMacroCode ();\r
1155 \r
1156 HashMap <String, String> result;\r
1157 \r
1158 result = genCStructCode(cStructDeclList, \r
1159 cStructInstTable, \r
1160 phase\r
1161 );\r
1162 \r
1163 hString += result.get("initDeclStr");\r
1164 hString += result.get("uninitDeclStr");\r
1165 \r
1166 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
1167 \r
1168 cString = newLine + newLine + result.get("initInstStr");\r
1169 \r
1170 }\r
1171 \r
1172 private String genCMacroCode () {\r
1173 String macroStr = "";\r
1174\r
1175 //\r
1176 // Generate size info Macro for all Tables\r
1177 //\r
1178 macroStr += guidTable.getSizeMacro();\r
1179 macroStr += stringTable.getSizeMacro();\r
1180 macroStr += skuIdTable.getSizeMacro();\r
1181 macroStr += localTokenNumberTable.getSizeMacro();\r
1182 macroStr += exMapTable.getSizeMacro();\r
1183\r
1184 //\r
1185 // Generate existance info Macro for all Tables\r
1186 //\r
1187 macroStr += guidTable.getExistanceMacro();\r
1188 macroStr += stringTable.getExistanceMacro();\r
1189 macroStr += skuIdTable.getExistanceMacro();\r
1190 macroStr += localTokenNumberTable.getExistanceMacro();\r
1191 macroStr += exMapTable.getExistanceMacro();\r
1192\r
1193 macroStr += newLine;\r
1194 \r
1195 return macroStr;\r
1196 }\r
1197 \r
1198 private HashMap <String, String> genCStructCode(\r
1199 ArrayList<CStructTypeDeclaration> declaList, \r
1200 HashMap<String, String> instTable, \r
1201 String phase\r
1202 ) {\r
1203 \r
1204 int i;\r
1205 HashMap <String, String> result = new HashMap<String, String>();\r
1206 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
1207 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
1208 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
1209 \r
1210 //\r
1211 // Initialize the storage for each alignment\r
1212 //\r
1213 for (i = 8; i > 0; i>>=1) {\r
1214 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
1215 alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
1216 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
1217 }\r
1218 \r
1219 String initDeclStr = "typedef struct {" + newLine;\r
1220 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
1221 String uninitDeclStr = "typedef struct {" + newLine;\r
1222\r
1223 //\r
1224 // Sort all C declaration and instantiation base on Alignment Size \r
1225 //\r
1226 for (Object d : declaList) {\r
1227 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
1228 \r
1229 if (decl.initTable) {\r
1230 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1231 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
1232 } else {\r
1233 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1234 }\r
1235 }\r
1236\r
1237 //\r
1238 // Generate code for every alignment size\r
1239 //\r
10d8dee5 1240 boolean uinitDatabaseEmpty = true;\r
58f1099f 1241 for (int align = 8; align > 0; align >>= 1) {\r
1242 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
1243 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
1244 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
1245 initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
1246 initInstStr += tab + instListBasedOnAlignment.get(i);\r
1247 \r
1248 //\r
1249 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
1250 // has a least one data memember with alignment size of 1. So we can\r
3534cbb7 1251 // remove the last "," in the C structure instantiation string. Luckily,\r
1252 // this is true as both data structure has SKUID_TABLE anyway.\r
58f1099f 1253 //\r
1254 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
1255 initInstStr += newLine;\r
1256 } else {\r
1257 initInstStr += commaNewLine;\r
1258 }\r
1259 }\r
1260 \r
1261 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
10d8dee5 1262 \r
1263 if (declaListBasedOnAlignment.size() != 0) {\r
1264 uinitDatabaseEmpty = false;\r
1265 }\r
1266 \r
58f1099f 1267 for (Object d : declaListBasedOnAlignment) {\r
1268 String s = (String)d;\r
1269 uninitDeclStr += tab + s;\r
1270 }\r
1271 }\r
1272 \r
10d8dee5 1273 if (uinitDatabaseEmpty) {\r
3534cbb7 1274 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
10d8dee5 1275 }\r
1276 \r
58f1099f 1277 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
10d8dee5 1278 initInstStr += "};" + newLine;\r
58f1099f 1279 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
1280 \r
1281 result.put("initDeclStr", initDeclStr);\r
1282 result.put("initInstStr", initInstStr);\r
1283 result.put("uninitDeclStr", uninitDeclStr);\r
1284\r
1285 return result;\r
1286 }\r
99d2c3c4 1287\r
6ff7a41c 1288 public void genCode () \r
1289 throws EntityException {\r
99d2c3c4 1290\r
32648c62 1291 final String newLine = "\r\n";\r
32648c62 1292 final String declNewLine = ";\r\n";\r
1293 final String tab = "\t";\r
32648c62 1294 final String commaNewLine = ", \r\n";\r
1295\r
1296 int i;\r
1297 ArrayList<String> decla;\r
1298 ArrayList<String> inst;\r
1299\r
1300 String macroStr = "";\r
1301 String initDeclStr = "";\r
1302 String initInstStr = "";\r
1303 String uninitDeclStr = "";\r
1304\r
1305 List<Token> initTokens = new ArrayList<Token> ();\r
1306 List<Token> uninitTokens = new ArrayList<Token> ();\r
1307 \r
1308 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();\r
1309 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();\r
1310\r
1311 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);\r
1312\r
1313 //\r
1314 // Generate Structure Declaration for PcdTokens without Default Value\r
1315 // PEI_PCD_DATABASE_INIT\r
1316 //\r
6a4cae58 1317 java.util.Comparator<Token> comparator = new AlignmentSizeComp();\r
4c114006 1318 java.util.Collections.sort(initTokens, comparator);\r
32648c62 1319 initCode = processTokens(initTokens);\r
1320\r
1321 //\r
1322 // Generate Structure Declaration for PcdTokens without Default Value\r
1323 // PEI_PCD_DATABASE_UNINIT\r
1324 //\r
4c114006 1325 java.util.Collections.sort(uninitTokens, comparator);\r
32648c62 1326 uninitCode = processTokens(uninitTokens);\r
1327\r
1328 //\r
1329 // Generate size info Macro for all Tables\r
1330 //\r
1331 macroStr += guidTable.getSizeMacro();\r
1332 macroStr += stringTable.getSizeMacro();\r
1333 macroStr += skuIdTable.getSizeMacro();\r
1334 macroStr += localTokenNumberTable.getSizeMacro();\r
1335 macroStr += exMapTable.getSizeMacro();\r
1336\r
1337 //\r
1338 // Generate existance info Macro for all Tables\r
1339 //\r
1340 macroStr += guidTable.getExistanceMacro();\r
1341 macroStr += stringTable.getExistanceMacro();\r
1342 macroStr += skuIdTable.getExistanceMacro();\r
1343 macroStr += localTokenNumberTable.getExistanceMacro();\r
1344 macroStr += exMapTable.getExistanceMacro();\r
1345\r
1346 //\r
1347 // Generate Structure Declaration for PcdTokens with Default Value\r
1348 // for example PEI_PCD_DATABASE_INIT\r
1349 //\r
1350 initDeclStr += "typedef struct {" + newLine;\r
1351 {\r
1352 initDeclStr += tab + exMapTable.getTypeDeclaration();\r
1353 initDeclStr += tab + guidTable.getTypeDeclaration();\r
1354 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();\r
1355 initDeclStr += tab + stringTable.getTypeDeclaration();\r
1356 initDeclStr += tab + sizeTable.getTypeDeclaration();\r
1357 initDeclStr += tab + skuIdTable.getTypeDeclaration();\r
1358 if (phase.equalsIgnoreCase("PEI")) {\r
1359 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;\r
1360 }\r
1361\r
1362 decla = initCode.get(new String("Declaration"));\r
1363 for (i = 0; i < decla.size(); i++) {\r
1364 initDeclStr += tab + decla.get(i) + declNewLine;\r
1365 }\r
1366\r
1367 //\r
1368 // Generate Structure Declaration for PcdToken with SkuEnabled\r
1369 //\r
1370 decla = initCode.get("DeclarationForSku");\r
1371\r
1372 for (i = 0; i < decla.size(); i++) {\r
1373 initDeclStr += tab + decla.get(i) + declNewLine;\r
1374 }\r
1375 }\r
1376 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);\r
1377\r
1378 //\r
1379 // Generate MACRO for structure intialization of PCDTokens with Default Value\r
1380 // The sequence must match the sequence of declaration of the memembers in the structure\r
1381 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());\r
1382 initInstStr += tmp + newLine;\r
1383 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;\r
1384 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;\r
1385 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine; \r
32648c62 1386 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;\r
1387 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;\r
1388 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;\r
1389 //\r
1390 // For SystemSkuId\r
1391 //\r
1392 if (phase.equalsIgnoreCase("PEI")) {\r
1393 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;\r
1394 }\r
1395\r
1396 inst = initCode.get("Instantiation");\r
1397 for (i = 0; i < inst.size(); i++) {\r
1398 initInstStr += tab + inst.get(i) + commaNewLine;\r
1399 }\r
1400\r
1401 inst = initCode.get("InstantiationForSku");\r
1402 for (i = 0; i < inst.size(); i++) {\r
1403 initInstStr += tab + inst.get(i);\r
1404 if (i != inst.size() - 1) {\r
1405 initInstStr += commaNewLine;\r
1406 }\r
1407 }\r
1408\r
1409 initInstStr += "};";\r
1410\r
1411 uninitDeclStr += "typedef struct {" + newLine;\r
1412 {\r
1413 decla = uninitCode.get("Declaration");\r
1414 if (decla.size() == 0) {\r
1415 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;\r
1416 } else {\r
1417 \r
1418 for (i = 0; i < decla.size(); i++) {\r
1419 uninitDeclStr += tab + decla.get(i) + declNewLine;\r
1420 }\r
1421 \r
1422 decla = uninitCode.get("DeclarationForSku");\r
1423 \r
1424 for (i = 0; i < decla.size(); i++) {\r
1425 uninitDeclStr += tab + decla.get(i) + declNewLine;\r
1426 }\r
1427 }\r
1428 }\r
1429 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);\r
1430\r
1431 cString = initInstStr + newLine;\r
1432 hString = macroStr + newLine \r
1433 + initDeclStr + newLine\r
1434 + uninitDeclStr + newLine\r
1435 + newLine;\r
4acf8ce7 1436 \r
1437 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
32648c62 1438\r
1439 }\r
1440\r
58f1099f 1441 public static String genInstantiationStr (ArrayList<String> alStr) {\r
32648c62 1442 String str = "";\r
1443 for (int i = 0; i< alStr.size(); i++) {\r
58f1099f 1444 if (i != 0) {\r
1445 str += "\t";\r
1446 }\r
1447 str += alStr.get(i);\r
32648c62 1448 if (i != alStr.size() - 1) {\r
1449 str += "\r\n";\r
1450 }\r
1451 }\r
1452\r
1453 return str;\r
1454 }\r
1455\r
6ff7a41c 1456 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) \r
1457 throws EntityException {\r
32648c62 1458\r
32648c62 1459 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();\r
1460\r
1461 ArrayList<String> decl = new ArrayList<String>();\r
1462 ArrayList<String> declForSkuEnableType = new ArrayList<String>();\r
1463 ArrayList<String> inst = new ArrayList<String>();\r
1464 ArrayList<String> instForSkuEnableType = new ArrayList<String>();\r
1465\r
1466 for (int index = 0; index < alToken.size(); index++) {\r
1467 Token token = alToken.get(index);\r
1468\r
6ff7a41c 1469 if (token.isSkuEnable()) {\r
32648c62 1470 //\r
1471 // BugBug: Schema only support Data type now\r
1472 //\r
1473 int tableIdx;\r
1474\r
1475 tableIdx = skuIdTable.add(token);\r
1476\r
1477 decl.add(getSkuEnabledTypeDeclaration(token));\r
1478 if (token.hasDefaultValue()) {\r
1479 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx)); \r
1480 }\r
1481\r
1482 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));\r
1483 if (token.hasDefaultValue()) {\r
1484 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));\r
1485 }\r
1486\r
1487 } else {\r
6ff7a41c 1488 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
32648c62 1489 decl.add(getVariableEnableTypeDeclaration(token));\r
1490 inst.add(getVariableEnableInstantiation(token));\r
6ff7a41c 1491 } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
32648c62 1492 decl.add(getVpdEnableTypeDeclaration(token));\r
1493 inst.add(getVpdEnableTypeInstantiation(token));\r
f63ef4b2 1494 } else if (token.isUnicodeStringType()) {\r
32648c62 1495 decl.add(getStringTypeDeclaration(token));\r
1496 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));\r
1497 }\r
1498 else {\r
1499 decl.add(getDataTypeDeclaration(token));\r
1500 if (token.hasDefaultValue()) {\r
1501 inst.add(getDataTypeInstantiation(token));\r
1502 }\r
1503 }\r
1504 }\r
1505\r
1506 sizeTable.add(token);\r
1507 localTokenNumberTable.add(token);\r
8840ad58 1508 token.tokenNumber = assignedTokenNumber++;\r
32648c62 1509\r
1510 }\r
1511\r
1512 map.put("Declaration", decl);\r
1513 map.put("DeclarationForSku", declForSkuEnableType);\r
1514 map.put("Instantiation", inst);\r
1515 map.put("InstantiationForSku", instForSkuEnableType);\r
1516\r
1517 return map;\r
1518 }\r
1519\r
1520 private String getSkuEnabledTypeDeclaration (Token token) {\r
3534cbb7 1521 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
32648c62 1522 }\r
1523\r
1524 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
1525\r
1526 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
58f1099f 1527 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
32648c62 1528 }\r
1529\r
1530 private String getDataTypeDeclarationForSkuEnabled (Token token) {\r
1531 String typeStr = "";\r
1532\r
1533 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1534 typeStr = "UINT8 %s_%s[%d];\r\n";\r
1535 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1536 typeStr = "UINT16 %s_%s[%d];\r\n";\r
1537 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1538 typeStr = "UINT32 %s_%s[%d];\r\n";\r
1539 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1540 typeStr = "UINT64 %s_%s[%d];\r\n";\r
1541 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1542 typeStr = "BOOLEAN %s_%s[%d];\r\n";\r
1543 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
6ff7a41c 1544 return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());\r
32648c62 1545 } \r
1546\r
6ff7a41c 1547 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size());\r
32648c62 1548\r
1549 }\r
1550\r
1551 private String getDataTypeInstantiationForSkuEnabled (Token token) {\r
1552 String str = "";\r
1553\r
1554 if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
6ff7a41c 1555 return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());\r
32648c62 1556 } else {\r
1557 str = "{ ";\r
6ff7a41c 1558 for (int idx = 0; idx < token.skuData.size(); idx++) {\r
32648c62 1559 str += token.skuData.get(idx).toString();\r
6ff7a41c 1560 if (idx != token.skuData.size() - 1) {\r
32648c62 1561 str += ", ";\r
1562 }\r
1563 }\r
1564 str += "}";\r
1565\r
1566 return str;\r
1567 }\r
1568\r
1569 }\r
1570\r
58f1099f 1571 private String getDataTypeInstantiationForVariableDefault_new (Token token, String cName, int skuId) {\r
1572 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
1573 }\r
1574\r
32648c62 1575 private String getDataTypeInstantiation (Token token) {\r
1576\r
32648c62 1577 if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
6ff7a41c 1578 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());\r
32648c62 1579 } else {\r
6ff7a41c 1580 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());\r
32648c62 1581 }\r
1582 }\r
1583\r
58f1099f 1584 private String getCType (Token t) \r
1585 throws EntityException {\r
1586 \r
1587 if (t.isHiiEnable()) {\r
1588 return "VARIABLE_HEAD";\r
1589 }\r
1590 \r
1591 if (t.isVpdEnable()) {\r
1592 return "VPD_HEAD";\r
1593 }\r
1594 \r
1595 if (t.isUnicodeStringType()) {\r
1596 return "STRING_HEAD";\r
1597 }\r
1598 \r
1599 switch (t.datumType) {\r
1600 case UINT64:\r
1601 return "UINT64";\r
1602 case UINT32:\r
1603 return "UINT32";\r
1604 case UINT16:\r
1605 return "UINT16";\r
1606 case UINT8:\r
1607 return "UINT8";\r
1608 case BOOLEAN:\r
1609 return "BOOLEAN";\r
1610 case POINTER:\r
1611 return "UINT8";\r
1612 default:\r
1613 throw new EntityException("Unknown type in getDataTypeCDeclaration");\r
1614 }\r
1615 }\r
1616 \r
1617 private void getCDeclarationString(Token t) \r
1618 throws EntityException {\r
1619 \r
1620 if (t.isSkuEnable()) {\r
1621 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
1622 } else {\r
1623 privateGlobalName = t.getPrimaryKeyString();\r
1624 }\r
32648c62 1625\r
bb5545b6 1626 String type = getCType(t);\r
1627 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable())) {\r
1628 int bufferSize;\r
1629 if (t.isASCIIStringType()) {\r
1630 //\r
1631 // Build tool will add a NULL string at the end of the ASCII string\r
1632 //\r
1633 bufferSize = t.datumSize + 1;\r
58f1099f 1634 } else {\r
bb5545b6 1635 bufferSize = t.datumSize;\r
58f1099f 1636 }\r
bb5545b6 1637 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
1638 } else {\r
1639 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
58f1099f 1640 }\r
1641 }\r
1642 \r
bb5545b6 1643 private String getDataTypeDeclarationForVariableDefault_new (Token token, String cName, int skuId) \r
1644 throws EntityException {\r
58f1099f 1645\r
3534cbb7 1646 String typeStr;\r
58f1099f 1647\r
1648 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1649 typeStr = "UINT8";\r
1650 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1651 typeStr = "UINT16";\r
1652 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1653 typeStr = "UINT32";\r
1654 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1655 typeStr = "UINT64";\r
1656 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1657 typeStr = "BOOLEAN";\r
1658 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
bb5545b6 1659 int size;\r
1660 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1661 typeStr = "UINT16";\r
1662 //\r
1663 // Include the NULL charactor\r
1664 //\r
1665 size = token.datumSize / 2 + 1;\r
1666 } else {\r
1667 typeStr = "UINT8";\r
1668 if (token.isHiiDefaultValueASCIIStringType()) {\r
1669 //\r
1670 // Include the NULL charactor\r
1671 //\r
1672 size = token.datumSize + 1;\r
1673 } else {\r
1674 size = token.datumSize;\r
1675 }\r
1676 }\r
1677 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
58f1099f 1678 } else {\r
bb5545b6 1679 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
58f1099f 1680 }\r
1681\r
3534cbb7 1682 return String.format("%-20s%s;\r\n", typeStr, cName);\r
58f1099f 1683 }\r
1684 \r
32648c62 1685 private String getDataTypeDeclaration (Token token) {\r
1686\r
1687 String typeStr = "";\r
1688\r
1689 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1690 typeStr = "UINT8";\r
1691 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1692 typeStr = "UINT16";\r
1693 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1694 typeStr = "UINT32";\r
1695 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1696 typeStr = "UINT64";\r
1697 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1698 typeStr = "BOOLEAN";\r
1699 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
1700 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);\r
1701 } else {\r
1702 }\r
1703\r
1704 return String.format("%s %s", typeStr, token.getPrimaryKeyString());\r
1705 }\r
1706\r
1707 private String getVpdEnableTypeDeclaration (Token token) {\r
1708 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());\r
1709 }\r
58f1099f 1710 \r
1711 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
1712 \r
1713 int i;\r
1714\r
1715 String s;\r
1716 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
1717 s += tab + "{" + newLine;\r
1718\r
1719 for (i = 0; i < t.skuData.size(); i++) {\r
bb5545b6 1720 if (t.isUnicodeStringType()) {\r
58f1099f 1721 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
1722 } else if (t.isHiiEnable()) {\r
1723 /* VPD_HEAD definition\r
1724 typedef struct {\r
1725 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r
1726 UINT16 StringIndex; // Offset in String Table in units of UINT16.\r
1727 UINT16 Offset; // Offset in Variable\r
bb5545b6 1728 UINT16 DefaultValueOffset; // Offset of the Default Value\r
58f1099f 1729 } VARIABLE_HEAD ;\r
1730 */\r
1731 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i); \r
1732 \r
1733 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
1734 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
1735 t.skuData.get(i).value.variableOffset,\r
1736 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
1737 );\r
1738 //\r
1739 // We need to support the default value, so we add the declaration and\r
1740 // the instantiation for the default value.\r
1741 //\r
1742 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
bb5545b6 1743 getHiiPtrTypeAlignmentSize(t),\r
58f1099f 1744 getDataTypeDeclarationForVariableDefault_new(t, variableDefaultName, i),\r
1745 true\r
1746 ); \r
1747 declaList.add(decl);\r
1748 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault_new (t, variableDefaultName, i));\r
1749 } else if (t.isVpdEnable()) {\r
1750 /* typedef struct {\r
1751 UINT32 Offset;\r
1752 } VPD_HEAD;\r
1753 */\r
1754 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
1755 } else {\r
4276d5da 1756 if (t.isByteStreamType()) {\r
1757 //\r
1758 // Byte stream type input has their own "{" "}", so we won't help to insert.\r
1759 //\r
1760 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
1761 } else {\r
1762 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
1763 }\r
58f1099f 1764 }\r
1765 \r
1766 if (i != t.skuData.size() - 1) {\r
1767 s += commaNewLine;\r
1768 } else {\r
1769 s += newLine;\r
1770 }\r
32648c62 1771\r
58f1099f 1772 }\r
1773 \r
1774 s += tab + "}";\r
1775 \r
1776 return s;\r
1777 }\r
1778 \r
32648c62 1779 private String getVpdEnableTypeInstantiation (Token token) {\r
6ff7a41c 1780 return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset,\r
32648c62 1781 token.getPrimaryKeyString());\r
1782 }\r
1783\r
1784 private String getStringTypeDeclaration (Token token) {\r
1785 return String.format("UINT16 %s", token.getPrimaryKeyString());\r
1786 }\r
1787\r
1788 private String getStringTypeInstantiation (int StringTableIdx, Token token) {\r
1789 return String.format ("%d /* %s */", StringTableIdx,\r
1790 token.getPrimaryKeyString()); \r
1791 }\r
1792\r
1793\r
1794 private String getVariableEnableTypeDeclaration (Token token) {\r
1795 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());\r
1796 }\r
1797\r
6ff7a41c 1798 private String getVariableEnableInstantiation (Token token) \r
1799 throws EntityException {\r
1800 //\r
1801 // Need scott fix\r
1802 // \r
1803 return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()),\r
1804 stringTable.add(token.getDefaultSku().getStringOfVariableName(), token),\r
1805 token.getDefaultSku().variableOffset, \r
32648c62 1806 token.getPrimaryKeyString());\r
1807 }\r
1808\r
1809 public int getTotalTokenNumber () {\r
1810 return sizeTable.getTableLen();\r
1811 }\r
99d2c3c4 1812\r
1813 public static String getPcdDatabaseCommonDefinitions () \r
1814 throws EntityException {\r
1815\r
1816 String retStr = "";\r
1817 try {\r
32648c62 1818 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1819 "Tools" + File.separator + \r
1820 "Conf" + File.separator +\r
1821 "Pcd" + File.separator +\r
1822 "PcdDatabaseCommonDefinitions.sample");\r
99d2c3c4 1823 FileReader reader = new FileReader(file);\r
1824 BufferedReader in = new BufferedReader(reader);\r
1825 String str;\r
1826 while ((str = in.readLine()) != null) {\r
1827 retStr = retStr +"\r\n" + str;\r
1828 }\r
1829 } catch (Exception ex) {\r
1830 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");\r
1831 }\r
1832\r
1833 return retStr;\r
1834 }\r
1835\r
32648c62 1836 public static String getPcdDxeDatabaseDefinitions () \r
1837 throws EntityException {\r
1838\r
1839 String retStr = "";\r
1840 try {\r
1841 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1842 "Tools" + File.separator + \r
1843 "Conf" + File.separator +\r
1844 "Pcd" + File.separator +\r
1845 "PcdDatabaseDxeDefinitions.sample");\r
1846 FileReader reader = new FileReader(file);\r
1847 BufferedReader in = new BufferedReader(reader);\r
1848 String str;\r
1849 while ((str = in.readLine()) != null) {\r
1850 retStr = retStr +"\r\n" + str;\r
1851 }\r
1852 } catch (Exception ex) {\r
1853 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");\r
1854 }\r
1855\r
1856 return retStr;\r
1857 }\r
1858\r
1859 public static String getPcdPeiDatabaseDefinitions () \r
1860 throws EntityException {\r
1861\r
1862 String retStr = "";\r
1863 try {\r
1864 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1865 "Tools" + File.separator + \r
1866 "Conf" + File.separator +\r
1867 "Pcd" + File.separator +\r
1868 "PcdDatabasePeiDefinitions.sample");\r
1869 FileReader reader = new FileReader(file);\r
1870 BufferedReader in = new BufferedReader(reader);\r
1871 String str;\r
1872 while ((str = in.readLine()) != null) {\r
1873 retStr = retStr +"\r\n" + str;\r
1874 }\r
1875 } catch (Exception ex) {\r
1876 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");\r
1877 }\r
1878\r
1879 return retStr;\r
1880 }\r
99d2c3c4 1881\r
1882}\r
1883\r
8840ad58 1884class ModuleInfo {\r
136adffc 1885 private String type;\r
1886 private FpdModuleIdentification moduleId;\r
1887 private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;\r
1888 \r
1889 \r
8840ad58 1890\r
136adffc 1891 public ModuleInfo (FpdModuleIdentification moduleId, String type, XmlObject pcdDef) {\r
1892 this.moduleId = moduleId;\r
8840ad58 1893 this.type = type;\r
136adffc 1894 this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();\r
1895 }\r
1896 public String getModuleType (){\r
1897 return this.type;\r
1898 }\r
1899 public FpdModuleIdentification getModuleId (){\r
1900 return this.moduleId;\r
1901 }\r
1902 public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){\r
1903 return this.pcdBuildDef;\r
8840ad58 1904 }\r
1905}\r
1906\r
878ddf1f 1907/** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
1908 This class will be used for wizard and build tools, So it can *not* inherit\r
1909 from buildAction or UIAction.\r
1910**/\r
1911public class CollectPCDAction {\r
1912 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.\r
1913 private MemoryDatabaseManager dbManager;\r
1914\r
1915 /// Workspacepath hold the workspace information.\r
1916 private String workspacePath;\r
1917\r
1918 /// FPD file is the root file. \r
1919 private String fpdFilePath;\r
1920\r
1921 /// Message level for CollectPCDAction.\r
1922 private int originalMessageLevel;\r
1923\r
8840ad58 1924 /// Cache the fpd docment instance for private usage.\r
136adffc 1925 private PlatformSurfaceAreaDocument fpdDocInstance;\r
1926 \r
1927 /// xmlObject name\r
1928 private static String xmlObjectName = "PcdBuildDefinition"; \r
1929 \r
878ddf1f 1930 /**\r
1931 Set WorkspacePath parameter for this action class.\r
1932\r
1933 @param workspacePath parameter for this action\r
1934 **/\r
1935 public void setWorkspacePath(String workspacePath) {\r
1936 this.workspacePath = workspacePath;\r
1937 }\r
1938\r
1939 /**\r
1940 Set action message level for CollectPcdAction tool.\r
1941\r
1942 The message should be restored when this action exit.\r
1943\r
1944 @param actionMessageLevel parameter for this action\r
1945 **/\r
1946 public void setActionMessageLevel(int actionMessageLevel) {\r
1947 originalMessageLevel = ActionMessage.messageLevel;\r
1948 ActionMessage.messageLevel = actionMessageLevel;\r
1949 }\r
1950\r
1951 /**\r
1952 Set FPDFileName parameter for this action class.\r
1953\r
1954 @param fpdFilePath fpd file path\r
1955 **/\r
1956 public void setFPDFilePath(String fpdFilePath) {\r
1957 this.fpdFilePath = fpdFilePath;\r
1958 }\r
1959\r
1960 /**\r
1961 Common function interface for outer.\r
1962 \r
1963 @param workspacePath The path of workspace of current build or analysis.\r
1964 @param fpdFilePath The fpd file path of current build or analysis.\r
1965 @param messageLevel The message level for this Action.\r
1966 \r
1967 @throws Exception The exception of this function. Because it can *not* be predict\r
1968 where the action class will be used. So only Exception can be throw.\r
1969 \r
1970 **/\r
1971 public void perform(String workspacePath, String fpdFilePath, \r
1972 int messageLevel) throws Exception {\r
1973 setWorkspacePath(workspacePath);\r
1974 setFPDFilePath(fpdFilePath);\r
1975 setActionMessageLevel(messageLevel);\r
1976 checkParameter();\r
1977 execute();\r
1978 ActionMessage.messageLevel = originalMessageLevel;\r
1979 }\r
1980\r
1981 /**\r
1982 Core execution function for this action class.\r
1983 \r
1984 This function work flows will be:\r
8840ad58 1985 1) Collect and prepocess PCD information from FPD file, all PCD\r
1986 information will be stored into memory database.\r
1987 2) Generate 3 strings for\r
1988 a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
1989 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
1990 c) DXE PCD Database (C structure) for PCD Service DXE.\r
99d2c3c4 1991 \r
878ddf1f 1992 \r
1993 @throws EntityException Exception indicate failed to execute this action.\r
1994 \r
1995 **/\r
136adffc 1996 public void execute() throws EntityException {\r
8840ad58 1997 //\r
1998 // Get memoryDatabaseManager instance from GlobalData.\r
1999 // The memoryDatabaseManager should be initialized for whatever build\r
2000 // tools or wizard tools\r
2001 //\r
2002 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
2003 throw new EntityException("The instance of PCD memory database manager is null");\r
2004 }\r
878ddf1f 2005\r
2006 //\r
2007 // Collect all PCD information defined in FPD file.\r
2008 // Evenry token defind in FPD will be created as an token into \r
2009 // memory database.\r
2010 //\r
8840ad58 2011 createTokenInDBFromFPD();\r
99d2c3c4 2012 \r
2013 //\r
2014 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver\r
2015 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
32648c62 2016 //\r
2017 genPcdDatabaseSourceCode ();\r
2018 \r
878ddf1f 2019 }\r
2020\r
32648c62 2021 /**\r
2022 This function generates source code for PCD Database.\r
2023 \r
2024 @param void\r
2025 @throws EntityException If the token does *not* exist in memory database.\r
99d2c3c4 2026\r
32648c62 2027 **/\r
8840ad58 2028 private void genPcdDatabaseSourceCode()\r
2029 throws EntityException {\r
32648c62 2030 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();\r
99d2c3c4 2031\r
32648c62 2032 ArrayList<Token> alPei = new ArrayList<Token> ();\r
2033 ArrayList<Token> alDxe = new ArrayList<Token> ();\r
99d2c3c4 2034\r
32648c62 2035 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
99d2c3c4 2036 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
58f1099f 2037 pcdPeiDatabase.genCodeNew();\r
2038 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()\r
32648c62 2039 + PcdDatabase.getPcdPeiDatabaseDefinitions();\r
58f1099f 2040 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
99d2c3c4 2041\r
2042 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe, \r
32648c62 2043 "DXE",\r
2044 alPei.size()\r
2045 );\r
58f1099f 2046 pcdDxeDatabase.genCodeNew();\r
2047 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString()\r
32648c62 2048 + PcdDatabase.getPcdDxeDatabaseDefinitions();\r
58f1099f 2049 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
32648c62 2050 }\r
2051\r
2052 /**\r
8840ad58 2053 Get component array from FPD.\r
878ddf1f 2054 \r
8840ad58 2055 This function maybe provided by some Global class.\r
878ddf1f 2056 \r
8840ad58 2057 @return List<ModuleInfo> the component array.\r
878ddf1f 2058 \r
8840ad58 2059 */\r
2060 private List<ModuleInfo> getComponentsFromFPD() \r
878ddf1f 2061 throws EntityException {\r
8840ad58 2062 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();\r
2063 ModuleInfo current = null;\r
2064 int index = 0;\r
8840ad58 2065 FrameworkModulesDocument.FrameworkModules fModules = null;\r
03b1a72d 2066 ModuleSADocument.ModuleSA[] modules = null;\r
2067 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();\r
878ddf1f 2068\r
8840ad58 2069 if (fpdDocInstance == null) {\r
2070 try {\r
136adffc 2071 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
8840ad58 2072 } catch(IOException ioE) {\r
2073 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
2074 } catch(XmlException xmlE) {\r
2075 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
2076 }\r
878ddf1f 2077\r
878ddf1f 2078 }\r
2079\r
136adffc 2080 Map<FpdModuleIdentification,XmlObject>pcdBuildDef = GlobalData.getFpdModuleSaXmlObject(CollectPCDAction.xmlObjectName);\r
2081 Set<FpdModuleIdentification> pcdBuildKeySet = pcdBuildDef.keySet();\r
2082 Iterator item = pcdBuildKeySet.iterator();\r
2083 while (item.hasNext()){\r
e39bb31c 2084 FpdModuleIdentification id = (FpdModuleIdentification)item.next();\r
2085 allModules.add(new ModuleInfo(id, id.getModule().getModuleType(),pcdBuildDef.get(id))); \r
136adffc 2086 }\r
8840ad58 2087 \r
2088 return allModules;\r
878ddf1f 2089 }\r
2090\r
2091 /**\r
2092 Create token instance object into memory database, the token information\r
2093 comes for FPD file. Normally, FPD file will contain all token platform \r
2094 informations.\r
878ddf1f 2095 \r
2096 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.\r
2097 \r
2098 @throws EntityException Failed to parse FPD xml file.\r
2099 \r
2100 **/\r
8840ad58 2101 private void createTokenInDBFromFPD() \r
878ddf1f 2102 throws EntityException {\r
8840ad58 2103 int index = 0;\r
2104 int index2 = 0;\r
2105 int pcdIndex = 0;\r
6ff7a41c 2106 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
2107 PcdBuildDefinition.PcdData pcdBuildData = null;\r
8840ad58 2108 Token token = null;\r
8840ad58 2109 SkuInstance skuInstance = null;\r
2110 int skuIndex = 0;\r
2111 List<ModuleInfo> modules = null;\r
2112 String primaryKey = null;\r
8840ad58 2113 String exceptionString = null;\r
2114 UsageInstance usageInstance = null;\r
2115 String primaryKey1 = null;\r
2116 String primaryKey2 = null;\r
2117 boolean isDuplicate = false;\r
6ff7a41c 2118 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
2119 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
548ce97a 2120 long tokenNumber = 0;\r
6ff7a41c 2121 String moduleName = null;\r
2122 String datum = null;\r
2123 int maxDatumSize = 0;\r
548ce97a 2124 String[] tokenSpaceStrRet = null;\r
2125\r
878ddf1f 2126 //\r
6ff7a41c 2127 // ----------------------------------------------\r
2128 // 1), Get all <ModuleSA> from FPD file.\r
2129 // ----------------------------------------------\r
878ddf1f 2130 // \r
8840ad58 2131 modules = getComponentsFromFPD();\r
878ddf1f 2132\r
8840ad58 2133 if (modules == null) {\r
7db4ab70 2134 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
878ddf1f 2135 }\r
2136\r
2137 //\r
6ff7a41c 2138 // -------------------------------------------------------------------\r
2139 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
2140 // -------------------------------------------------------------------\r
8840ad58 2141 // \r
2142 for (index = 0; index < modules.size(); index ++) {\r
2143 isDuplicate = false;\r
2144 for (index2 = 0; index2 < index; index2 ++) {\r
2145 //\r
2146 // BUGBUG: For transition schema, we can *not* get module's version from \r
2147 // <ModuleSAs>, It is work around code.\r
2148 // \r
136adffc 2149 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).getModuleId().getModule().getName(), \r
2150 null,\r
833b1541 2151 null,\r
2152 null, \r
136adffc 2153 modules.get(index).getModuleId().getArch(),\r
8840ad58 2154 null);\r
136adffc 2155 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).getModuleId().getModule().getName(), \r
833b1541 2156 null, \r
2157 null, \r
2158 null, \r
136adffc 2159 modules.get(index2).getModuleId().getArch(), \r
8840ad58 2160 null);\r
2161 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {\r
2162 isDuplicate = true;\r
2163 break;\r
2164 }\r
2165 }\r
878ddf1f 2166\r
8840ad58 2167 if (isDuplicate) {\r
2168 continue;\r
2169 }\r
878ddf1f 2170\r
6ff7a41c 2171 //\r
2172 // It is legal for a module does not contains ANY pcd build definitions.\r
2173 // \r
136adffc 2174 if (modules.get(index).getPcdBuildDef() == null) {\r
8840ad58 2175 continue;\r
6ff7a41c 2176 }\r
2177 \r
136adffc 2178 pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();\r
6ff7a41c 2179\r
136adffc 2180 moduleName = modules.get(index).getModuleId().getModule().getName();\r
878ddf1f 2181\r
878ddf1f 2182 //\r
6ff7a41c 2183 // ----------------------------------------------------------------------\r
2184 // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
2185 // ----------------------------------------------------------------------\r
8840ad58 2186 // \r
2187 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {\r
2188 pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
548ce97a 2189 \r
2190 try {\r
2191 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
2192 } catch ( Exception e ) {\r
2193 throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
2194 }\r
2195\r
2196 if (tokenSpaceStrRet == null) {\r
2197 throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
2198 } \r
2199\r
8840ad58 2200 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
548ce97a 2201 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 2202 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
2203 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
51da9e80 2204 tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
6c4dc226 2205 if (pcdBuildData.getValue() != null) {\r
2206 datum = pcdBuildData.getValue().toString();\r
2207 } else {\r
2208 datum = null;\r
2209 }\r
6ff7a41c 2210 maxDatumSize = pcdBuildData.getMaxDatumSize();\r
8840ad58 2211\r
bab72a57 2212 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r
2213 (datumType != Token.DATUM_TYPE.BOOLEAN)){\r
2214 exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
2215 "datum type of this PCD entry is not BOOLEAN!",\r
2216 pcdBuildData.getCName(),\r
2217 moduleName);\r
2218 throw new EntityException(exceptionString);\r
2219 }\r
2220\r
6ff7a41c 2221 //\r
2222 // -------------------------------------------------------------------------------------------\r
2223 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
2224 // -------------------------------------------------------------------------------------------\r
2225 // \r
2226 if (!Token.isDynamic(pcdType)) {\r
2227 //\r
2228 // Value is required.\r
2229 // \r
2230 if (datum == null) {\r
7db4ab70 2231 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r
6ff7a41c 2232 pcdBuildData.getCName(),\r
2233 moduleName);\r
2234 throw new EntityException(exceptionString);\r
2235 }\r
2236\r
2237 //\r
2238 // Check whether the datum size is matched datum type.\r
2239 // \r
6f7e61a0 2240 if ((exceptionString = verifyDatum(pcdBuildData.getCName(), \r
2241 moduleName,\r
2242 datum,\r
2243 datumType,\r
2244 maxDatumSize)) != null) {\r
6ff7a41c 2245 throw new EntityException(exceptionString);\r
2246 }\r
2247 }\r
8840ad58 2248\r
6ff7a41c 2249 //\r
2250 // ---------------------------------------------------------------------------------\r
2251 // 2.1.2), Create token or update token information for current anaylized PCD data.\r
2252 // ---------------------------------------------------------------------------------\r
2253 // \r
8840ad58 2254 if (dbManager.isTokenInDatabase(primaryKey)) {\r
2255 //\r
2256 // If the token is already exist in database, do some necessary checking\r
2257 // and add a usage instance into this token in database\r
2258 // \r
2259 token = dbManager.getTokenByKey(primaryKey);\r
6ff7a41c 2260 \r
2261 //\r
2262 // checking for DatumType, DatumType should be unique for one PCD used in different\r
2263 // modules.\r
2264 // \r
2265 if (token.datumType != datumType) {\r
7db4ab70 2266 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 2267 pcdBuildData.getCName(), \r
2268 pcdBuildData.getDatumType().toString(), \r
2269 Token.getStringOfdatumType(token.datumType));\r
2270 throw new EntityException(exceptionString);\r
2271 }\r
8840ad58 2272\r
878ddf1f 2273 //\r
6ff7a41c 2274 // Check token number is valid\r
8840ad58 2275 // \r
6ff7a41c 2276 if (tokenNumber != token.tokenNumber) {\r
7db4ab70 2277 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 2278 pcdBuildData.getCName(),\r
2279 moduleName);\r
8840ad58 2280 throw new EntityException(exceptionString);\r
2281 }\r
2282\r
878ddf1f 2283 //\r
6ff7a41c 2284 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
8840ad58 2285 // \r
6ff7a41c 2286 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
7db4ab70 2287 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
6ff7a41c 2288 "is different with others module's",\r
2289 token.cName,\r
2290 moduleName);\r
8840ad58 2291 throw new EntityException(exceptionString);\r
2292 }\r
6ff7a41c 2293\r
2294 if (token.isDynamicPCD) {\r
2295 //\r
2296 // Check datum is equal the datum in dynamic information.\r
2297 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
2298 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
2299 // \r
2300 if (!token.isSkuEnable() && \r
7db4ab70 2301 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
2302 (datum != null)) {\r
2303 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
2304 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
6ff7a41c 2305 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
7db4ab70 2306 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
6ff7a41c 2307 token.cName,\r
2308 moduleName);\r
7db4ab70 2309 throw new EntityException(exceptionString);\r
6ff7a41c 2310 }\r
2311 }\r
7db4ab70 2312\r
2313 if ((maxDatumSize != 0) &&\r
2314 (maxDatumSize != token.datumSize)){\r
2315 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r
2316 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
2317 token.cName,\r
2318 moduleName,\r
2319 maxDatumSize,\r
2320 token.datumSize);\r
2321 throw new EntityException(exceptionString);\r
2322 }\r
6ff7a41c 2323 }\r
2324 \r
8840ad58 2325 } else {\r
2326 //\r
2327 // If the token is not in database, create a new token instance and add\r
2328 // a usage instance into this token in database.\r
2329 // \r
548ce97a 2330 try {\r
2331 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
2332 } catch (Exception e) {\r
2333 throw new EntityException("Fail to get token space guid for token " + token.cName);\r
2334 }\r
2335\r
2336 if (tokenSpaceStrRet == null) {\r
2337 throw new EntityException("Fail to get token space guid for token " + token.cName);\r
2338 }\r
2339\r
8840ad58 2340 token = new Token(pcdBuildData.getCName(), \r
548ce97a 2341 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 2342 \r
2343 token.datumType = datumType;\r
2344 token.tokenNumber = tokenNumber;\r
2345 token.isDynamicPCD = Token.isDynamic(pcdType);\r
2346 token.datumSize = maxDatumSize;\r
2347 \r
2348 if (token.isDynamicPCD) {\r
2349 //\r
2350 // For Dynamic and Dynamic Ex type, need find the dynamic information\r
2351 // in <DynamicPcdBuildDefinition> section in FPD file.\r
2352 // \r
2353 updateDynamicInformation(moduleName, \r
2354 token,\r
2355 datum,\r
2356 maxDatumSize);\r
8840ad58 2357 }\r
6ff7a41c 2358 \r
8840ad58 2359 dbManager.addTokenToDatabase(primaryKey, token);\r
878ddf1f 2360 }\r
878ddf1f 2361\r
878ddf1f 2362 //\r
6ff7a41c 2363 // -----------------------------------------------------------------------------------\r
2364 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
2365 // -----------------------------------------------------------------------------------\r
2366 // \r
2367 token.updateSupportPcdType(pcdType);\r
2368\r
2369 //\r
2370 // ------------------------------------------------\r
2371 // 2.1.4), Create an usage instance for this token.\r
2372 // ------------------------------------------------\r
8840ad58 2373 // \r
2374 usageInstance = new UsageInstance(token, \r
6ff7a41c 2375 moduleName, \r
833b1541 2376 null,\r
2377 null,\r
2378 null,\r
136adffc 2379 CommonDefinition.getModuleType(modules.get(index).getModuleType()), \r
6ff7a41c 2380 pcdType,\r
136adffc 2381 modules.get(index).getModuleId().getArch(), \r
8840ad58 2382 null,\r
6ff7a41c 2383 datum,\r
2384 maxDatumSize);\r
8840ad58 2385 token.addUsageInstance(usageInstance);\r
878ddf1f 2386 }\r
878ddf1f 2387 }\r
878ddf1f 2388 }\r
2389\r
6f7e61a0 2390 /**\r
2391 Verify the datum value according its datum size and datum type, this\r
2392 function maybe moved to FPD verification tools in future.\r
2393 \r
2394 @param cName\r
2395 @param moduleName\r
2396 @param datum\r
2397 @param datumType\r
2398 @param maxDatumSize\r
2399 \r
2400 @return String\r
2401 */\r
2402 /***/\r
2403 public String verifyDatum(String cName,\r
2404 String moduleName,\r
2405 String datum, \r
2406 Token.DATUM_TYPE datumType, \r
2407 int maxDatumSize) {\r
2408 String exceptionString = null;\r
2409 int value;\r
2410 BigInteger value64;\r
2411 String subStr;\r
f63ef4b2 2412 int index;\r
6f7e61a0 2413\r
2414 if (moduleName == null) {\r
2415 moduleName = "section <DynamicPcdBuildDefinitions>";\r
2416 } else {\r
2417 moduleName = "module " + moduleName;\r
2418 }\r
2419\r
2420 if (maxDatumSize == 0) {\r
2421 exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r
2422 cName,\r
2423 moduleName);\r
2424 return exceptionString;\r
2425 }\r
2426\r
2427 switch (datumType) {\r
2428 case UINT8:\r
2429 if (maxDatumSize != 1) {\r
2430 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2431 "is UINT8, but datum size is %d, they are not matched!",\r
2432 cName,\r
2433 moduleName,\r
2434 maxDatumSize);\r
2435 return exceptionString;\r
2436 }\r
2437\r
2438 if (datum != null) {\r
2439 try {\r
2440 value = Integer.decode(datum);\r
2441 } catch (NumberFormatException nfeExp) {\r
2442 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r
2443 "digital format of UINT8",\r
2444 cName,\r
2445 moduleName);\r
2446 return exceptionString;\r
2447 }\r
2448 if (value > 0xFF) {\r
2449 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r
2450 " the max size of UINT8 - 0xFF",\r
2451 cName, \r
2452 moduleName,\r
2453 datum);\r
2454 return exceptionString;\r
2455 }\r
2456 }\r
2457 break;\r
2458 case UINT16:\r
2459 if (maxDatumSize != 2) {\r
2460 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2461 "is UINT16, but datum size is %d, they are not matched!",\r
2462 cName,\r
2463 moduleName,\r
2464 maxDatumSize);\r
2465 return exceptionString;\r
2466 }\r
2467 if (datum != null) {\r
2468 try {\r
2469 value = Integer.decode(datum);\r
2470 } catch (NumberFormatException nfeExp) {\r
2471 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r
2472 "not valid digital of UINT16",\r
2473 cName,\r
2474 moduleName);\r
2475 return exceptionString;\r
2476 }\r
2477 if (value > 0xFFFF) {\r
2478 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
2479 "which exceed the range of UINT16 - 0xFFFF",\r
2480 cName, \r
2481 moduleName,\r
2482 datum);\r
2483 return exceptionString;\r
2484 }\r
2485 }\r
2486 break;\r
2487 case UINT32:\r
2488 if (maxDatumSize != 4) {\r
2489 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2490 "is UINT32, but datum size is %d, they are not matched!",\r
2491 cName,\r
2492 moduleName,\r
2493 maxDatumSize);\r
2494 return exceptionString;\r
2495 }\r
2496\r
2497 if (datum != null) {\r
2498 try {\r
2499 if (datum.length() > 2) {\r
2500 if ((datum.charAt(0) == '0') && \r
2501 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
2502 subStr = datum.substring(2, datum.length());\r
2503 value64 = new BigInteger(subStr, 16);\r
2504 } else {\r
2505 value64 = new BigInteger(datum);\r
2506 }\r
2507 } else {\r
2508 value64 = new BigInteger(datum);\r
2509 }\r
2510 } catch (NumberFormatException nfeExp) {\r
2511 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r
2512 "valid digital of UINT32",\r
2513 cName,\r
2514 moduleName);\r
2515 return exceptionString;\r
2516 }\r
2517\r
2518 if (value64.bitLength() > 32) {\r
2519 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r
2520 "exceed the range of UINT32 - 0xFFFFFFFF",\r
2521 cName, \r
2522 moduleName,\r
2523 datum);\r
2524 return exceptionString;\r
2525 }\r
2526 }\r
2527 break;\r
2528 case UINT64:\r
2529 if (maxDatumSize != 8) {\r
2530 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2531 "is UINT64, but datum size is %d, they are not matched!",\r
2532 cName,\r
2533 moduleName,\r
2534 maxDatumSize);\r
2535 return exceptionString;\r
2536 }\r
2537\r
2538 if (datum != null) {\r
2539 try {\r
2540 if (datum.length() > 2) {\r
2541 if ((datum.charAt(0) == '0') && \r
2542 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
2543 subStr = datum.substring(2, datum.length());\r
2544 value64 = new BigInteger(subStr, 16);\r
2545 } else {\r
2546 value64 = new BigInteger(datum);\r
2547 }\r
2548 } else {\r
2549 value64 = new BigInteger(datum);\r
2550 }\r
2551 } catch (NumberFormatException nfeExp) {\r
2552 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r
2553 " digital of UINT64",\r
2554 cName,\r
2555 moduleName);\r
2556 return exceptionString;\r
2557 }\r
2558\r
2559 if (value64.bitLength() > 64) {\r
2560 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
2561 "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r
2562 cName, \r
2563 moduleName,\r
2564 datum);\r
2565 return exceptionString;\r
2566 }\r
2567 }\r
2568 break;\r
2569 case BOOLEAN:\r
2570 if (maxDatumSize != 1) {\r
2571 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2572 "is BOOLEAN, but datum size is %d, they are not matched!",\r
2573 cName,\r
2574 moduleName,\r
2575 maxDatumSize);\r
2576 return exceptionString;\r
2577 }\r
2578\r
2579 if (datum != null) {\r
2580 if (!(datum.equalsIgnoreCase("TRUE") ||\r
2581 datum.equalsIgnoreCase("FALSE"))) {\r
2582 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
2583 "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r
2584 cName,\r
2585 moduleName);\r
2586 return exceptionString;\r
2587 }\r
2588\r
2589 }\r
2590 break;\r
2591 case POINTER:\r
2592 if (datum == null) {\r
2593 break;\r
2594 }\r
2595\r
2596 char ch = datum.charAt(0);\r
2597 int start, end;\r
2598 String strValue;\r
2599 //\r
2600 // For void* type PCD, only three datum is support:\r
2601 // 1) Unicode: string with start char is "L"\r
2602 // 2) Ansci: String start char is ""\r
2603 // 3) byte array: String start char "{"\r
2604 // \r
2605 if (ch == 'L') {\r
2606 start = datum.indexOf('\"');\r
2607 end = datum.lastIndexOf('\"');\r
2608 if ((start > end) || \r
2609 (end > datum.length())||\r
2610 ((start == end) && (datum.length() > 0))) {\r
f63ef4b2 2611 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
6f7e61a0 2612 "a UNICODE string because start with L\", but format maybe"+\r
2613 "is not right, correct UNICODE string is L\"...\"!",\r
2614 cName,\r
2615 moduleName);\r
2616 return exceptionString;\r
2617 }\r
2618\r
2619 strValue = datum.substring(start + 1, end);\r
2620 if ((strValue.length() * 2) > maxDatumSize) {\r
f63ef4b2 2621 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
6f7e61a0 2622 "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r
2623 cName,\r
2624 moduleName,\r
2625 strValue.length() * 2, \r
2626 maxDatumSize);\r
2627 return exceptionString;\r
2628 }\r
2629 } else if (ch == '\"'){\r
2630 start = datum.indexOf('\"');\r
2631 end = datum.lastIndexOf('\"');\r
2632 if ((start > end) || \r
2633 (end > datum.length())||\r
2634 ((start == end) && (datum.length() > 0))) {\r
f63ef4b2 2635 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
6f7e61a0 2636 "a ANSCII string because start with \", but format maybe"+\r
2637 "is not right, correct ANSIC string is \"...\"!",\r
2638 cName,\r
2639 moduleName);\r
2640 return exceptionString;\r
2641 }\r
2642 strValue = datum.substring(start + 1, end);\r
2643 if ((strValue.length()) > maxDatumSize) {\r
f63ef4b2 2644 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
6f7e61a0 2645 "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r
2646 cName,\r
2647 moduleName,\r
2648 strValue.length(),\r
2649 maxDatumSize);\r
2650 return exceptionString;\r
2651 }\r
2652 } else if (ch =='{') {\r
2653 String[] strValueArray;\r
2654\r
2655 start = datum.indexOf('{');\r
2656 end = datum.lastIndexOf('}');\r
f63ef4b2 2657 strValue = datum.substring(start + 1, end);\r
2658 strValue = strValue.trim();\r
2659 if (strValue.length() == 0) {\r
2660 break;\r
2661 }\r
6f7e61a0 2662 strValueArray = strValue.split(",");\r
f63ef4b2 2663 for (index = 0; index < strValueArray.length; index ++) {\r
2664 try{\r
2435723a 2665 value = Integer.decode(strValueArray[index].trim());\r
f63ef4b2 2666 } catch (NumberFormatException nfeEx) {\r
2667 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
2668 "it is byte array in fact. For every byte in array should be a valid"+\r
2669 "byte digital, but element %s is not a valid byte digital!",\r
2670 cName,\r
2671 moduleName,\r
2672 strValueArray[index]);\r
2673 return exceptionString;\r
2674 }\r
2675 if (value > 0xFF) {\r
2676 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r
2677 "it is byte array in fact. But the element of %s exceed the byte range",\r
2678 cName,\r
2679 moduleName,\r
2680 strValueArray[index]);\r
2681 return exceptionString;\r
2682 }\r
2683 }\r
2684\r
6f7e61a0 2685 if (strValueArray.length > maxDatumSize) {\r
f63ef4b2 2686 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r
6f7e61a0 2687 "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r
2688 cName,\r
2689 moduleName,\r
2690 strValueArray.length,\r
2691 maxDatumSize);\r
2692 return exceptionString;\r
2693 }\r
2694 } else {\r
f63ef4b2 2695 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 2696 "1) UNICODE string: like L\"xxxx\";\r\n"+\r
2697 "2) ANSIC string: like \"xxx\";\r\n"+\r
2698 "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r
2699 "But the datum in seems does not following above format!",\r
2700 cName, \r
2701 moduleName);\r
2702 return exceptionString;\r
2703 }\r
2704 break;\r
2705 default:\r
2706 exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r
2707 "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r
2708 cName,\r
2709 moduleName);\r
2710 return exceptionString;\r
2711 }\r
2712 return null;\r
2713 }\r
2714\r
878ddf1f 2715 /**\r
6ff7a41c 2716 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
8840ad58 2717 \r
6ff7a41c 2718 This function should be implemented in GlobalData in future.\r
8840ad58 2719 \r
6ff7a41c 2720 @param token The token instance which has hold module's PCD information\r
2721 @param moduleName The name of module who will use this Dynamic PCD.\r
8840ad58 2722 \r
6ff7a41c 2723 @return DynamicPcdBuildDefinitions.PcdBuildData\r
2724 */\r
2725 /***/\r
2726 private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,\r
2727 String moduleName)\r
878ddf1f 2728 throws EntityException {\r
6ff7a41c 2729 int index = 0;\r
2730 String exceptionString = null;\r
2731 String dynamicPrimaryKey = null;\r
2732 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
2733 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
548ce97a 2734 String[] tokenSpaceStrRet = null;\r
878ddf1f 2735\r
3d52de13 2736 //\r
8840ad58 2737 // If FPD document is not be opened, open and initialize it.\r
2738 // \r
2739 if (fpdDocInstance == null) {\r
2740 try {\r
136adffc 2741 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
8840ad58 2742 } catch(IOException ioE) {\r
2743 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
2744 } catch(XmlException xmlE) {\r
2745 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
2746 }\r
3d52de13 2747 }\r
136adffc 2748 \r
2749 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
6ff7a41c 2750 if (dynamicPcdBuildDefinitions == null) {\r
7db4ab70 2751 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
6ff7a41c 2752 "PCD entry %s in module %s!",\r
2753 token.cName,\r
2754 moduleName);\r
2755 throw new EntityException(exceptionString);\r
3d52de13 2756 }\r
8840ad58 2757\r
6ff7a41c 2758 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
2759 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
136adffc 2760 //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];\r
2761 String tokenSpaceGuidString = null;\r
548ce97a 2762 try {\r
2763 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
2764 } catch (Exception e) {\r
2765 throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
2766 }\r
2767 \r
2768 if (tokenSpaceStrRet == null) {\r
2769 throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
2770 }\r
2771\r
6ff7a41c 2772 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
548ce97a 2773 translateSchemaStringToUUID(tokenSpaceStrRet[1]));\r
6ff7a41c 2774 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
2775 return dynamicPcdBuildDataArray.get(index);\r
2776 }\r
8840ad58 2777 }\r
2778\r
6ff7a41c 2779 return null;\r
2780 }\r
2781\r
6ff7a41c 2782 /**\r
2783 Update dynamic information for PCD entry.\r
2784 \r
2785 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
2786 FPD file.\r
2787 \r
2788 @param moduleName The name of the module who use this PCD\r
2789 @param token The token instance\r
2790 @param datum The <datum> in module's PCD information\r
2791 @param maxDatumSize The <maxDatumSize> in module's PCD information\r
2792 \r
2793 @return Token\r
2794 */\r
2795 private Token updateDynamicInformation(String moduleName, \r
2796 Token token,\r
2797 String datum,\r
2798 int maxDatumSize) \r
2799 throws EntityException {\r
2800 int index = 0;\r
2801 int offset;\r
2802 String exceptionString = null;\r
2803 DynamicTokenValue dynamicValue;\r
2804 SkuInstance skuInstance = null;\r
2805 String temp;\r
2806 boolean hasSkuId0 = false;\r
38ee8d9e 2807 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
51da9e80 2808 long tokenNumber = 0;\r
6c4dc226 2809 String hiiDefaultValue = null;\r
cd0170f5 2810 String[] variableGuidString = null;\r
6ff7a41c 2811\r
2812 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
2813 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r
2814\r
2815 dynamicInfo = getDynamicInfoFromFPD(token, moduleName);\r
2816 if (dynamicInfo == null) {\r
7db4ab70 2817 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r
6ff7a41c 2818 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
2819 "in FPD file, but it is required!",\r
2820 token.cName,\r
2821 moduleName);\r
2822 throw new EntityException(exceptionString);\r
2823 }\r
878ddf1f 2824\r
7db4ab70 2825 token.datumSize = dynamicInfo.getMaxDatumSize();\r
2826\r
6f7e61a0 2827 exceptionString = verifyDatum(token.cName, \r
2828 moduleName,\r
2829 null, \r
2830 token.datumType, \r
2831 token.datumSize);\r
7db4ab70 2832 if (exceptionString != null) {\r
2833 throw new EntityException(exceptionString);\r
2834 }\r
2835\r
2836 if ((maxDatumSize != 0) && \r
2837 (maxDatumSize != token.datumSize)) {\r
2838 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r
2839 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
2840 token.cName,\r
2841 moduleName, \r
2842 maxDatumSize,\r
2843 dynamicInfo.getMaxDatumSize());\r
2844 throw new EntityException(exceptionString);\r
2845 }\r
51da9e80 2846 tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
38ee8d9e 2847 if (tokenNumber != token.tokenNumber) {\r
2848 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
2849 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
2850 token.cName,\r
2851 moduleName,\r
2852 token.tokenNumber,\r
2853 tokenNumber);\r
2854 throw new EntityException(exceptionString);\r
2855 }\r
2856\r
2857 pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r
2858 if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
2859 token.dynamicExTokenNumber = tokenNumber;\r
2860 }\r
7db4ab70 2861\r
6ff7a41c 2862 skuInfoList = dynamicInfo.getSkuInfoList();\r
878ddf1f 2863\r
6ff7a41c 2864 //\r
2865 // Loop all sku data \r
2866 // \r
2867 for (index = 0; index < skuInfoList.size(); index ++) {\r
2868 skuInstance = new SkuInstance();\r
2869 //\r
2870 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
2871 // \r
2872 temp = skuInfoList.get(index).getSkuId().toString();\r
2873 skuInstance.id = Integer.decode(temp);\r
6ff7a41c 2874 if (skuInstance.id == 0) {\r
2875 hasSkuId0 = true;\r
2876 }\r
2877 //\r
2878 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
2879 // \r
2880 if (skuInfoList.get(index).getValue() != null) {\r
6c4dc226 2881 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
6f7e61a0 2882 if ((exceptionString = verifyDatum(token.cName, \r
2883 null, \r
6c4dc226 2884 skuInfoList.get(index).getValue().toString(), \r
6f7e61a0 2885 token.datumType, \r
2886 token.datumSize)) != null) {\r
2887 throw new EntityException(exceptionString);\r
2888 }\r
2889\r
6ff7a41c 2890 token.skuData.add(skuInstance);\r
8840ad58 2891\r
878ddf1f 2892 //\r
6ff7a41c 2893 // Judege wether is same of datum between module's information\r
2894 // and dynamic information.\r
8840ad58 2895 // \r
6ff7a41c 2896 if (datum != null) {\r
2897 if ((skuInstance.id == 0) &&\r
6c4dc226 2898 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
6f7e61a0 2899 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
7db4ab70 2900 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
2901 " or you could not define value for a dynamic PCD in every <ModuleSA>!"; \r
8840ad58 2902 throw new EntityException(exceptionString);\r
2903 }\r
6ff7a41c 2904 }\r
2905 continue;\r
2906 }\r
8840ad58 2907\r
6ff7a41c 2908 //\r
2909 // Judge whether is HII group case.\r
2910 // \r
2911 if (skuInfoList.get(index).getVariableName() != null) {\r
2912 exceptionString = null;\r
2913 if (skuInfoList.get(index).getVariableGuid() == null) {\r
7db4ab70 2914 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2915 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
2916 token.cName,\r
2917 index);\r
cd0170f5 2918 if (exceptionString != null) {\r
2919 throw new EntityException(exceptionString);\r
2920 } \r
6ff7a41c 2921 }\r
2922\r
2923 if (skuInfoList.get(index).getVariableOffset() == null) {\r
7db4ab70 2924 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2925 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
2926 token.cName,\r
2927 index);\r
cd0170f5 2928 if (exceptionString != null) {\r
2929 throw new EntityException(exceptionString);\r
2930 }\r
6ff7a41c 2931 }\r
2932\r
2933 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
7db4ab70 2934 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
6ff7a41c 2935 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
2936 token.cName,\r
2937 index);\r
cd0170f5 2938 if (exceptionString != null) {\r
2939 throw new EntityException(exceptionString);\r
2940 }\r
878ddf1f 2941 }\r
6ff7a41c 2942\r
6c4dc226 2943 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
2944 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
2945 } else {\r
2946 hiiDefaultValue = null;\r
2947 }\r
6f7e61a0 2948\r
2949 if ((exceptionString = verifyDatum(token.cName, \r
2950 null, \r
6c4dc226 2951 hiiDefaultValue, \r
6f7e61a0 2952 token.datumType, \r
2953 token.datumSize)) != null) {\r
2954 throw new EntityException(exceptionString);\r
2955 }\r
2956\r
6ff7a41c 2957 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
2958 if (offset > 0xFFFF) {\r
7db4ab70 2959 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
6ff7a41c 2960 "exceed 64K, it is not allowed!",\r
2961 token.cName,\r
2962 index));\r
2963 }\r
2964\r
cd0170f5 2965 //\r
2966 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
2967 // \r
136adffc 2968 variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r
cd0170f5 2969 if (variableGuidString == null) {\r
2970 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
2971 token.cName, \r
2972 skuInfoList.get(index).getVariableGuid().toString()));\r
2973 }\r
136adffc 2974 String variableStr = skuInfoList.get(index).getVariableName();\r
2975 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
2976 Matcher matcher = pattern.matcher(variableStr);\r
2977 List<String> varNameList = new ArrayList<String>();\r
2978 while (matcher.find()){\r
2979 String str = variableStr.substring(matcher.start(),matcher.end());\r
2980 varNameList.add(str);\r
2981 }\r
2982 \r
2983 skuInstance.value.setHiiData(varNameList,\r
cd0170f5 2984 translateSchemaStringToUUID(variableGuidString[1]),\r
6ff7a41c 2985 skuInfoList.get(index).getVariableOffset(),\r
6c4dc226 2986 skuInfoList.get(index).getHiiDefaultValue().toString());\r
6ff7a41c 2987 token.skuData.add(skuInstance);\r
2988 continue;\r
878ddf1f 2989 }\r
6ff7a41c 2990\r
2991 if (skuInfoList.get(index).getVpdOffset() != null) {\r
2992 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
2993 token.skuData.add(skuInstance);\r
2994 continue;\r
2995 }\r
2996\r
7db4ab70 2997 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
6ff7a41c 2998 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
2999 token.cName);\r
8840ad58 3000 throw new EntityException(exceptionString);\r
3001 }\r
3002\r
6ff7a41c 3003 if (!hasSkuId0) {\r
7db4ab70 3004 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
6ff7a41c 3005 "no sku id = 0 data, which is required for every dynamic PCD",\r
3006 token.cName);\r
7db4ab70 3007 throw new EntityException(exceptionString);\r
6ff7a41c 3008 }\r
3009\r
8840ad58 3010 return token;\r
3011 }\r
3012\r
3013 /**\r
3014 Translate the schema string to UUID instance.\r
3015 \r
3016 In schema, the string of UUID is defined as following two types string:\r
3017 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
3018 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
3019 \r
3020 2) GuidNamingConvention: pattern =\r
3021 [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
3022 \r
3023 This function will convert string and create uuid instance.\r
3024 \r
3025 @param uuidString UUID string in XML file\r
3026 \r
3027 @return UUID UUID instance\r
3028 **/\r
3029 private UUID translateSchemaStringToUUID(String uuidString) \r
3030 throws EntityException {\r
3031 String temp;\r
3032 String[] splitStringArray;\r
3033 int index;\r
3034 int chIndex;\r
3035 int chLen;\r
3036\r
3037 if (uuidString == null) {\r
3038 return null;\r
3039 }\r
3040\r
3041 if (uuidString.length() == 0) {\r
3042 return null;\r
3043 }\r
3044\r
6ff7a41c 3045 if (uuidString.equals("0") ||\r
3046 uuidString.equalsIgnoreCase("0x0")) {\r
3047 return new UUID(0, 0);\r
3048 }\r
3049\r
cd0170f5 3050 uuidString = uuidString.replaceAll("\\{", "");\r
3051 uuidString = uuidString.replaceAll("\\}", "");\r
3052\r
8840ad58 3053 //\r
3054 // If the UUID schema string is GuidArrayType type then need translate \r
3055 // to GuidNamingConvention type at first.\r
3056 // \r
3057 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
3058 splitStringArray = uuidString.split("," );\r
3059 if (splitStringArray.length != 11) {\r
7db4ab70 3060 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
8840ad58 3061 }\r
3062\r
3063 //\r
3064 // Remove blank space from these string and remove header string "0x"\r
3065 // \r
3066 for (index = 0; index < 11; index ++) {\r
3067 splitStringArray[index] = splitStringArray[index].trim();\r
3068 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
3069 }\r
3070\r
3071 //\r
3072 // Add heading '0' to normalize the string length\r
3073 // \r
3074 for (index = 3; index < 11; index ++) {\r
3075 chLen = splitStringArray[index].length();\r
3076 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
3077 splitStringArray[index] = "0" + splitStringArray[index];\r
3078 }\r
3079 }\r
3080\r
3081 //\r
3082 // construct the final GuidNamingConvention string\r
3083 // \r
3084 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
3085 splitStringArray[0],\r
3086 splitStringArray[1],\r
3087 splitStringArray[2],\r
3088 splitStringArray[3],\r
3089 splitStringArray[4],\r
3090 splitStringArray[5],\r
3091 splitStringArray[6],\r
3092 splitStringArray[7],\r
3093 splitStringArray[8],\r
3094 splitStringArray[9],\r
3095 splitStringArray[10]);\r
3096 uuidString = temp;\r
3097 }\r
3098\r
3099 return UUID.fromString(uuidString);\r
878ddf1f 3100 }\r
3101\r
3102 /**\r
3103 check parameter for this action.\r
3104 \r
3105 @throws EntityException Bad parameter.\r
3106 **/\r
3107 private void checkParameter() throws EntityException {\r
3108 File file = null;\r
3109\r
3110 if((fpdFilePath == null) ||(workspacePath == null)) {\r
3111 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
3112 }\r
3113\r
3114 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r
3115 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
3116 }\r
3117\r
3118 file = new File(workspacePath);\r
3119 if(!file.exists()) {\r
3120 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r
3121 }\r
3122\r
3123 file = new File(fpdFilePath);\r
3124\r
3125 if(!file.exists()) {\r
3126 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r
3127 }\r
3128 }\r
3129\r
3130 /**\r
3131 Test case function\r
3132\r
3133 @param argv parameter from command line\r
3134 **/\r
3135 public static void main(String argv[]) throws EntityException {\r
3136 CollectPCDAction ca = new CollectPCDAction();\r
cd0170f5 3137 ca.setWorkspacePath("m:/tianocore/edk2");\r
3138 ca.setFPDFilePath("m:/tianocore/edk2/EdkNt32Pkg/Nt32.fpd");\r
878ddf1f 3139 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
136adffc 3140// GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
3141// "m:/tianocore/edk2");\r
3142// ca.execute();\r
878ddf1f 3143 }\r
3144}\r