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