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