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