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