]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java
Add new PcdDatabase.java file.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PcdDatabase.java
CommitLineData
241876c7 1/** @file\r
2 PcdDatabase class.\r
3\r
4Copyright (c) 2006, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14package org.tianocore.build.pcd.action;\r
15\r
16import java.io.BufferedReader; \r
17import java.io.File;\r
18import java.io.FileReader;\r
19import java.io.IOException;\r
20import java.math.BigInteger;\r
21import java.util.ArrayList;\r
22import java.util.Comparator;\r
23import java.util.HashMap;\r
24import java.util.Iterator;\r
25import java.util.List;\r
26import java.util.Map;\r
27import java.util.Set;\r
28import java.util.UUID;\r
29import java.util.regex.Matcher;\r
30import java.util.regex.Pattern;\r
31\r
32import org.apache.xmlbeans.XmlException;\r
33import org.apache.xmlbeans.XmlObject;\r
34import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
35import org.tianocore.FrameworkModulesDocument;\r
36import org.tianocore.ModuleSADocument;\r
37import org.tianocore.PcdBuildDefinitionDocument;\r
38import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
39import org.tianocore.PlatformSurfaceAreaDocument;\r
40import org.tianocore.build.fpd.FpdParserTask;\r
41import org.tianocore.build.global.GlobalData;\r
42import org.tianocore.build.id.FpdModuleIdentification;\r
43import org.tianocore.build.id.ModuleIdentification;\r
44import org.tianocore.pcd.action.ActionMessage;\r
45import org.tianocore.pcd.entity.CommonDefinition;\r
46import org.tianocore.pcd.entity.DynamicTokenValue;\r
47import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
48import org.tianocore.pcd.entity.SkuInstance;\r
49import org.tianocore.pcd.entity.Token;\r
50import org.tianocore.pcd.entity.UsageIdentification;\r
51import org.tianocore.pcd.entity.UsageInstance;\r
52import org.tianocore.pcd.exception.EntityException;\r
53\r
54/**\r
55 CStructTypeDeclaration \r
56 \r
57 This class is used to store the declaration string, such as\r
58 "UINT32 PcdPlatformFlashBaseAddress", of \r
59 each memember in the C structure, which is a standard C language\r
60 feature used to implement a simple and efficient database for\r
61 dynamic(ex) type PCD entry.\r
62**/\r
63class CStructTypeDeclaration {\r
64 String key;\r
65 int alignmentSize;\r
66 String cCode;\r
67 boolean initTable;\r
68 \r
69 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {\r
70 this.key = key;\r
71 this.alignmentSize = alignmentSize;\r
72 this.cCode = cCode;\r
73 this.initTable = initTable;\r
74 }\r
75}\r
76\r
77/**\r
78 StringTable \r
79 \r
80 This class is used to store the String in a PCD database.\r
81 \r
82**/\r
83class StringTable {\r
84 private ArrayList<String> al; \r
85 private ArrayList<String> alComments;\r
86 private String phase;\r
87 int len; \r
88\r
89 public StringTable (String phase) {\r
90 this.phase = phase;\r
91 al = new ArrayList<String>();\r
92 alComments = new ArrayList<String>();\r
93 len = 0;\r
94 }\r
95\r
96 public String getSizeMacro () {\r
97 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());\r
98 }\r
99\r
100 private int getSize () {\r
101 //\r
102 // We have at least one Unicode Character in the table.\r
103 //\r
104 return len == 0 ? 1 : len;\r
105 }\r
106\r
107 public String getExistanceMacro () {\r
108 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
109 }\r
110 \r
111 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {\r
112 final String stringTable = "StringTable";\r
113 final String tab = "\t";\r
114 final String newLine = "\r\n";\r
115 final String commaNewLine = ",\r\n";\r
116 \r
117 CStructTypeDeclaration decl;\r
118\r
119 String cDeclCode = "";\r
120 String cInstCode = "";\r
121\r
122 //\r
123 // If we have a empty StringTable\r
124 //\r
125 if (al.size() == 0) {\r
126 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine; \r
127 decl = new CStructTypeDeclaration (\r
128 stringTable,\r
129 2,\r
130 cDeclCode,\r
131 true\r
132 ); \r
133 declaList.add(decl);\r
134\r
135 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";\r
136 instTable.put(stringTable, cInstCode);\r
137 } else {\r
138\r
139 //\r
140 // If there is any String in the StringTable\r
141 //\r
142 for (int i = 0; i < al.size(); i++) {\r
143 String str = al.get(i);\r
144 String stringTableName;\r
145 \r
146 if (i == 0) {\r
147 //\r
148 // StringTable is a well-known name in the PCD DXE driver\r
149 //\r
150 stringTableName = stringTable;\r
151 \r
152 } else {\r
153 stringTableName = String.format("%s_%d", stringTable, i);\r
154 cDeclCode += tab;\r
155 }\r
156 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", \r
157 stringTableName, str.length() + 1, \r
158 alComments.get(i)) \r
159 + newLine;\r
160 \r
161 if (i == 0) {\r
162 cInstCode = "/* StringTable */" + newLine;\r
163 }\r
164 \r
165 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));\r
166 if (i != al.size() - 1) {\r
167 cInstCode += commaNewLine;\r
168 }\r
169 }\r
170 \r
171 decl = new CStructTypeDeclaration (\r
172 stringTable,\r
173 2,\r
174 cDeclCode,\r
175 true\r
176 ); \r
177 declaList.add(decl);\r
178 \r
179 instTable.put(stringTable, cInstCode);\r
180 }\r
181 }\r
182\r
183 public int add (String inputStr, Token token) {\r
184 int i;\r
185 int pos;\r
186\r
187 String str = inputStr;\r
188 \r
189 //\r
190 // The input can be two types:\r
191 // "L\"Bootmode\"" or "Bootmode". \r
192 // We drop the L\" and \" for the first type. \r
193 if (str.startsWith("L\"") && str.endsWith("\"")) {\r
194 str = str.substring(2, str.length() - 1);\r
195 }\r
196 //\r
197 // Check if StringTable has this String already.\r
198 // If so, return the current pos.\r
199 //\r
200 for (i = 0, pos = 0; i < al.size(); i++) {\r
201 String s = al.get(i);;\r
202\r
203 if (str.equals(s)) {\r
204 return pos;\r
205 }\r
206 pos = s.length() + 1;\r
207 }\r
208 \r
209 i = len;\r
210 //\r
211 // Include the NULL character at the end of String\r
212 //\r
213 len += str.length() + 1; \r
214 al.add(str);\r
215 alComments.add(token.getPrimaryKeyString());\r
216\r
217 return i;\r
218 }\r
219}\r
220\r
221/**\r
222 SizeTable \r
223 \r
224 This class is used to store the Size information for\r
225 POINTER TYPE PCD entry in a PCD database.\r
226\r
227**/\r
228class SizeTable {\r
229 private ArrayList<ArrayList<Integer>> al;\r
230 private ArrayList<String> alComments;\r
231 private int len;\r
232 private String phase;\r
233 \r
234 public SizeTable (String phase) {\r
235 al = new ArrayList<ArrayList<Integer>>();\r
236 alComments = new ArrayList<String>();\r
237 len = 0;\r
238 this.phase = phase;\r
239 }\r
240\r
241 public String getSizeMacro () {\r
242 return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());\r
243 }\r
244 \r
245 private int getSize() {\r
246 return len == 0 ? 1 : len;\r
247 }\r
248\r
249 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
250 final String name = "SizeTable";\r
251 \r
252 CStructTypeDeclaration decl;\r
253 String cCode;\r
254\r
255 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase); \r
256 decl = new CStructTypeDeclaration (\r
257 name,\r
258 2,\r
259 cCode,\r
260 true\r
261 ); \r
262 declaList.add(decl);\r
263\r
264\r
265 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
266 instTable.put(name, cCode);\r
267 }\r
268\r
269 private ArrayList<String> getInstantiation () {\r
270 final String comma = ",";\r
271 ArrayList<String> Output = new ArrayList<String>();\r
272\r
273 Output.add("/* SizeTable */");\r
274 Output.add("{");\r
275 if (al.size() == 0) {\r
276 Output.add("\t0");\r
277 } else {\r
278 for (int index = 0; index < al.size(); index++) {\r
279 ArrayList<Integer> ial = al.get(index);\r
280 \r
281 String str = "\t";\r
282 \r
283 for (int index2 = 0; index2 < ial.size(); index2++) {\r
284 str += " " + ial.get(index2).toString();\r
285 if (index2 != ial.size() - 1) {\r
286 str += comma;\r
287 }\r
288 }\r
289\r
290 str += " /* " + alComments.get(index) + " */"; \r
291 \r
292 if (index != (al.size() - 1)) {\r
293 str += comma;\r
294 }\r
295\r
296 Output.add(str);\r
297 \r
298 }\r
299 }\r
300 Output.add("}");\r
301\r
302 return Output;\r
303 }\r
304\r
305 public void add (Token token) {\r
306\r
307 //\r
308 // We only have size information for POINTER type PCD entry.\r
309 //\r
310 if (token.datumType != Token.DATUM_TYPE.POINTER) {\r
311 return;\r
312 }\r
313 \r
314 ArrayList<Integer> ial = token.getPointerTypeSize();\r
315 \r
316 len+= ial.size(); \r
317\r
318 al.add(ial);\r
319 alComments.add(token.getPrimaryKeyString());\r
320\r
321 return;\r
322 }\r
323 \r
324}\r
325\r
326/**\r
327 GuidTable \r
328 \r
329 This class is used to store the GUIDs in a PCD database.\r
330**/\r
331class GuidTable {\r
332 private ArrayList<UUID> al;\r
333 private ArrayList<String> alComments;\r
334 private String phase;\r
335 private int len;\r
336 private int bodyLineNum;\r
337\r
338 public GuidTable (String phase) {\r
339 this.phase = phase;\r
340 al = new ArrayList<UUID>();\r
341 alComments = new ArrayList<String>();\r
342 len = 0;\r
343 bodyLineNum = 0;\r
344 }\r
345\r
346 public String getSizeMacro () {\r
347 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());\r
348 }\r
349\r
350 private int getSize () {\r
351 return (al.size() == 0)? 1 : al.size();\r
352 }\r
353\r
354 public String getExistanceMacro () {\r
355 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
356 }\r
357\r
358 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
359 final String name = "GuidTable";\r
360 \r
361 CStructTypeDeclaration decl;\r
362 String cCode = "";\r
363\r
364 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase); \r
365 decl = new CStructTypeDeclaration (\r
366 name,\r
367 4,\r
368 cCode,\r
369 true\r
370 ); \r
371 declaList.add(decl);\r
372\r
373\r
374 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
375 instTable.put(name, cCode);\r
376 }\r
377\r
378 private String getUuidCString (UUID uuid) {\r
379 String[] guidStrArray;\r
380\r
381 guidStrArray =(uuid.toString()).split("-");\r
382\r
383 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
384 guidStrArray[0],\r
385 guidStrArray[1],\r
386 guidStrArray[2],\r
387 (guidStrArray[3].substring(0, 2)),\r
388 (guidStrArray[3].substring(2, 4)),\r
389 (guidStrArray[4].substring(0, 2)),\r
390 (guidStrArray[4].substring(2, 4)),\r
391 (guidStrArray[4].substring(4, 6)),\r
392 (guidStrArray[4].substring(6, 8)),\r
393 (guidStrArray[4].substring(8, 10)),\r
394 (guidStrArray[4].substring(10, 12))\r
395 );\r
396 }\r
397\r
398 private ArrayList<String> getInstantiation () {\r
399 ArrayList<String> Output = new ArrayList<String>();\r
400\r
401 Output.add("/* GuidTable */");\r
402 Output.add("{");\r
403\r
404 if (al.size() == 0) {\r
405 Output.add("\t" + getUuidCString(new UUID(0, 0)));\r
406 }\r
407 \r
408 for (int i = 0; i < al.size(); i++) {\r
409 String str = "\t" + getUuidCString(al.get(i));\r
410\r
411 str += "/* " + alComments.get(i) + " */";\r
412 if (i != (al.size() - 1)) {\r
413 str += ",";\r
414 }\r
415 Output.add(str);\r
416 bodyLineNum++;\r
417\r
418 }\r
419 Output.add("}");\r
420\r
421 return Output;\r
422 }\r
423\r
424 public int add (UUID uuid, String name) {\r
425 //\r
426 // Check if GuidTable has this entry already.\r
427 // If so, return the GuidTable index.\r
428 //\r
429 for (int i = 0; i < al.size(); i++) {\r
430 if (al.get(i).compareTo(uuid) == 0) {\r
431 return i;\r
432 }\r
433 }\r
434 \r
435 len++; \r
436 al.add(uuid);\r
437 alComments.add(name);\r
438\r
439 //\r
440 // Return the previous Table Index\r
441 //\r
442 return len - 1;\r
443 }\r
444\r
445}\r
446\r
447/**\r
448 SkuIdTable \r
449 \r
450 This class is used to store the SKU IDs in a PCD database.\r
451\r
452**/\r
453class SkuIdTable {\r
454 private ArrayList<Integer[]> al;\r
455 private ArrayList<String> alComment;\r
456 private String phase;\r
457 private int len;\r
458\r
459 public SkuIdTable (String phase) {\r
460 this.phase = phase;\r
461 al = new ArrayList<Integer[]>();\r
462 alComment = new ArrayList<String>();\r
463 len = 0;\r
464 }\r
465\r
466 public String getSizeMacro () {\r
467 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());\r
468 }\r
469\r
470 private int getSize () {\r
471 return (len == 0)? 1 : len;\r
472 }\r
473\r
474 public String getExistanceMacro () {\r
475 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
476 }\r
477\r
478 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
479 final String name = "SkuIdTable";\r
480 \r
481 CStructTypeDeclaration decl;\r
482 String cCode = "";\r
483\r
484 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase); \r
485 decl = new CStructTypeDeclaration (\r
486 name,\r
487 1,\r
488 cCode,\r
489 true\r
490 ); \r
491 declaList.add(decl);\r
492\r
493\r
494 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
495 instTable.put(name, cCode);\r
496\r
497 //\r
498 // SystemSkuId is in PEI phase PCD Database\r
499 //\r
500 if (phase.equalsIgnoreCase("PEI")) {\r
501 decl = new CStructTypeDeclaration (\r
502 "SystemSkuId",\r
503 1,\r
504 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),\r
505 true\r
506 );\r
507 declaList.add(decl);\r
508 \r
509 instTable.put("SystemSkuId", "0");\r
510 }\r
511\r
512 }\r
513\r
514 private ArrayList<String> getInstantiation () {\r
515 ArrayList<String> Output = new ArrayList<String> ();\r
516\r
517 Output.add("/* SkuIdTable */");\r
518 Output.add("{");\r
519\r
520 if (al.size() == 0) {\r
521 Output.add("\t0");\r
522 }\r
523 \r
524 for (int index = 0; index < al.size(); index++) {\r
525 String str;\r
526\r
527 str = "/* " + alComment.get(index) + "*/ ";\r
528 str += "/* MaxSku */ ";\r
529\r
530\r
531 Integer[] ia = al.get(index);\r
532\r
533 str += "\t" + ia[0].toString() + ", ";\r
534 for (int index2 = 1; index2 < ia.length; index2++) {\r
535 str += ia[index2].toString();\r
536 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {\r
537 str += ", ";\r
538 }\r
539 }\r
540\r
541 Output.add(str);\r
542\r
543 }\r
544\r
545 Output.add("}");\r
546\r
547 return Output;\r
548 }\r
549\r
550 public int add (Token token) {\r
551\r
552 int index;\r
553 int pos;\r
554 \r
555 //\r
556 // Check if this SKU_ID Array is already in the table\r
557 //\r
558 pos = 0;\r
559 for (Object o: al) {\r
560 Integer [] s = (Integer[]) o;\r
561 boolean different = false;\r
562 if (s[0] == token.getSkuIdCount()) {\r
563 for (index = 1; index < s.length; index++) {\r
564 if (s[index] != token.skuData.get(index-1).id) {\r
565 different = true;\r
566 break;\r
567 }\r
568 }\r
569 } else {\r
570 different = true;\r
571 }\r
572 if (different) {\r
573 pos += s[0] + 1;\r
574 } else {\r
575 return pos;\r
576 }\r
577 }\r
578\r
579 Integer [] skuIds = new Integer[token.skuData.size() + 1];\r
580 skuIds[0] = new Integer(token.skuData.size());\r
581 for (index = 1; index < skuIds.length; index++) {\r
582 skuIds[index] = new Integer(token.skuData.get(index - 1).id);\r
583 }\r
584\r
585 index = len;\r
586\r
587 len += skuIds.length; \r
588 al.add(skuIds);\r
589 alComment.add(token.getPrimaryKeyString());\r
590\r
591 return index;\r
592 }\r
593\r
594}\r
595\r
596class LocalTokenNumberTable {\r
597 private ArrayList<String> al;\r
598 private ArrayList<String> alComment;\r
599 private String phase;\r
600 private int len;\r
601\r
602 public LocalTokenNumberTable (String phase) {\r
603 this.phase = phase;\r
604 al = new ArrayList<String>();\r
605 alComment = new ArrayList<String>();\r
606\r
607 len = 0;\r
608 }\r
609\r
610 public String getSizeMacro () {\r
611 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())\r
612 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());\r
613 }\r
614\r
615 public int getSize () {\r
616 return (al.size() == 0)? 1 : al.size();\r
617 }\r
618\r
619 public String getExistanceMacro () {\r
620 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
621 }\r
622\r
623 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
624 final String name = "LocalTokenNumberTable";\r
625 \r
626 CStructTypeDeclaration decl;\r
627 String cCode = "";\r
628\r
629 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase); \r
630 decl = new CStructTypeDeclaration (\r
631 name,\r
632 4,\r
633 cCode,\r
634 true\r
635 ); \r
636 declaList.add(decl);\r
637\r
638 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
639 instTable.put(name, cCode);\r
640 }\r
641\r
642 private ArrayList<String> getInstantiation () {\r
643 ArrayList<String> output = new ArrayList<String>();\r
644\r
645 output.add("/* LocalTokenNumberTable */");\r
646 output.add("{");\r
647\r
648 if (al.size() == 0) {\r
649 output.add("\t0");\r
650 }\r
651 \r
652 for (int index = 0; index < al.size(); index++) {\r
653 String str;\r
654\r
655 str = "\t" + (String)al.get(index);\r
656\r
657 str += " /* " + alComment.get(index) + " */ ";\r
658\r
659\r
660 if (index != (al.size() - 1)) {\r
661 str += ",";\r
662 }\r
663\r
664 output.add(str);\r
665\r
666 }\r
667\r
668 output.add("}");\r
669\r
670 return output;\r
671 }\r
672\r
673 public int add (Token token) {\r
674 int index = len;\r
675 String str;\r
676\r
677 len++; \r
678\r
679 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());\r
680\r
681 if (token.isUnicodeStringType()) {\r
682 str += " | PCD_TYPE_STRING";\r
683 }\r
684\r
685 if (token.isSkuEnable()) {\r
686 str += " | PCD_TYPE_SKU_ENABLED";\r
687 }\r
688\r
689 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
690 str += " | PCD_TYPE_HII";\r
691 }\r
692\r
693 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
694 str += " | PCD_TYPE_VPD";\r
695 }\r
696 \r
697 switch (token.datumType) {\r
698 case UINT8:\r
699 case BOOLEAN:\r
700 str += " | PCD_DATUM_TYPE_UINT8";\r
701 break;\r
702 case UINT16:\r
703 str += " | PCD_DATUM_TYPE_UINT16";\r
704 break;\r
705 case UINT32:\r
706 str += " | PCD_DATUM_TYPE_UINT32";\r
707 break;\r
708 case UINT64:\r
709 str += " | PCD_DATUM_TYPE_UINT64";\r
710 break;\r
711 case POINTER:\r
712 str += " | PCD_DATUM_TYPE_POINTER";\r
713 break;\r
714 }\r
715 \r
716 al.add(str);\r
717 alComment.add(token.getPrimaryKeyString());\r
718\r
719 return index;\r
720 }\r
721}\r
722\r
723/**\r
724 ExMapTable \r
725 \r
726 This class is used to store the table of mapping information\r
727 between DynamicEX ID pair(Guid, TokenNumber) and\r
728 the local token number assigned by PcdDatabase class.\r
729**/\r
730class ExMapTable {\r
731\r
732 /**\r
733 ExTriplet \r
734 \r
735 This class is used to store the mapping information\r
736 between DynamicEX ID pair(Guid, TokenNumber) and\r
737 the local token number assigned by PcdDatabase class.\r
738 **/\r
739 class ExTriplet {\r
740 public Integer guidTableIdx;\r
741 public Long exTokenNumber;\r
742 public Long localTokenIdx;\r
743 \r
744 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {\r
745 this.guidTableIdx = new Integer(guidTableIdx);\r
746 this.exTokenNumber = new Long(exTokenNumber);\r
747 this.localTokenIdx = new Long(localTokenIdx);\r
748 }\r
749 }\r
750\r
751 private ArrayList<ExTriplet> al;\r
752 private Map<ExTriplet, String> alComment;\r
753 private String phase;\r
754 private int len;\r
755 private int bodyLineNum;\r
756 \r
757 public ExMapTable (String phase) {\r
758 this.phase = phase;\r
759 al = new ArrayList<ExTriplet>();\r
760 alComment = new HashMap<ExTriplet, String>();\r
761 bodyLineNum = 0;\r
762 len = 0;\r
763 }\r
764\r
765 public String getSizeMacro () {\r
766 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())\r
767 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());\r
768 }\r
769\r
770 public String getExistanceMacro () {\r
771 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
772 }\r
773\r
774 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
775 final String exMapTableName = "ExMapTable";\r
776 \r
777 sortTable();\r
778 \r
779 CStructTypeDeclaration decl;\r
780 String cCode = "";\r
781\r
782 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase); \r
783 decl = new CStructTypeDeclaration (\r
784 exMapTableName,\r
785 4,\r
786 cCode,\r
787 true\r
788 ); \r
789 declaList.add(decl);\r
790\r
791\r
792 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
793 instTable.put(exMapTableName, cCode);\r
794 }\r
795 \r
796 private ArrayList<String> getInstantiation () {\r
797 ArrayList<String> Output = new ArrayList<String>();\r
798\r
799 Output.add("/* ExMapTable */");\r
800 Output.add("{");\r
801 if (al.size() == 0) {\r
802 Output.add("\t{0, 0, 0}");\r
803 }\r
804 \r
805 int index;\r
806 for (index = 0; index < al.size(); index++) {\r
807 String str;\r
808\r
809 ExTriplet e = (ExTriplet)al.get(index);\r
810\r
811 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";\r
812 str += e.localTokenIdx.toString() + ", ";\r
813 str += e.guidTableIdx.toString();\r
814\r
815 str += "}" + " /* " + alComment.get(e) + " */" ;\r
816\r
817 if (index != al.size() - 1) {\r
818 str += ",";\r
819 }\r
820\r
821 Output.add(str);\r
822 bodyLineNum++;\r
823\r
824 }\r
825\r
826 Output.add("}");\r
827\r
828 return Output;\r
829 }\r
830\r
831 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {\r
832 int index = len;\r
833\r
834 len++;\r
835 ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx); \r
836\r
837 al.add(et);\r
838 alComment.put(et, name);\r
839\r
840 return index;\r
841 }\r
842\r
843 private int getTableLen () {\r
844 return al.size() == 0 ? 1 : al.size();\r
845 }\r
846\r
847 //\r
848 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in\r
849 // PCD PEIM/Driver, we need to sort the ExMapTable according to the\r
850 // following order:\r
851 // 1) ExGuid\r
852 // 2) ExTokenNumber\r
853 // \r
854 class ExTripletComp implements Comparator<ExTriplet> {\r
855 public int compare (ExTriplet a, ExTriplet b) {\r
856 if (a.guidTableIdx == b.guidTableIdx ) {\r
857 //\r
858 // exTokenNumber is long, we can't use simple substraction.\r
859 //\r
860 if (a.exTokenNumber > b.exTokenNumber) {\r
861 return 1;\r
862 } else if (a.exTokenNumber == b.exTokenNumber) {\r
863 return 0;\r
864 } else {\r
865 return -1;\r
866 }\r
867 }\r
868 \r
869 return a.guidTableIdx - b.guidTableIdx;\r
870 }\r
871 }\r
872\r
873 private void sortTable () {\r
874 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();\r
875 java.util.Collections.sort(al, comparator);\r
876 }\r
877}\r
878\r
879/**\r
880 PcdDatabase \r
881 \r
882 This class is used to generate C code for Autogen.h and Autogen.c of\r
883 a PCD service DXE driver and PCD service PEIM.\r
884**/\r
885public class PcdDatabase {\r
886\r
887 private final static int SkuHeadAlignmentSize = 4;\r
888 private final String newLine = "\r\n";\r
889 private final String commaNewLine = ",\r\n";\r
890 private final String tab = "\t";\r
891 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
892 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
893 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
894 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
895 public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";\r
896 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
897\r
898\r
899 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";\r
900 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";\r
901 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n"; \r
902 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";\r
903 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";\r
904 public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";\r
905 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";\r
906 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";\r
907\r
908\r
909 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n"; \r
910 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";\r
911 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";\r
912 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";\r
913 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";\r
914\r
915 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";\r
916 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";\r
917 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";\r
918 \r
919 private final static String skuDataTableTemplate = "SkuDataTable";\r
920\r
921\r
922 private StringTable stringTable;\r
923 private GuidTable guidTable;\r
924 private LocalTokenNumberTable localTokenNumberTable;\r
925 private SkuIdTable skuIdTable;\r
926 private SizeTable sizeTable;\r
927 private ExMapTable exMapTable;\r
928\r
929 private ArrayList<Token> alTokens;\r
930 private String phase;\r
931 private int assignedTokenNumber;\r
932 \r
933 //\r
934 // Use two class global variable to store\r
935 // temperary \r
936 //\r
937 private String privateGlobalName;\r
938 private String privateGlobalCCode;\r
939 //\r
940 // After Major changes done to the PCD\r
941 // database generation class PcdDatabase\r
942 // Please increment the version and please\r
943 // also update the version number in PCD\r
944 // service PEIM and DXE driver accordingly.\r
945 //\r
946 private final int version = 2;\r
947\r
948 private String hString;\r
949 private String cString;\r
950\r
951 /**\r
952 Constructor for PcdDatabase class. \r
953 \r
954 <p>We have two PCD dynamic(ex) database for the Framework implementation. One\r
955 for PEI phase and the other for DXE phase. </p>\r
956 \r
957 @param alTokens A ArrayList of Dynamic(EX) PCD entry.\r
958 @param exePhase The phase to generate PCD database for: valid input\r
959 is "PEI" or "DXE".\r
960 @param startLen The starting Local Token Number for the PCD database. For\r
961 PEI phase, the starting Local Token Number starts from 0.\r
962 For DXE phase, the starting Local Token Number starts\r
963 from the total number of PCD entry of PEI phase.\r
964 @return void\r
965 **/\r
966 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {\r
967 phase = exePhase;\r
968\r
969 stringTable = new StringTable(phase);\r
970 guidTable = new GuidTable(phase);\r
971 localTokenNumberTable = new LocalTokenNumberTable(phase);\r
972 skuIdTable = new SkuIdTable(phase);\r
973 sizeTable = new SizeTable(phase);\r
974 exMapTable = new ExMapTable(phase); \r
975\r
976 //\r
977 // Local token number 0 is reserved for INVALID_TOKEN_NUMBER.\r
978 // So we will increment 1 for the startLen passed from the \r
979 // constructor.\r
980 //\r
981 assignedTokenNumber = startLen + 1;\r
982 this.alTokens = alTokens;\r
983 }\r
984\r
985 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {\r
986 for (int i = 0; i < alTokens.size(); i++) {\r
987 Token t = (Token)alTokens.get(i);\r
988 if (t.isDynamicEx()) {\r
989 exTokens.add(t);\r
990 } else {\r
991 nexTokens.add(t);\r
992 }\r
993 }\r
994\r
995 return;\r
996 }\r
997\r
998 private int getDataTypeAlignmentSize (Token token) {\r
999 switch (token.datumType) {\r
1000 case UINT8:\r
1001 return 1;\r
1002 case UINT16:\r
1003 return 2;\r
1004 case UINT32:\r
1005 return 4;\r
1006 case UINT64:\r
1007 return 8;\r
1008 case POINTER:\r
1009 return 1;\r
1010 case BOOLEAN:\r
1011 return 1;\r
1012 default:\r
1013 return 1;\r
1014 }\r
1015 }\r
1016 \r
1017 private int getHiiPtrTypeAlignmentSize(Token token) {\r
1018 switch (token.datumType) {\r
1019 case UINT8:\r
1020 return 1;\r
1021 case UINT16:\r
1022 return 2;\r
1023 case UINT32:\r
1024 return 4;\r
1025 case UINT64:\r
1026 return 8;\r
1027 case POINTER:\r
1028 if (token.isHiiEnable()) {\r
1029 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1030 return 2;\r
1031 }\r
1032 }\r
1033 return 1;\r
1034 case BOOLEAN:\r
1035 return 1;\r
1036 default:\r
1037 return 1;\r
1038 }\r
1039 }\r
1040 \r
1041 private int getAlignmentSize (Token token) {\r
1042 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
1043 return 2;\r
1044 }\r
1045\r
1046 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
1047 return 4;\r
1048 }\r
1049\r
1050 if (token.isUnicodeStringType()) {\r
1051 return 2;\r
1052 }\r
1053 \r
1054 return getDataTypeAlignmentSize(token);\r
1055 }\r
1056\r
1057 public String getCString () {\r
1058 return cString;\r
1059 }\r
1060\r
1061 public String getHString () {\r
1062 return hString;\r
1063 }\r
1064 \r
1065 private void genCodeWorker(Token t,\r
1066 ArrayList<CStructTypeDeclaration> declaList,\r
1067 HashMap<String, String> instTable, String phase)\r
1068 throws EntityException {\r
1069\r
1070 CStructTypeDeclaration decl;\r
1071\r
1072 //\r
1073 // Insert SKU_HEAD if isSkuEnable is true\r
1074 //\r
1075 if (t.isSkuEnable()) {\r
1076 int tableIdx;\r
1077 tableIdx = skuIdTable.add(t);\r
1078 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
1079 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
1080 declaList.add(decl);\r
1081 instTable.put(t.getPrimaryKeyString(),\r
1082 getSkuEnabledTypeInstantiaion(t, tableIdx));\r
1083 }\r
1084\r
1085 //\r
1086 // Insert PCD_ENTRY declaration and instantiation\r
1087 //\r
1088 getCDeclarationString(t);\r
1089\r
1090 decl = new CStructTypeDeclaration(privateGlobalName,\r
1091 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
1092 declaList.add(decl);\r
1093\r
1094 if (t.hasDefaultValue()) {\r
1095 instTable.put(privateGlobalName, \r
1096 getTypeInstantiation(t, declaList, instTable, phase)\r
1097 );\r
1098 }\r
1099\r
1100 }\r
1101\r
1102 private void ProcessTokens (List<Token> tokens, \r
1103 ArrayList<CStructTypeDeclaration> cStructDeclList,\r
1104 HashMap<String, String> cStructInstTable,\r
1105 String phase\r
1106 ) \r
1107 throws EntityException {\r
1108 \r
1109 for (int idx = 0; idx < tokens.size(); idx++) {\r
1110 Token t = tokens.get(idx);\r
1111 \r
1112 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
1113 \r
1114 sizeTable.add(t);\r
1115 localTokenNumberTable.add(t);\r
1116 t.tokenNumber = assignedTokenNumber++;\r
1117 \r
1118 //\r
1119 // Add a mapping if this dynamic PCD entry is a EX type\r
1120 //\r
1121 if (t.isDynamicEx()) {\r
1122 exMapTable.add((int)t.tokenNumber, \r
1123 t.dynamicExTokenNumber, \r
1124 guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()), \r
1125 t.getPrimaryKeyString()\r
1126 );\r
1127 }\r
1128 }\r
1129\r
1130 }\r
1131 \r
1132 public void genCode () throws EntityException {\r
1133 \r
1134 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
1135 HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
1136 \r
1137 List<Token> nexTokens = new ArrayList<Token> ();\r
1138 List<Token> exTokens = new ArrayList<Token> ();\r
1139\r
1140 getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
1141\r
1142 //\r
1143 // We have to process Non-Ex type PCD entry first. The reason is\r
1144 // that our optimization assumes that the Token Number of Non-Ex \r
1145 // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
1146 // \r
1147 // EX type token number starts from the last Non-EX PCD entry and\r
1148 // grows continously upwards.\r
1149 //\r
1150 ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);\r
1151 ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);\r
1152 \r
1153 stringTable.genCode(cStructDeclList, cStructInstTable);\r
1154 skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1155 exMapTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1156 localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1157 sizeTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1158 guidTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1159 \r
1160 hString = genCMacroCode ();\r
1161 \r
1162 HashMap <String, String> result;\r
1163 \r
1164 result = genCStructCode(cStructDeclList, \r
1165 cStructInstTable, \r
1166 phase\r
1167 );\r
1168 \r
1169 hString += result.get("initDeclStr");\r
1170 hString += result.get("uninitDeclStr");\r
1171 \r
1172 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
1173 \r
1174 cString = newLine + newLine + result.get("initInstStr");\r
1175 \r
1176 }\r
1177 \r
1178 private String genCMacroCode () {\r
1179 String macroStr = "";\r
1180\r
1181 //\r
1182 // Generate size info Macro for all Tables\r
1183 //\r
1184 macroStr += guidTable.getSizeMacro();\r
1185 macroStr += stringTable.getSizeMacro();\r
1186 macroStr += skuIdTable.getSizeMacro();\r
1187 macroStr += localTokenNumberTable.getSizeMacro();\r
1188 macroStr += exMapTable.getSizeMacro();\r
1189 macroStr += sizeTable.getSizeMacro();\r
1190\r
1191 //\r
1192 // Generate existance info Macro for all Tables\r
1193 //\r
1194 macroStr += guidTable.getExistanceMacro();\r
1195 macroStr += stringTable.getExistanceMacro();\r
1196 macroStr += skuIdTable.getExistanceMacro();\r
1197 macroStr += localTokenNumberTable.getExistanceMacro();\r
1198 macroStr += exMapTable.getExistanceMacro();\r
1199\r
1200 macroStr += newLine;\r
1201 \r
1202 return macroStr;\r
1203 }\r
1204 \r
1205 private HashMap <String, String> genCStructCode(\r
1206 ArrayList<CStructTypeDeclaration> declaList, \r
1207 HashMap<String, String> instTable, \r
1208 String phase\r
1209 ) {\r
1210 \r
1211 int i;\r
1212 HashMap <String, String> result = new HashMap<String, String>();\r
1213 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
1214 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
1215 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
1216 \r
1217 //\r
1218 // Initialize the storage for each alignment\r
1219 //\r
1220 for (i = 8; i > 0; i>>=1) {\r
1221 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
1222 alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
1223 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
1224 }\r
1225 \r
1226 String initDeclStr = "typedef struct {" + newLine;\r
1227 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
1228 String uninitDeclStr = "typedef struct {" + newLine;\r
1229\r
1230 //\r
1231 // Sort all C declaration and instantiation base on Alignment Size \r
1232 //\r
1233 for (Object d : declaList) {\r
1234 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
1235 \r
1236 if (decl.initTable) {\r
1237 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1238 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
1239 } else {\r
1240 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1241 }\r
1242 }\r
1243\r
1244 //\r
1245 // Generate code for every alignment size\r
1246 //\r
1247 boolean uinitDatabaseEmpty = true;\r
1248 for (int align = 8; align > 0; align >>= 1) {\r
1249 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
1250 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
1251 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
1252 initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
1253 initInstStr += tab + instListBasedOnAlignment.get(i);\r
1254 \r
1255 //\r
1256 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
1257 // has a least one data memember with alignment size of 1. So we can\r
1258 // remove the last "," in the C structure instantiation string. Luckily,\r
1259 // this is true as both data structure has SKUID_TABLE anyway.\r
1260 //\r
1261 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
1262 initInstStr += newLine;\r
1263 } else {\r
1264 initInstStr += commaNewLine;\r
1265 }\r
1266 }\r
1267 \r
1268 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
1269 \r
1270 if (declaListBasedOnAlignment.size() != 0) {\r
1271 uinitDatabaseEmpty = false;\r
1272 }\r
1273 \r
1274 for (Object d : declaListBasedOnAlignment) {\r
1275 String s = (String)d;\r
1276 uninitDeclStr += tab + s;\r
1277 }\r
1278 }\r
1279 \r
1280 if (uinitDatabaseEmpty) {\r
1281 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
1282 }\r
1283 \r
1284 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
1285 initInstStr += "};" + newLine;\r
1286 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
1287 \r
1288 result.put("initDeclStr", initDeclStr);\r
1289 result.put("initInstStr", initInstStr);\r
1290 result.put("uninitDeclStr", uninitDeclStr);\r
1291\r
1292 return result;\r
1293 }\r
1294\r
1295 public static String genInstantiationStr (ArrayList<String> alStr) {\r
1296 String str = "";\r
1297 for (int i = 0; i< alStr.size(); i++) {\r
1298 if (i != 0) {\r
1299 str += "\t";\r
1300 }\r
1301 str += alStr.get(i);\r
1302 if (i != alStr.size() - 1) {\r
1303 str += "\r\n";\r
1304 }\r
1305 }\r
1306\r
1307 return str;\r
1308 }\r
1309\r
1310 private String getSkuEnabledTypeDeclaration (Token token) {\r
1311 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
1312 }\r
1313\r
1314 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
1315\r
1316 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
1317 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
1318 }\r
1319\r
1320 private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {\r
1321 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
1322 }\r
1323\r
1324 private String getCType (Token t) \r
1325 throws EntityException {\r
1326 \r
1327 if (t.isHiiEnable()) {\r
1328 return "VARIABLE_HEAD";\r
1329 }\r
1330 \r
1331 if (t.isVpdEnable()) {\r
1332 return "VPD_HEAD";\r
1333 }\r
1334 \r
1335 if (t.isUnicodeStringType()) {\r
1336 return "STRING_HEAD";\r
1337 }\r
1338 \r
1339 switch (t.datumType) {\r
1340 case UINT64:\r
1341 return "UINT64";\r
1342 case UINT32:\r
1343 return "UINT32";\r
1344 case UINT16:\r
1345 return "UINT16";\r
1346 case UINT8:\r
1347 return "UINT8";\r
1348 case BOOLEAN:\r
1349 return "BOOLEAN";\r
1350 case POINTER:\r
1351 return "UINT8";\r
1352 default:\r
1353 throw new EntityException("Unknown type in getDataTypeCDeclaration");\r
1354 }\r
1355 }\r
1356 \r
1357 //\r
1358 // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString\r
1359 //\r
1360 private void getCDeclarationString(Token t) \r
1361 throws EntityException {\r
1362 \r
1363 if (t.isSkuEnable()) {\r
1364 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
1365 } else {\r
1366 privateGlobalName = t.getPrimaryKeyString();\r
1367 }\r
1368\r
1369 String type = getCType(t);\r
1370 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {\r
1371 int bufferSize;\r
1372 if (t.isASCIIStringType()) {\r
1373 //\r
1374 // Build tool will add a NULL string at the end of the ASCII string\r
1375 //\r
1376 bufferSize = t.datumSize + 1;\r
1377 } else {\r
1378 bufferSize = t.datumSize;\r
1379 }\r
1380 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
1381 } else {\r
1382 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
1383 }\r
1384 }\r
1385 \r
1386 private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId) \r
1387 throws EntityException {\r
1388\r
1389 String typeStr;\r
1390\r
1391 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1392 typeStr = "UINT8";\r
1393 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1394 typeStr = "UINT16";\r
1395 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1396 typeStr = "UINT32";\r
1397 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1398 typeStr = "UINT64";\r
1399 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1400 typeStr = "BOOLEAN";\r
1401 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
1402 int size;\r
1403 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1404 typeStr = "UINT16";\r
1405 //\r
1406 // Include the NULL charactor\r
1407 //\r
1408 size = token.datumSize / 2 + 1;\r
1409 } else {\r
1410 typeStr = "UINT8";\r
1411 if (token.isHiiDefaultValueASCIIStringType()) {\r
1412 //\r
1413 // Include the NULL charactor\r
1414 //\r
1415 size = token.datumSize + 1;\r
1416 } else {\r
1417 size = token.datumSize;\r
1418 }\r
1419 }\r
1420 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
1421 } else {\r
1422 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
1423 }\r
1424\r
1425 return String.format("%-20s%s;\r\n", typeStr, cName);\r
1426 }\r
1427 \r
1428 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
1429 \r
1430 int i;\r
1431\r
1432 String s;\r
1433 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
1434 s += tab + "{" + newLine;\r
1435\r
1436 for (i = 0; i < t.skuData.size(); i++) {\r
1437 if (t.isUnicodeStringType()) {\r
1438 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
1439 } else if (t.isHiiEnable()) {\r
1440 /* VPD_HEAD definition\r
1441 typedef struct {\r
1442 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r
1443 UINT16 StringIndex; // Offset in String Table in units of UINT16.\r
1444 UINT16 Offset; // Offset in Variable\r
1445 UINT16 DefaultValueOffset; // Offset of the Default Value\r
1446 } VARIABLE_HEAD ;\r
1447 */\r
1448 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i); \r
1449 \r
1450 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
1451 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
1452 t.skuData.get(i).value.variableOffset,\r
1453 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
1454 );\r
1455 //\r
1456 // We need to support the default value, so we add the declaration and\r
1457 // the instantiation for the default value.\r
1458 //\r
1459 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
1460 getHiiPtrTypeAlignmentSize(t),\r
1461 getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),\r
1462 true\r
1463 ); \r
1464 declaList.add(decl);\r
1465 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));\r
1466 } else if (t.isVpdEnable()) {\r
1467 /* typedef struct {\r
1468 UINT32 Offset;\r
1469 } VPD_HEAD;\r
1470 */\r
1471 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
1472 } else {\r
1473 if (t.isByteStreamType()) {\r
1474 //\r
1475 // Byte stream type input has their own "{" "}", so we won't help to insert.\r
1476 //\r
1477 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
1478 } else {\r
1479 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
1480 }\r
1481 }\r
1482 \r
1483 if (i != t.skuData.size() - 1) {\r
1484 s += commaNewLine;\r
1485 } else {\r
1486 s += newLine;\r
1487 }\r
1488\r
1489 }\r
1490 \r
1491 s += tab + "}";\r
1492 \r
1493 return s;\r
1494 }\r
1495 \r
1496 public static String getPcdDatabaseCommonDefinitions () \r
1497 throws EntityException {\r
1498\r
1499 String retStr = "";\r
1500 try {\r
1501 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1502 "Tools" + File.separator + \r
1503 "Conf" + File.separator +\r
1504 "Pcd" + File.separator +\r
1505 "PcdDatabaseCommonDefinitions.sample");\r
1506 FileReader reader = new FileReader(file);\r
1507 BufferedReader in = new BufferedReader(reader);\r
1508 String str;\r
1509 while ((str = in.readLine()) != null) {\r
1510 retStr = retStr +"\r\n" + str;\r
1511 }\r
1512 } catch (Exception ex) {\r
1513 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");\r
1514 }\r
1515\r
1516 return retStr;\r
1517 }\r
1518\r
1519 public static String getPcdDxeDatabaseDefinitions () \r
1520 throws EntityException {\r
1521\r
1522 String retStr = "";\r
1523 try {\r
1524 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1525 "Tools" + File.separator + \r
1526 "Conf" + File.separator +\r
1527 "Pcd" + File.separator +\r
1528 "PcdDatabaseDxeDefinitions.sample");\r
1529 FileReader reader = new FileReader(file);\r
1530 BufferedReader in = new BufferedReader(reader);\r
1531 String str;\r
1532 while ((str = in.readLine()) != null) {\r
1533 retStr = retStr +"\r\n" + str;\r
1534 }\r
1535 } catch (Exception ex) {\r
1536 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");\r
1537 }\r
1538\r
1539 return retStr;\r
1540 }\r
1541\r
1542 public static String getPcdPeiDatabaseDefinitions () \r
1543 throws EntityException {\r
1544\r
1545 String retStr = "";\r
1546 try {\r
1547 File file = new File(GlobalData.getWorkspacePath() + File.separator + \r
1548 "Tools" + File.separator + \r
1549 "Conf" + File.separator +\r
1550 "Pcd" + File.separator +\r
1551 "PcdDatabasePeiDefinitions.sample");\r
1552 FileReader reader = new FileReader(file);\r
1553 BufferedReader in = new BufferedReader(reader);\r
1554 String str;\r
1555 while ((str = in.readLine()) != null) {\r
1556 retStr = retStr +"\r\n" + str;\r
1557 }\r
1558 } catch (Exception ex) {\r
1559 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");\r
1560 }\r
1561\r
1562 return retStr;\r
1563 }\r
1564\r
1565 /**\r
1566 Translate the schema string to UUID instance.\r
1567 \r
1568 In schema, the string of UUID is defined as following two types string:\r
1569 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
1570 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
1571 \r
1572 2) GuidNamingConvention: pattern =\r
1573 [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
1574 \r
1575 This function will convert string and create uuid instance.\r
1576 \r
1577 @param uuidString UUID string in XML file\r
1578 \r
1579 @return UUID UUID instance\r
1580 **/\r
1581 private UUID translateSchemaStringToUUID(String uuidString) \r
1582 throws EntityException {\r
1583 String temp;\r
1584 String[] splitStringArray;\r
1585 int index;\r
1586 int chIndex;\r
1587 int chLen;\r
1588\r
1589 if (uuidString == null) {\r
1590 return null;\r
1591 }\r
1592\r
1593 if (uuidString.length() == 0) {\r
1594 return null;\r
1595 }\r
1596\r
1597 if (uuidString.equals("0") ||\r
1598 uuidString.equalsIgnoreCase("0x0")) {\r
1599 return new UUID(0, 0);\r
1600 }\r
1601\r
1602 uuidString = uuidString.replaceAll("\\{", "");\r
1603 uuidString = uuidString.replaceAll("\\}", "");\r
1604\r
1605 //\r
1606 // If the UUID schema string is GuidArrayType type then need translate \r
1607 // to GuidNamingConvention type at first.\r
1608 // \r
1609 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
1610 splitStringArray = uuidString.split("," );\r
1611 if (splitStringArray.length != 11) {\r
1612 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
1613 }\r
1614\r
1615 //\r
1616 // Remove blank space from these string and remove header string "0x"\r
1617 // \r
1618 for (index = 0; index < 11; index ++) {\r
1619 splitStringArray[index] = splitStringArray[index].trim();\r
1620 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
1621 }\r
1622\r
1623 //\r
1624 // Add heading '0' to normalize the string length\r
1625 // \r
1626 for (index = 3; index < 11; index ++) {\r
1627 chLen = splitStringArray[index].length();\r
1628 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
1629 splitStringArray[index] = "0" + splitStringArray[index];\r
1630 }\r
1631 }\r
1632\r
1633 //\r
1634 // construct the final GuidNamingConvention string\r
1635 // \r
1636 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
1637 splitStringArray[0],\r
1638 splitStringArray[1],\r
1639 splitStringArray[2],\r
1640 splitStringArray[3],\r
1641 splitStringArray[4],\r
1642 splitStringArray[5],\r
1643 splitStringArray[6],\r
1644 splitStringArray[7],\r
1645 splitStringArray[8],\r
1646 splitStringArray[9],\r
1647 splitStringArray[10]);\r
1648 uuidString = temp;\r
1649 }\r
1650\r
1651 return UUID.fromString(uuidString);\r
1652 }\r
1653}