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