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