]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
1) correct the assert condition for LibPcdSetPtr and LibPcdSetExPtr
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
1 /** @file
2 CollectPCDAction class.
3
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.
5 This class will be used for wizard and build tools, So it can *not* inherit
6 from buildAction or wizardAction.
7
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18 package org.tianocore.build.pcd.action;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.math.BigInteger;
25 import java.util.ArrayList;
26 import java.util.Comparator;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.UUID;
30
31 import org.apache.xmlbeans.XmlException;
32 import org.apache.xmlbeans.XmlObject;
33 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;
34 import org.tianocore.FrameworkModulesDocument;
35 import org.tianocore.FrameworkPlatformDescriptionDocument;
36 import org.tianocore.ModuleSADocument;
37 import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;
38 import org.tianocore.build.global.GlobalData;
39 import org.tianocore.build.global.SurfaceAreaQuery;
40 import org.tianocore.build.pcd.action.ActionMessage;
41 import org.tianocore.build.pcd.entity.DynamicTokenValue;
42 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
43 import org.tianocore.build.pcd.entity.SkuInstance;
44 import org.tianocore.build.pcd.entity.Token;
45 import org.tianocore.build.pcd.entity.UsageInstance;
46 import org.tianocore.build.pcd.exception.EntityException;
47 import org.tianocore.ModuleTypeDef;
48
49 class CStructTypeDeclaration {
50 String key;
51 int alignmentSize;
52 String cCode;
53 boolean initTable;
54
55 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {
56 this.key = key;
57 this.alignmentSize = alignmentSize;
58 this.cCode = cCode;
59 this.initTable = initTable;
60 }
61 }
62
63 class StringTable {
64 private ArrayList<String> al;
65 private ArrayList<String> alComments;
66 private String phase;
67 int len;
68
69 public StringTable (String phase) {
70 this.phase = phase;
71 al = new ArrayList<String>();
72 alComments = new ArrayList<String>();
73 len = 0;
74 }
75
76 public String getSizeMacro () {
77 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
78 }
79
80 private int getSize () {
81 //
82 // We have at least one Unicode Character in the table.
83 //
84 return len == 0 ? 1 : len;
85 }
86
87 public int getTableLen () {
88 return al.size() == 0 ? 1 : al.size();
89 }
90
91 public String getExistanceMacro () {
92 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
93 }
94
95 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {
96 final String stringTable = "StringTable";
97 final String tab = "\t";
98 final String newLine = "\r\n";
99 final String commaNewLine = ",\r\n";
100
101 CStructTypeDeclaration decl;
102
103 String cDeclCode = "";
104 String cInstCode = "";
105
106 //
107 // If we have a empty StringTable
108 //
109 if (al.size() == 0) {
110 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;
111 decl = new CStructTypeDeclaration (
112 stringTable,
113 2,
114 cDeclCode,
115 true
116 );
117 declaList.add(decl);
118
119 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";
120 instTable.put(stringTable, cInstCode);
121 } else {
122
123 //
124 // If there is any String in the StringTable
125 //
126 for (int i = 0; i < al.size(); i++) {
127 String str = al.get(i);
128 String stringTableName;
129
130 if (i == 0) {
131 //
132 // StringTable is a well-known name in the PCD DXE driver
133 //
134 stringTableName = stringTable;
135
136 } else {
137 stringTableName = String.format("%s_%d", stringTable, i);
138 cDeclCode += tab;
139 }
140 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", stringTableName, str.length() + 1, alComments.get(i)) + newLine;
141
142 if (i == 0) {
143 cInstCode = "/* StringTable */" + newLine;
144 }
145 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
146 if (i != al.size() - 1) {
147 cInstCode += commaNewLine;
148 }
149 }
150
151 decl = new CStructTypeDeclaration (
152 stringTable,
153 2,
154 cDeclCode,
155 true
156 );
157 declaList.add(decl);
158
159 instTable.put(stringTable, cInstCode);
160 }
161 }
162
163 public String getTypeDeclaration () {
164
165 String output;
166
167 final String stringTable = "StringTable";
168 final String tab = "\t";
169 final String newLine = ";\r\n";
170
171 output = "/* StringTable */\r\n";
172
173 if (al.size() == 0) {
174 output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;
175 }
176
177 for (int i = 0; i < al.size(); i++) {
178 String str = al.get(i);
179
180 if (i == 0) {
181 //
182 // StringTable is a well-known name in the PCD DXE driver
183 //
184 output += tab + String.format("UINT16 %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;
185 } else {
186 output += tab + String.format("UINT16 %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;
187 }
188 }
189
190 return output;
191
192 }
193
194 public ArrayList<String> getInstantiation () {
195 ArrayList<String> output = new ArrayList<String>();
196
197 output.add("/* StringTable */");
198
199 if (al.size() == 0) {
200 output.add("{ 0 }");
201 } else {
202 String str;
203
204 for (int i = 0; i < al.size(); i++) {
205 str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
206 if (i != al.size() - 1) {
207 str += ",";
208 }
209 output.add(str);
210 }
211 }
212
213 return output;
214 }
215
216 public int add (String inputStr, Token token) {
217 int i;
218 int pos;
219
220 String str = inputStr;
221
222 //
223 // The input can be two types:
224 // "L\"Bootmode\"" or "Bootmode".
225 // We drop the L\" and \" for the first type.
226 if (str.startsWith("L\"") && str.endsWith("\"")) {
227 str = str.substring(2, str.length() - 1);
228 }
229 //
230 // Check if StringTable has this String already.
231 // If so, return the current pos.
232 //
233 for (i = 0, pos = 0; i < al.size(); i++) {
234 String s = al.get(i);;
235
236 if (str.equals(s)) {
237 return pos;
238 }
239 pos = s.length() + 1;
240
241 }
242
243 i = len;
244 //
245 // Include the NULL character at the end of String
246 //
247 len += str.length() + 1;
248 al.add(str);
249 alComments.add(token.getPrimaryKeyString());
250
251 return i;
252 }
253 }
254
255 class SizeTable {
256 private ArrayList<Integer> al;
257 private ArrayList<String> alComments;
258 private String phase;
259 private int len;
260
261 public SizeTable (String phase) {
262 this.phase = phase;
263 al = new ArrayList<Integer>();
264 alComments = new ArrayList<String>();
265 len = 0;
266 }
267
268 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
269 final String name = "SizeTable";
270
271 CStructTypeDeclaration decl;
272 String cCode;
273
274 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);
275 decl = new CStructTypeDeclaration (
276 name,
277 2,
278 cCode,
279 true
280 );
281 declaList.add(decl);
282
283
284 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
285 instTable.put(name, cCode);
286 }
287
288 public String getTypeDeclaration () {
289 return String.format(PcdDatabase.SizeTableDeclaration, phase);
290 }
291
292 public ArrayList<String> getInstantiation () {
293 ArrayList<String> Output = new ArrayList<String>();
294
295 Output.add("/* SizeTable */");
296 Output.add("{");
297 if (al.size() == 0) {
298 Output.add("\t0");
299 } else {
300 for (int index = 0; index < al.size(); index++) {
301 Integer n = al.get(index);
302 String str = "\t" + n.toString();
303
304 if (index != (al.size() - 1)) {
305 str += ",";
306 }
307
308 str += " /* " + alComments.get(index) + " */";
309 Output.add(str);
310
311 }
312 }
313 Output.add("}");
314
315 return Output;
316 }
317
318 public int add (Token token) {
319 int index = len;
320
321 len++;
322 al.add(token.datumSize);
323 alComments.add(token.getPrimaryKeyString());
324
325 return index;
326 }
327
328 public int getTableLen () {
329 return al.size() == 0 ? 1 : al.size();
330 }
331
332 }
333
334 class GuidTable {
335 private ArrayList<UUID> al;
336 private ArrayList<String> alComments;
337 private String phase;
338 private int len;
339 private int bodyLineNum;
340
341 public GuidTable (String phase) {
342 this.phase = phase;
343 al = new ArrayList<UUID>();
344 alComments = new ArrayList<String>();
345 len = 0;
346 bodyLineNum = 0;
347 }
348
349 public String getSizeMacro () {
350 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
351 }
352
353 private int getSize () {
354 return (al.size() == 0)? 1 : al.size();
355 }
356
357 public String getExistanceMacro () {
358 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
359 }
360
361 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
362 final String name = "GuidTable";
363
364 CStructTypeDeclaration decl;
365 String cCode = "";
366
367 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);
368 decl = new CStructTypeDeclaration (
369 name,
370 8,
371 cCode,
372 true
373 );
374 declaList.add(decl);
375
376
377 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
378 instTable.put(name, cCode);
379 }
380
381 public String getTypeDeclaration () {
382 return String.format(PcdDatabase.GuidTableDeclaration, phase);
383 }
384
385 private String getUuidCString (UUID uuid) {
386 String[] guidStrArray;
387
388 guidStrArray =(uuid.toString()).split("-");
389
390 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}}",
391 guidStrArray[0],
392 guidStrArray[1],
393 guidStrArray[2],
394 (guidStrArray[3].substring(0, 2)),
395 (guidStrArray[3].substring(2, 4)),
396 (guidStrArray[4].substring(0, 2)),
397 (guidStrArray[4].substring(2, 4)),
398 (guidStrArray[4].substring(4, 6)),
399 (guidStrArray[4].substring(6, 8)),
400 (guidStrArray[4].substring(8, 10)),
401 (guidStrArray[4].substring(10, 12))
402 );
403 }
404
405 public ArrayList<String> getInstantiation () {
406 ArrayList<String> Output = new ArrayList<String>();
407
408 Output.add("/* GuidTable */");
409 Output.add("{");
410 if (al.size() == 0) {
411 Output.add("\t" + getUuidCString(new UUID(0, 0)));
412 }
413
414 for (int i = 0; i < al.size(); i++) {
415 String str = "\t" + getUuidCString(al.get(i));
416
417 str += "/* " + alComments.get(i) + " */";
418 if (i != (al.size() - 1)) {
419 str += ",";
420 }
421 Output.add(str);
422 bodyLineNum++;
423
424 }
425 Output.add("}");
426
427 return Output;
428 }
429
430 public int add (UUID uuid, String name) {
431 //
432 // Check if GuidTable has this entry already.
433 // If so, return the GuidTable index.
434 //
435 for (int i = 0; i < al.size(); i++) {
436 if (al.get(i).equals(uuid)) {
437 return i;
438 }
439 }
440
441 len++;
442 al.add(uuid);
443 alComments.add(name);
444
445 //
446 // Return the previous Table Index
447 //
448 return len - 1;
449 }
450
451 public int getTableLen () {
452 return al.size() == 0 ? 0 : al.size();
453 }
454
455 }
456
457 class SkuIdTable {
458 private ArrayList<Integer[]> al;
459 private ArrayList<String> alComment;
460 private String phase;
461 private int len;
462
463 public SkuIdTable (String phase) {
464 this.phase = phase;
465 al = new ArrayList<Integer[]>();
466 alComment = new ArrayList<String>();
467 len = 0;
468 }
469
470 public String getSizeMacro () {
471 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
472 }
473
474 private int getSize () {
475 return (len == 0)? 1 : len;
476 }
477
478 public String getExistanceMacro () {
479 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
480 }
481
482 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
483 final String name = "SkuIdTable";
484
485 CStructTypeDeclaration decl;
486 String cCode = "";
487
488 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);
489 decl = new CStructTypeDeclaration (
490 name,
491 1,
492 cCode,
493 true
494 );
495 declaList.add(decl);
496
497
498 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
499 instTable.put(name, cCode);
500
501 //
502 // SystemSkuId is in PEI phase PCD Database
503 //
504 if (phase.equalsIgnoreCase("PEI")) {
505 decl = new CStructTypeDeclaration (
506 "SystemSkuId",
507 1,
508 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),
509 true
510 );
511 declaList.add(decl);
512
513 instTable.put("SystemSkuId", "0");
514 }
515
516 }
517
518 public String getTypeDeclaration () {
519 return String.format(PcdDatabase.SkuIdTableDeclaration, phase);
520 }
521
522 public ArrayList<String> getInstantiation () {
523 ArrayList<String> Output = new ArrayList<String> ();
524
525 Output.add("/* SkuIdTable */");
526 Output.add("{");
527
528 if (al.size() == 0) {
529 Output.add("\t0");
530 }
531
532 for (int index = 0; index < al.size(); index++) {
533 String str;
534
535 str = "/* " + alComment.get(index) + "*/ ";
536 str += "/* MaxSku */ ";
537
538
539 Integer[] ia = al.get(index);
540
541 str += "\t" + ia[0].toString() + ", ";
542 for (int index2 = 1; index2 < ia.length; index2++) {
543 str += ia[index2].toString();
544 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {
545 str += ", ";
546 }
547 }
548
549 Output.add(str);
550
551 }
552
553 Output.add("}");
554
555 return Output;
556 }
557
558 public int add (Token token) {
559
560 int index;
561 int pos;
562
563 //
564 // Check if this SKU_ID Array is already in the table
565 //
566 pos = 0;
567 for (Object o: al) {
568 Integer [] s = (Integer[]) o;
569 boolean different = false;
570 if (s[0] == token.getSkuIdCount()) {
571 for (index = 1; index < s.length; index++) {
572 if (s[index] != token.skuData.get(index-1).id) {
573 different = true;
574 break;
575 }
576 }
577 } else {
578 different = true;
579 }
580 if (different) {
581 pos += s[0] + 1;
582 } else {
583 return pos;
584 }
585 }
586
587 Integer [] skuIds = new Integer[token.skuData.size() + 1];
588 skuIds[0] = new Integer(token.skuData.size());
589 for (index = 1; index < skuIds.length; index++) {
590 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
591 }
592
593 index = len;
594
595 len += skuIds.length;
596 al.add(skuIds);
597 alComment.add(token.getPrimaryKeyString());
598
599 return index;
600 }
601
602 public int getTableLen () {
603 return al.size() == 0 ? 1 : al.size();
604 }
605
606 }
607
608 class LocalTokenNumberTable {
609 private ArrayList<String> al;
610 private ArrayList<String> alComment;
611 private String phase;
612 private int len;
613
614 public LocalTokenNumberTable (String phase) {
615 this.phase = phase;
616 al = new ArrayList<String>();
617 alComment = new ArrayList<String>();
618
619 len = 0;
620 }
621
622 public String getSizeMacro () {
623 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
624 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
625 }
626
627 public int getSize () {
628 return (al.size() == 0)? 1 : al.size();
629 }
630
631 public String getExistanceMacro () {
632 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
633 }
634
635 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
636 final String name = "LocalTokenNumberTable";
637
638 CStructTypeDeclaration decl;
639 String cCode = "";
640
641 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
642 decl = new CStructTypeDeclaration (
643 name,
644 4,
645 cCode,
646 true
647 );
648 declaList.add(decl);
649
650 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
651 instTable.put(name, cCode);
652 }
653
654 public String getTypeDeclaration () {
655 return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
656 }
657
658 public ArrayList<String> getInstantiation () {
659 ArrayList<String> output = new ArrayList<String>();
660
661 output.add("/* LocalTokenNumberTable */");
662 output.add("{");
663
664 if (al.size() == 0) {
665 output.add("\t0");
666 }
667
668 for (int index = 0; index < al.size(); index++) {
669 String str;
670
671 str = "\t" + (String)al.get(index);
672
673 str += " /* " + alComment.get(index) + " */ ";
674
675
676 if (index != (al.size() - 1)) {
677 str += ",";
678 }
679
680 output.add(str);
681
682 }
683
684 output.add("}");
685
686 return output;
687 }
688
689 public int add (Token token) {
690 int index = len;
691 String str;
692
693 len++;
694
695 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
696
697 if (token.isUnicodeStringType()) {
698 str += " | PCD_TYPE_STRING";
699 }
700
701 if (token.isSkuEnable()) {
702 str += " | PCD_TYPE_SKU_ENABLED";
703 }
704
705 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
706 str += " | PCD_TYPE_HII";
707 }
708
709 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
710 str += " | PCD_TYPE_VPD";
711 }
712
713 al.add(str);
714 alComment.add(token.getPrimaryKeyString());
715
716 return index;
717 }
718 }
719
720 class ExMapTable {
721
722 class ExTriplet {
723 public Integer guidTableIdx;
724 public Long exTokenNumber;
725 public Long localTokenIdx;
726
727 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
728 this.guidTableIdx = new Integer(guidTableIdx);
729 this.exTokenNumber = new Long(exTokenNumber);
730 this.localTokenIdx = new Long(localTokenIdx);
731 }
732 }
733
734 private ArrayList<ExTriplet> al;
735 private ArrayList<String> alComment;
736 private String phase;
737 private int len;
738 private int bodyLineNum;
739
740 public ExMapTable (String phase) {
741 this.phase = phase;
742 al = new ArrayList<ExTriplet>();
743 alComment = new ArrayList<String>();
744 bodyLineNum = 0;
745 len = 0;
746 }
747
748 public String getSizeMacro () {
749 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
750 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
751 }
752
753 public String getExistanceMacro () {
754 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
755 }
756
757 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
758 final String exMapTableName = "ExMapTable";
759
760 sortTable();
761
762 CStructTypeDeclaration decl;
763 String cCode = "";
764
765 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);
766 decl = new CStructTypeDeclaration (
767 exMapTableName,
768 4,
769 cCode,
770 true
771 );
772 declaList.add(decl);
773
774
775 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
776 instTable.put(exMapTableName, cCode);
777 }
778
779 public String getTypeDeclaration () {
780 return String.format(PcdDatabase.ExMapTableDeclaration, phase);
781 }
782
783 public ArrayList<String> getInstantiation () {
784 ArrayList<String> Output = new ArrayList<String>();
785
786 Output.add("/* ExMapTable */");
787 Output.add("{");
788 if (al.size() == 0) {
789 Output.add("\t{0, 0, 0}");
790 }
791
792 int index;
793 for (index = 0; index < al.size(); index++) {
794 String str;
795
796 ExTriplet e = (ExTriplet)al.get(index);
797
798 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";
799 str += e.localTokenIdx.toString() + ", ";
800 str += e.guidTableIdx.toString();
801
802 str += "}" + " /* " + alComment.get(index) + " */" ;
803
804 if (index != al.size() - 1) {
805 str += ",";
806 }
807
808 Output.add(str);
809 bodyLineNum++;
810
811 }
812
813 Output.add("}");
814
815 return Output;
816 }
817
818 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
819 int index = len;
820
821 len++;
822 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));
823 alComment.add(name);
824
825 return index;
826 }
827
828 public int getTableLen () {
829 return al.size() == 0 ? 1 : al.size();
830 }
831
832 //
833 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in
834 // PCD PEIM/Driver, we need to sort the ExMapTable according to the
835 // following order:
836 // 1) ExGuid
837 // 2) ExTokenNumber
838 //
839 class ExTripletComp implements Comparator<ExTriplet> {
840 public int compare (ExTriplet a, ExTriplet b) {
841 if (a.guidTableIdx == b.guidTableIdx ) {
842 if (a.exTokenNumber > b.exTokenNumber) {
843 return 1;
844 } else if (a.exTokenNumber > b.exTokenNumber) {
845 return 1;
846 } else {
847 return 0;
848 }
849 }
850
851 return a.guidTableIdx - b.guidTableIdx;
852 }
853 }
854
855 private void sortTable () {
856 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();
857 java.util.Collections.sort(al, comparator);
858 }
859 }
860
861 class PcdDatabase {
862
863 private final static int SkuHeadAlignmentSize = 4;
864 private final String newLine = "\r\n";
865 private final String commaNewLine = ",\r\n";
866 private final String tab = "\t";
867 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
868 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
869 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
870 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
871 public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
872 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
873
874
875 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
876 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
877 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
878 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
879 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
880 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
881 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
882
883
884 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
885 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
886 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
887 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
888 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
889
890 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
891 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";
892 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
893
894 private final static String skuDataTableTemplate = "SkuDataTable";
895
896
897 private StringTable stringTable;
898 private GuidTable guidTable;
899 private LocalTokenNumberTable localTokenNumberTable;
900 private SkuIdTable skuIdTable;
901 private SizeTable sizeTable;
902 private ExMapTable exMapTable;
903
904 private ArrayList<Token> alTokens;
905 private String phase;
906 private int assignedTokenNumber;
907
908 //
909 // Use two class global variable to store
910 // temperary
911 //
912 private String privateGlobalName;
913 private String privateGlobalCCode;
914 //
915 // After Major changes done to the PCD
916 // database generation class PcdDatabase
917 // Please increment the version and please
918 // also update the version number in PCD
919 // service PEIM and DXE driver accordingly.
920 //
921 private final int version = 2;
922
923 private String hString;
924 private String cString;
925
926
927 class AlignmentSizeComp implements Comparator<Token> {
928 public int compare (Token a, Token b) {
929 return getAlignmentSize(b)
930 - getAlignmentSize(a);
931 }
932 }
933
934 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
935 phase = exePhase;
936
937 stringTable = new StringTable(phase);
938 guidTable = new GuidTable(phase);
939 localTokenNumberTable = new LocalTokenNumberTable(phase);
940 skuIdTable = new SkuIdTable(phase);
941 sizeTable = new SizeTable(phase);
942 exMapTable = new ExMapTable(phase);
943
944 assignedTokenNumber = startLen + 1;
945 this.alTokens = alTokens;
946 }
947
948 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {
949 for (int i = 0; i < alTokens.size(); i++) {
950 Token t = (Token)alTokens.get(i);
951 if (t.isDynamicEx()) {
952 exTokens.add(t);
953 } else {
954 nexTokens.add(t);
955 }
956 }
957
958 return;
959 }
960
961 private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {
962 for (int i = 0; i < alTokens.size(); i++) {
963 Token t = (Token)alTokens.get(i);
964 if (t.hasDefaultValue()) {
965 initTokens.add(t);
966 } else {
967 uninitTokens.add(t);
968 }
969 }
970
971 return;
972 }
973
974 private int getDataTypeAlignmentSize (Token token) {
975 switch (token.datumType) {
976 case UINT8:
977 return 1;
978 case UINT16:
979 return 2;
980 case UINT32:
981 return 4;
982 case UINT64:
983 return 8;
984 case POINTER:
985 return 1;
986 case BOOLEAN:
987 return 1;
988 default:
989 return 1;
990 }
991 }
992
993 private int getAlignmentSize (Token token) {
994 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
995 return 2;
996 }
997
998 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
999 return 4;
1000 }
1001
1002 if (token.isUnicodeStringType()) {
1003 return 2;
1004 }
1005
1006 return getDataTypeAlignmentSize(token);
1007 }
1008
1009 public String getCString () {
1010 return cString;
1011 }
1012
1013 public String getHString () {
1014 return hString;
1015 }
1016
1017 private void genCodeWorker(Token t,
1018 ArrayList<CStructTypeDeclaration> declaList,
1019 HashMap<String, String> instTable, String phase)
1020 throws EntityException {
1021
1022 CStructTypeDeclaration decl;
1023
1024 //
1025 // Insert SKU_HEAD if isSkuEnable is true
1026 //
1027 if (t.isSkuEnable()) {
1028 int tableIdx;
1029 tableIdx = skuIdTable.add(t);
1030 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),
1031 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);
1032 declaList.add(decl);
1033 instTable.put(t.getPrimaryKeyString(),
1034 getSkuEnabledTypeInstantiaion(t, tableIdx));
1035 }
1036
1037 //
1038 // Insert PCD_ENTRY declaration and instantiation
1039 //
1040 getCDeclarationString(t);
1041
1042 decl = new CStructTypeDeclaration(privateGlobalName,
1043 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());
1044 declaList.add(decl);
1045
1046 if (t.hasDefaultValue()) {
1047 instTable.put(privateGlobalName,
1048 getTypeInstantiation(t, declaList, instTable, phase)
1049 );
1050 }
1051
1052 }
1053
1054 private void ProcessTokensNew (List<Token> tokens,
1055 ArrayList<CStructTypeDeclaration> cStructDeclList,
1056 HashMap<String, String> cStructInstTable,
1057 String phase
1058 )
1059 throws EntityException {
1060
1061 for (int idx = 0; idx < tokens.size(); idx++) {
1062 Token t = tokens.get(idx);
1063
1064 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);
1065
1066 sizeTable.add(t);
1067 localTokenNumberTable.add(t);
1068 t.tokenNumber = assignedTokenNumber++;
1069
1070 //
1071 // Add a mapping if this dynamic PCD entry is a EX type
1072 //
1073 if (t.isDynamicEx()) {
1074 exMapTable.add(t.tokenNumber,
1075 t.dynamicExTokenNumber,
1076 guidTable.add(t.tokenSpaceName, t.getPrimaryKeyString()),
1077 t.getPrimaryKeyString()
1078 );
1079 }
1080 }
1081
1082 }
1083
1084 public void genCodeNew () throws EntityException {
1085
1086 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();
1087 HashMap<String, String> cStructInstTable = new HashMap<String, String>();
1088
1089 List<Token> nexTokens = new ArrayList<Token> ();
1090 List<Token> exTokens = new ArrayList<Token> ();
1091
1092 getNonExAndExTokens (alTokens, nexTokens, exTokens);
1093
1094 //
1095 // We have to process Non-Ex type PCD entry first. The reason is
1096 // that our optimization assumes that the Token Number of Non-Ex
1097 // PCD entry start from 1 (for PEI phase) and grows continously upwards.
1098 //
1099 // EX type token number starts from the last Non-EX PCD entry and
1100 // grows continously upwards.
1101 //
1102 ProcessTokensNew (nexTokens, cStructDeclList, cStructInstTable, phase);
1103 ProcessTokensNew (exTokens, cStructDeclList, cStructInstTable, phase);
1104
1105 stringTable.genCodeNew(cStructDeclList, cStructInstTable);
1106 skuIdTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1107 exMapTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1108 localTokenNumberTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1109 sizeTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1110 guidTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1111
1112 hString = genCMacroCode ();
1113
1114 HashMap <String, String> result;
1115
1116 result = genCStructCode(cStructDeclList,
1117 cStructInstTable,
1118 phase
1119 );
1120
1121 hString += result.get("initDeclStr");
1122 hString += result.get("uninitDeclStr");
1123
1124 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
1125
1126 cString = newLine + newLine + result.get("initInstStr");
1127
1128 }
1129
1130 private String genCMacroCode () {
1131 String macroStr = "";
1132
1133 //
1134 // Generate size info Macro for all Tables
1135 //
1136 macroStr += guidTable.getSizeMacro();
1137 macroStr += stringTable.getSizeMacro();
1138 macroStr += skuIdTable.getSizeMacro();
1139 macroStr += localTokenNumberTable.getSizeMacro();
1140 macroStr += exMapTable.getSizeMacro();
1141
1142 //
1143 // Generate existance info Macro for all Tables
1144 //
1145 macroStr += guidTable.getExistanceMacro();
1146 macroStr += stringTable.getExistanceMacro();
1147 macroStr += skuIdTable.getExistanceMacro();
1148 macroStr += localTokenNumberTable.getExistanceMacro();
1149 macroStr += exMapTable.getExistanceMacro();
1150
1151 macroStr += newLine;
1152
1153 return macroStr;
1154 }
1155
1156 private HashMap <String, String> genCStructCode(
1157 ArrayList<CStructTypeDeclaration> declaList,
1158 HashMap<String, String> instTable,
1159 String phase
1160 ) {
1161
1162 int i;
1163 HashMap <String, String> result = new HashMap<String, String>();
1164 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();
1165 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();
1166 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();
1167
1168 //
1169 // Initialize the storage for each alignment
1170 //
1171 for (i = 8; i > 0; i>>=1) {
1172 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());
1173 alignmentInitInst.put(new Integer(i), new ArrayList<String>());
1174 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());
1175 }
1176
1177 String initDeclStr = "typedef struct {" + newLine;
1178 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;
1179 String uninitDeclStr = "typedef struct {" + newLine;
1180
1181 //
1182 // Sort all C declaration and instantiation base on Alignment Size
1183 //
1184 for (Object d : declaList) {
1185 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;
1186
1187 if (decl.initTable) {
1188 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1189 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));
1190 } else {
1191 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1192 }
1193 }
1194
1195 //
1196 // Generate code for every alignment size
1197 //
1198 boolean uinitDatabaseEmpty = true;
1199 for (int align = 8; align > 0; align >>= 1) {
1200 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));
1201 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));
1202 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {
1203 initDeclStr += tab + declaListBasedOnAlignment.get(i);
1204 initInstStr += tab + instListBasedOnAlignment.get(i);
1205
1206 //
1207 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE
1208 // has a least one data memember with alignment size of 1. So we can
1209 // remove the last "," in the C structure instantiation string. Luckily,
1210 // this is true as both data structure has SKUID_TABLE anyway.
1211 //
1212 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {
1213 initInstStr += newLine;
1214 } else {
1215 initInstStr += commaNewLine;
1216 }
1217 }
1218
1219 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));
1220
1221 if (declaListBasedOnAlignment.size() != 0) {
1222 uinitDatabaseEmpty = false;
1223 }
1224
1225 for (Object d : declaListBasedOnAlignment) {
1226 String s = (String)d;
1227 uninitDeclStr += tab + s;
1228 }
1229 }
1230
1231 if (uinitDatabaseEmpty) {
1232 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");
1233 }
1234
1235 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;
1236 initInstStr += "};" + newLine;
1237 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;
1238
1239 result.put("initDeclStr", initDeclStr);
1240 result.put("initInstStr", initInstStr);
1241 result.put("uninitDeclStr", uninitDeclStr);
1242
1243 return result;
1244 }
1245
1246 public void genCode ()
1247 throws EntityException {
1248
1249 final String newLine = "\r\n";
1250 final String declNewLine = ";\r\n";
1251 final String tab = "\t";
1252 final String commaNewLine = ", \r\n";
1253
1254 int i;
1255 ArrayList<String> decla;
1256 ArrayList<String> inst;
1257
1258 String macroStr = "";
1259 String initDeclStr = "";
1260 String initInstStr = "";
1261 String uninitDeclStr = "";
1262
1263 List<Token> initTokens = new ArrayList<Token> ();
1264 List<Token> uninitTokens = new ArrayList<Token> ();
1265
1266 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();
1267 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();
1268
1269 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);
1270
1271 //
1272 // Generate Structure Declaration for PcdTokens without Default Value
1273 // PEI_PCD_DATABASE_INIT
1274 //
1275 java.util.Comparator<Token> comparator = new AlignmentSizeComp();
1276 java.util.Collections.sort(initTokens, comparator);
1277 initCode = processTokens(initTokens);
1278
1279 //
1280 // Generate Structure Declaration for PcdTokens without Default Value
1281 // PEI_PCD_DATABASE_UNINIT
1282 //
1283 java.util.Collections.sort(uninitTokens, comparator);
1284 uninitCode = processTokens(uninitTokens);
1285
1286 //
1287 // Generate size info Macro for all Tables
1288 //
1289 macroStr += guidTable.getSizeMacro();
1290 macroStr += stringTable.getSizeMacro();
1291 macroStr += skuIdTable.getSizeMacro();
1292 macroStr += localTokenNumberTable.getSizeMacro();
1293 macroStr += exMapTable.getSizeMacro();
1294
1295 //
1296 // Generate existance info Macro for all Tables
1297 //
1298 macroStr += guidTable.getExistanceMacro();
1299 macroStr += stringTable.getExistanceMacro();
1300 macroStr += skuIdTable.getExistanceMacro();
1301 macroStr += localTokenNumberTable.getExistanceMacro();
1302 macroStr += exMapTable.getExistanceMacro();
1303
1304 //
1305 // Generate Structure Declaration for PcdTokens with Default Value
1306 // for example PEI_PCD_DATABASE_INIT
1307 //
1308 initDeclStr += "typedef struct {" + newLine;
1309 {
1310 initDeclStr += tab + exMapTable.getTypeDeclaration();
1311 initDeclStr += tab + guidTable.getTypeDeclaration();
1312 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
1313 initDeclStr += tab + stringTable.getTypeDeclaration();
1314 initDeclStr += tab + sizeTable.getTypeDeclaration();
1315 initDeclStr += tab + skuIdTable.getTypeDeclaration();
1316 if (phase.equalsIgnoreCase("PEI")) {
1317 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
1318 }
1319
1320 decla = initCode.get(new String("Declaration"));
1321 for (i = 0; i < decla.size(); i++) {
1322 initDeclStr += tab + decla.get(i) + declNewLine;
1323 }
1324
1325 //
1326 // Generate Structure Declaration for PcdToken with SkuEnabled
1327 //
1328 decla = initCode.get("DeclarationForSku");
1329
1330 for (i = 0; i < decla.size(); i++) {
1331 initDeclStr += tab + decla.get(i) + declNewLine;
1332 }
1333 }
1334 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
1335
1336 //
1337 // Generate MACRO for structure intialization of PCDTokens with Default Value
1338 // The sequence must match the sequence of declaration of the memembers in the structure
1339 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
1340 initInstStr += tmp + newLine;
1341 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
1342 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
1343 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
1344 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
1345 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
1346 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
1347 //
1348 // For SystemSkuId
1349 //
1350 if (phase.equalsIgnoreCase("PEI")) {
1351 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
1352 }
1353
1354 inst = initCode.get("Instantiation");
1355 for (i = 0; i < inst.size(); i++) {
1356 initInstStr += tab + inst.get(i) + commaNewLine;
1357 }
1358
1359 inst = initCode.get("InstantiationForSku");
1360 for (i = 0; i < inst.size(); i++) {
1361 initInstStr += tab + inst.get(i);
1362 if (i != inst.size() - 1) {
1363 initInstStr += commaNewLine;
1364 }
1365 }
1366
1367 initInstStr += "};";
1368
1369 uninitDeclStr += "typedef struct {" + newLine;
1370 {
1371 decla = uninitCode.get("Declaration");
1372 if (decla.size() == 0) {
1373 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
1374 } else {
1375
1376 for (i = 0; i < decla.size(); i++) {
1377 uninitDeclStr += tab + decla.get(i) + declNewLine;
1378 }
1379
1380 decla = uninitCode.get("DeclarationForSku");
1381
1382 for (i = 0; i < decla.size(); i++) {
1383 uninitDeclStr += tab + decla.get(i) + declNewLine;
1384 }
1385 }
1386 }
1387 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
1388
1389 cString = initInstStr + newLine;
1390 hString = macroStr + newLine
1391 + initDeclStr + newLine
1392 + uninitDeclStr + newLine
1393 + newLine;
1394
1395 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
1396
1397 }
1398
1399 public static String genInstantiationStr (ArrayList<String> alStr) {
1400 String str = "";
1401 for (int i = 0; i< alStr.size(); i++) {
1402 if (i != 0) {
1403 str += "\t";
1404 }
1405 str += alStr.get(i);
1406 if (i != alStr.size() - 1) {
1407 str += "\r\n";
1408 }
1409 }
1410
1411 return str;
1412 }
1413
1414 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken)
1415 throws EntityException {
1416
1417 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
1418
1419 ArrayList<String> decl = new ArrayList<String>();
1420 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
1421 ArrayList<String> inst = new ArrayList<String>();
1422 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
1423
1424 for (int index = 0; index < alToken.size(); index++) {
1425 Token token = alToken.get(index);
1426
1427 if (token.isSkuEnable()) {
1428 //
1429 // BugBug: Schema only support Data type now
1430 //
1431 int tableIdx;
1432
1433 tableIdx = skuIdTable.add(token);
1434
1435 decl.add(getSkuEnabledTypeDeclaration(token));
1436 if (token.hasDefaultValue()) {
1437 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
1438 }
1439
1440 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
1441 if (token.hasDefaultValue()) {
1442 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
1443 }
1444
1445 } else {
1446 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
1447 decl.add(getVariableEnableTypeDeclaration(token));
1448 inst.add(getVariableEnableInstantiation(token));
1449 } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
1450 decl.add(getVpdEnableTypeDeclaration(token));
1451 inst.add(getVpdEnableTypeInstantiation(token));
1452 } else if (token.isUnicodeStringType()) {
1453 decl.add(getStringTypeDeclaration(token));
1454 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
1455 }
1456 else {
1457 decl.add(getDataTypeDeclaration(token));
1458 if (token.hasDefaultValue()) {
1459 inst.add(getDataTypeInstantiation(token));
1460 }
1461 }
1462 }
1463
1464 sizeTable.add(token);
1465 localTokenNumberTable.add(token);
1466 token.tokenNumber = assignedTokenNumber++;
1467
1468 }
1469
1470 map.put("Declaration", decl);
1471 map.put("DeclarationForSku", declForSkuEnableType);
1472 map.put("Instantiation", inst);
1473 map.put("InstantiationForSku", instForSkuEnableType);
1474
1475 return map;
1476 }
1477
1478 private String getSkuEnabledTypeDeclaration (Token token) {
1479 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());
1480 }
1481
1482 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
1483
1484 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
1485 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());
1486 }
1487
1488 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1489 String typeStr = "";
1490
1491 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1492 typeStr = "UINT8 %s_%s[%d];\r\n";
1493 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1494 typeStr = "UINT16 %s_%s[%d];\r\n";
1495 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1496 typeStr = "UINT32 %s_%s[%d];\r\n";
1497 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1498 typeStr = "UINT64 %s_%s[%d];\r\n";
1499 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1500 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1501 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1502 return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1503 }
1504
1505 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size());
1506
1507 }
1508
1509 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1510 String str = "";
1511
1512 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1513 return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1514 } else {
1515 str = "{ ";
1516 for (int idx = 0; idx < token.skuData.size(); idx++) {
1517 str += token.skuData.get(idx).toString();
1518 if (idx != token.skuData.size() - 1) {
1519 str += ", ";
1520 }
1521 }
1522 str += "}";
1523
1524 return str;
1525 }
1526
1527 }
1528
1529 private String getDataTypeInstantiationForVariableDefault_new (Token token, String cName, int skuId) {
1530 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);
1531 }
1532
1533 private String getDataTypeInstantiation (Token token) {
1534
1535 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1536 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1537 } else {
1538 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1539 }
1540 }
1541
1542 private String getCType (Token t)
1543 throws EntityException {
1544
1545 if (t.isHiiEnable()) {
1546 return "VARIABLE_HEAD";
1547 }
1548
1549 if (t.isVpdEnable()) {
1550 return "VPD_HEAD";
1551 }
1552
1553 if (t.isUnicodeStringType()) {
1554 return "STRING_HEAD";
1555 }
1556
1557 switch (t.datumType) {
1558 case UINT64:
1559 return "UINT64";
1560 case UINT32:
1561 return "UINT32";
1562 case UINT16:
1563 return "UINT16";
1564 case UINT8:
1565 return "UINT8";
1566 case BOOLEAN:
1567 return "BOOLEAN";
1568 case POINTER:
1569 return "UINT8";
1570 default:
1571 throw new EntityException("Unknown type in getDataTypeCDeclaration");
1572 }
1573 }
1574
1575 private void getCDeclarationString(Token t)
1576 throws EntityException {
1577
1578 if (t.isSkuEnable()) {
1579 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);
1580 } else {
1581 privateGlobalName = t.getPrimaryKeyString();
1582 }
1583
1584 if (t.isUnicodeStringType()) {
1585 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", "STRING_HEAD", t.getPrimaryKeyString(), t.getSkuIdCount());
1586 } else {
1587 String type = getCType(t);
1588 if (t.datumType == Token.DATUM_TYPE.POINTER) {
1589 int bufferSize;
1590 if (t.isASCIIStringType()) {
1591 //
1592 // Build tool will add a NULL string at the end of the ASCII string
1593 //
1594 bufferSize = t.datumSize + 1;
1595 } else {
1596 bufferSize = t.datumSize;
1597 }
1598 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);
1599 } else {
1600 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());
1601 }
1602 }
1603 }
1604
1605 private String getDataTypeDeclarationForVariableDefault_new (Token token, String cName, int skuId) {
1606
1607 String typeStr;
1608
1609 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1610 typeStr = "UINT8";
1611 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1612 typeStr = "UINT16";
1613 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1614 typeStr = "UINT32";
1615 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1616 typeStr = "UINT64";
1617 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1618 typeStr = "BOOLEAN";
1619 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1620 return String.format("%-20s%s[%d];\r\n", cName, token.datumSize);
1621 } else {
1622 typeStr = "";
1623 }
1624
1625 return String.format("%-20s%s;\r\n", typeStr, cName);
1626 }
1627
1628 private String getDataTypeDeclaration (Token token) {
1629
1630 String typeStr = "";
1631
1632 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1633 typeStr = "UINT8";
1634 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1635 typeStr = "UINT16";
1636 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1637 typeStr = "UINT32";
1638 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1639 typeStr = "UINT64";
1640 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1641 typeStr = "BOOLEAN";
1642 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1643 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1644 } else {
1645 }
1646
1647 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1648 }
1649
1650 private String getVpdEnableTypeDeclaration (Token token) {
1651 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1652 }
1653
1654 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {
1655
1656 int i;
1657
1658 String s;
1659 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;
1660 s += tab + "{" + newLine;
1661
1662 for (i = 0; i < t.skuData.size(); i++) {
1663 if (t.isUnicodeStringType() && !t.isHiiEnable()) {
1664 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));
1665 } else if (t.isHiiEnable()) {
1666 /* VPD_HEAD definition
1667 typedef struct {
1668 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
1669 UINT16 StringIndex; // Offset in String Table in units of UINT16.
1670 UINT16 Offset; // Offset in Variable
1671 } VARIABLE_HEAD ;
1672 */
1673 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);
1674
1675 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),
1676 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),
1677 t.skuData.get(i).value.variableOffset,
1678 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)
1679 );
1680 //
1681 // We need to support the default value, so we add the declaration and
1682 // the instantiation for the default value.
1683 //
1684 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,
1685 getDataTypeAlignmentSize(t),
1686 getDataTypeDeclarationForVariableDefault_new(t, variableDefaultName, i),
1687 true
1688 );
1689 declaList.add(decl);
1690 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault_new (t, variableDefaultName, i));
1691 } else if (t.isVpdEnable()) {
1692 /* typedef struct {
1693 UINT32 Offset;
1694 } VPD_HEAD;
1695 */
1696 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);
1697 } else {
1698 if (t.isByteStreamType()) {
1699 //
1700 // Byte stream type input has their own "{" "}", so we won't help to insert.
1701 //
1702 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);
1703 } else {
1704 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);
1705 }
1706 }
1707
1708 if (i != t.skuData.size() - 1) {
1709 s += commaNewLine;
1710 } else {
1711 s += newLine;
1712 }
1713
1714 }
1715
1716 s += tab + "}";
1717
1718 return s;
1719 }
1720
1721 private String getVpdEnableTypeInstantiation (Token token) {
1722 return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset,
1723 token.getPrimaryKeyString());
1724 }
1725
1726 private String getStringTypeDeclaration (Token token) {
1727 return String.format("UINT16 %s", token.getPrimaryKeyString());
1728 }
1729
1730 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1731 return String.format ("%d /* %s */", StringTableIdx,
1732 token.getPrimaryKeyString());
1733 }
1734
1735
1736 private String getVariableEnableTypeDeclaration (Token token) {
1737 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1738 }
1739
1740 private String getVariableEnableInstantiation (Token token)
1741 throws EntityException {
1742 //
1743 // Need scott fix
1744 //
1745 return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()),
1746 stringTable.add(token.getDefaultSku().getStringOfVariableName(), token),
1747 token.getDefaultSku().variableOffset,
1748 token.getPrimaryKeyString());
1749 }
1750
1751 public int getTotalTokenNumber () {
1752 return sizeTable.getTableLen();
1753 }
1754
1755 public static String getPcdDatabaseCommonDefinitions ()
1756 throws EntityException {
1757
1758 String retStr = "";
1759 try {
1760 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1761 "Tools" + File.separator +
1762 "Conf" + File.separator +
1763 "Pcd" + File.separator +
1764 "PcdDatabaseCommonDefinitions.sample");
1765 FileReader reader = new FileReader(file);
1766 BufferedReader in = new BufferedReader(reader);
1767 String str;
1768 while ((str = in.readLine()) != null) {
1769 retStr = retStr +"\r\n" + str;
1770 }
1771 } catch (Exception ex) {
1772 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1773 }
1774
1775 return retStr;
1776 }
1777
1778 public static String getPcdDxeDatabaseDefinitions ()
1779 throws EntityException {
1780
1781 String retStr = "";
1782 try {
1783 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1784 "Tools" + File.separator +
1785 "Conf" + File.separator +
1786 "Pcd" + File.separator +
1787 "PcdDatabaseDxeDefinitions.sample");
1788 FileReader reader = new FileReader(file);
1789 BufferedReader in = new BufferedReader(reader);
1790 String str;
1791 while ((str = in.readLine()) != null) {
1792 retStr = retStr +"\r\n" + str;
1793 }
1794 } catch (Exception ex) {
1795 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1796 }
1797
1798 return retStr;
1799 }
1800
1801 public static String getPcdPeiDatabaseDefinitions ()
1802 throws EntityException {
1803
1804 String retStr = "";
1805 try {
1806 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1807 "Tools" + File.separator +
1808 "Conf" + File.separator +
1809 "Pcd" + File.separator +
1810 "PcdDatabasePeiDefinitions.sample");
1811 FileReader reader = new FileReader(file);
1812 BufferedReader in = new BufferedReader(reader);
1813 String str;
1814 while ((str = in.readLine()) != null) {
1815 retStr = retStr +"\r\n" + str;
1816 }
1817 } catch (Exception ex) {
1818 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1819 }
1820
1821 return retStr;
1822 }
1823
1824 }
1825
1826 class ModuleInfo {
1827 public ModuleSADocument.ModuleSA module;
1828 public ModuleTypeDef.Enum type;
1829
1830 public ModuleInfo (ModuleSADocument.ModuleSA module, ModuleTypeDef.Enum type) {
1831 this.module = module;
1832 this.type = type;
1833 }
1834 }
1835
1836 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1837 This class will be used for wizard and build tools, So it can *not* inherit
1838 from buildAction or UIAction.
1839 **/
1840 public class CollectPCDAction {
1841 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1842 private MemoryDatabaseManager dbManager;
1843
1844 /// Workspacepath hold the workspace information.
1845 private String workspacePath;
1846
1847 /// FPD file is the root file.
1848 private String fpdFilePath;
1849
1850 /// Message level for CollectPCDAction.
1851 private int originalMessageLevel;
1852
1853 /// Cache the fpd docment instance for private usage.
1854 private FrameworkPlatformDescriptionDocument fpdDocInstance;
1855
1856 /**
1857 Set WorkspacePath parameter for this action class.
1858
1859 @param workspacePath parameter for this action
1860 **/
1861 public void setWorkspacePath(String workspacePath) {
1862 this.workspacePath = workspacePath;
1863 }
1864
1865 /**
1866 Set action message level for CollectPcdAction tool.
1867
1868 The message should be restored when this action exit.
1869
1870 @param actionMessageLevel parameter for this action
1871 **/
1872 public void setActionMessageLevel(int actionMessageLevel) {
1873 originalMessageLevel = ActionMessage.messageLevel;
1874 ActionMessage.messageLevel = actionMessageLevel;
1875 }
1876
1877 /**
1878 Set FPDFileName parameter for this action class.
1879
1880 @param fpdFilePath fpd file path
1881 **/
1882 public void setFPDFilePath(String fpdFilePath) {
1883 this.fpdFilePath = fpdFilePath;
1884 }
1885
1886 /**
1887 Common function interface for outer.
1888
1889 @param workspacePath The path of workspace of current build or analysis.
1890 @param fpdFilePath The fpd file path of current build or analysis.
1891 @param messageLevel The message level for this Action.
1892
1893 @throws Exception The exception of this function. Because it can *not* be predict
1894 where the action class will be used. So only Exception can be throw.
1895
1896 **/
1897 public void perform(String workspacePath, String fpdFilePath,
1898 int messageLevel) throws Exception {
1899 setWorkspacePath(workspacePath);
1900 setFPDFilePath(fpdFilePath);
1901 setActionMessageLevel(messageLevel);
1902 checkParameter();
1903 execute();
1904 ActionMessage.messageLevel = originalMessageLevel;
1905 }
1906
1907 /**
1908 Core execution function for this action class.
1909
1910 This function work flows will be:
1911 1) Collect and prepocess PCD information from FPD file, all PCD
1912 information will be stored into memory database.
1913 2) Generate 3 strings for
1914 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
1915 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
1916 c) DXE PCD Database (C structure) for PCD Service DXE.
1917
1918
1919 @throws EntityException Exception indicate failed to execute this action.
1920
1921 **/
1922 private void execute() throws EntityException {
1923 //
1924 // Get memoryDatabaseManager instance from GlobalData.
1925 // The memoryDatabaseManager should be initialized for whatever build
1926 // tools or wizard tools
1927 //
1928 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1929 throw new EntityException("The instance of PCD memory database manager is null");
1930 }
1931
1932 //
1933 // Collect all PCD information defined in FPD file.
1934 // Evenry token defind in FPD will be created as an token into
1935 // memory database.
1936 //
1937 createTokenInDBFromFPD();
1938
1939 //
1940 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1941 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1942 //
1943 genPcdDatabaseSourceCode ();
1944
1945 }
1946
1947 /**
1948 This function generates source code for PCD Database.
1949
1950 @param void
1951 @throws EntityException If the token does *not* exist in memory database.
1952
1953 **/
1954 private void genPcdDatabaseSourceCode()
1955 throws EntityException {
1956 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1957
1958 ArrayList<Token> alPei = new ArrayList<Token> ();
1959 ArrayList<Token> alDxe = new ArrayList<Token> ();
1960
1961 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1962 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1963 pcdPeiDatabase.genCodeNew();
1964 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1965 + PcdDatabase.getPcdPeiDatabaseDefinitions();
1966 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();
1967
1968 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
1969 "DXE",
1970 alPei.size()
1971 );
1972 pcdDxeDatabase.genCodeNew();
1973 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString()
1974 + PcdDatabase.getPcdDxeDatabaseDefinitions();
1975 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();
1976 }
1977
1978 /**
1979 Get component array from FPD.
1980
1981 This function maybe provided by some Global class.
1982
1983 @return List<ModuleInfo> the component array.
1984
1985 */
1986 private List<ModuleInfo> getComponentsFromFPD()
1987 throws EntityException {
1988 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();
1989 ModuleInfo current = null;
1990 int index = 0;
1991 org.tianocore.Components components = null;
1992 FrameworkModulesDocument.FrameworkModules fModules = null;
1993 ModuleSADocument.ModuleSA[] modules = null;
1994 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
1995
1996 if (fpdDocInstance == null) {
1997 try {
1998 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
1999 } catch(IOException ioE) {
2000 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
2001 } catch(XmlException xmlE) {
2002 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
2003 }
2004
2005 }
2006
2007 map.put("FrameworkPlatformDescription", fpdDocInstance);
2008 SurfaceAreaQuery.setDoc(map);
2009 modules = SurfaceAreaQuery.getFpdModuleSAs();
2010 for (index = 0; index < modules.length; index ++) {
2011 SurfaceAreaQuery.setDoc(GlobalData.getDoc(modules[index].getModuleName()));
2012 allModules.add(new ModuleInfo(modules[index],
2013 ModuleTypeDef.Enum.forString(SurfaceAreaQuery.getModuleType())));
2014 }
2015
2016 return allModules;
2017 }
2018
2019 /**
2020 Create token instance object into memory database, the token information
2021 comes for FPD file. Normally, FPD file will contain all token platform
2022 informations.
2023
2024 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
2025
2026 @throws EntityException Failed to parse FPD xml file.
2027
2028 **/
2029 private void createTokenInDBFromFPD()
2030 throws EntityException {
2031 int index = 0;
2032 int index2 = 0;
2033 int pcdIndex = 0;
2034 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();
2035 PcdBuildDefinition.PcdData pcdBuildData = null;
2036 Token token = null;
2037 SkuInstance skuInstance = null;
2038 int skuIndex = 0;
2039 List<ModuleInfo> modules = null;
2040 String primaryKey = null;
2041 String exceptionString = null;
2042 UsageInstance usageInstance = null;
2043 String primaryKey1 = null;
2044 String primaryKey2 = null;
2045 boolean isDuplicate = false;
2046 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
2047 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
2048 int tokenNumber = 0;
2049 String moduleName = null;
2050 String datum = null;
2051 int maxDatumSize = 0;
2052
2053 //
2054 // ----------------------------------------------
2055 // 1), Get all <ModuleSA> from FPD file.
2056 // ----------------------------------------------
2057 //
2058 modules = getComponentsFromFPD();
2059
2060 if (modules == null) {
2061 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
2062 }
2063
2064 //
2065 // -------------------------------------------------------------------
2066 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
2067 // -------------------------------------------------------------------
2068 //
2069 for (index = 0; index < modules.size(); index ++) {
2070 isDuplicate = false;
2071 for (index2 = 0; index2 < index; index2 ++) {
2072 //
2073 // BUGBUG: For transition schema, we can *not* get module's version from
2074 // <ModuleSAs>, It is work around code.
2075 //
2076 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(),
2077 null,
2078 null,
2079 null,
2080 modules.get(index).module.getArch().toString(),
2081 null);
2082 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(),
2083 null,
2084 null,
2085 null,
2086 modules.get(index2).module.getArch().toString(),
2087 null);
2088 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {
2089 isDuplicate = true;
2090 break;
2091 }
2092 }
2093
2094 if (isDuplicate) {
2095 continue;
2096 }
2097
2098 //
2099 // It is legal for a module does not contains ANY pcd build definitions.
2100 //
2101 if (modules.get(index).module.getPcdBuildDefinition() == null) {
2102 continue;
2103 }
2104
2105 pcdBuildDataArray = modules.get(index).module.getPcdBuildDefinition().getPcdDataList();
2106
2107 moduleName = modules.get(index).module.getModuleName();
2108
2109 //
2110 // ----------------------------------------------------------------------
2111 // 2.1), Loop all Pcd entry for a module and add it into memory database.
2112 // ----------------------------------------------------------------------
2113 //
2114 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {
2115 pcdBuildData = pcdBuildDataArray.get(pcdIndex);
2116 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),
2117 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
2118 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
2119 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
2120 tokenNumber = Integer.decode(pcdBuildData.getToken().toString());
2121 if (pcdBuildData.getValue() != null) {
2122 datum = pcdBuildData.getValue().toString();
2123 } else {
2124 datum = null;
2125 }
2126 maxDatumSize = pcdBuildData.getMaxDatumSize();
2127
2128 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&
2129 (datumType != Token.DATUM_TYPE.BOOLEAN)){
2130 exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+
2131 "datum type of this PCD entry is not BOOLEAN!",
2132 pcdBuildData.getCName(),
2133 moduleName);
2134 throw new EntityException(exceptionString);
2135 }
2136
2137 //
2138 // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools
2139 // will check that, following checking code could be removed.
2140 //
2141 if (pcdBuildData.getTokenSpaceGuid() == null) {
2142 exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in module %s! This is required!",
2143 pcdBuildData.getCName(),
2144 moduleName);
2145 throw new EntityException(exceptionString);
2146 }
2147
2148 //
2149 // -------------------------------------------------------------------------------------------
2150 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
2151 // -------------------------------------------------------------------------------------------
2152 //
2153 if (!Token.isDynamic(pcdType)) {
2154 //
2155 // Value is required.
2156 //
2157 if (datum == null) {
2158 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",
2159 pcdBuildData.getCName(),
2160 moduleName);
2161 throw new EntityException(exceptionString);
2162 }
2163
2164 //
2165 // Check whether the datum size is matched datum type.
2166 //
2167 if ((exceptionString = verifyDatum(pcdBuildData.getCName(),
2168 moduleName,
2169 datum,
2170 datumType,
2171 maxDatumSize)) != null) {
2172 throw new EntityException(exceptionString);
2173 }
2174 }
2175
2176 //
2177 // ---------------------------------------------------------------------------------
2178 // 2.1.2), Create token or update token information for current anaylized PCD data.
2179 // ---------------------------------------------------------------------------------
2180 //
2181 if (dbManager.isTokenInDatabase(primaryKey)) {
2182 //
2183 // If the token is already exist in database, do some necessary checking
2184 // and add a usage instance into this token in database
2185 //
2186 token = dbManager.getTokenByKey(primaryKey);
2187
2188 //
2189 // checking for DatumType, DatumType should be unique for one PCD used in different
2190 // modules.
2191 //
2192 if (token.datumType != datumType) {
2193 exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",
2194 pcdBuildData.getCName(),
2195 pcdBuildData.getDatumType().toString(),
2196 Token.getStringOfdatumType(token.datumType));
2197 throw new EntityException(exceptionString);
2198 }
2199
2200 //
2201 // Check token number is valid
2202 //
2203 if (tokenNumber != token.tokenNumber) {
2204 exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",
2205 pcdBuildData.getCName(),
2206 moduleName);
2207 throw new EntityException(exceptionString);
2208 }
2209
2210 //
2211 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
2212 //
2213 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {
2214 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+
2215 "is different with others module's",
2216 token.cName,
2217 moduleName);
2218 throw new EntityException(exceptionString);
2219 }
2220
2221 if (token.isDynamicPCD) {
2222 //
2223 // Check datum is equal the datum in dynamic information.
2224 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,
2225 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.
2226 //
2227 if (!token.isSkuEnable() &&
2228 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&
2229 (datum != null)) {
2230 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {
2231 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+
2232 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+
2233 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",
2234 token.cName,
2235 moduleName);
2236 throw new EntityException(exceptionString);
2237 }
2238 }
2239
2240 if ((maxDatumSize != 0) &&
2241 (maxDatumSize != token.datumSize)){
2242 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+
2243 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",
2244 token.cName,
2245 moduleName,
2246 maxDatumSize,
2247 token.datumSize);
2248 throw new EntityException(exceptionString);
2249 }
2250 }
2251
2252 } else {
2253 //
2254 // If the token is not in database, create a new token instance and add
2255 // a usage instance into this token in database.
2256 //
2257 token = new Token(pcdBuildData.getCName(),
2258 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
2259
2260 token.datumType = datumType;
2261 token.tokenNumber = tokenNumber;
2262 token.isDynamicPCD = Token.isDynamic(pcdType);
2263 token.datumSize = maxDatumSize;
2264
2265 if (token.isDynamicPCD) {
2266 //
2267 // For Dynamic and Dynamic Ex type, need find the dynamic information
2268 // in <DynamicPcdBuildDefinition> section in FPD file.
2269 //
2270 updateDynamicInformation(moduleName,
2271 token,
2272 datum,
2273 maxDatumSize);
2274 }
2275
2276 dbManager.addTokenToDatabase(primaryKey, token);
2277 }
2278
2279 //
2280 // -----------------------------------------------------------------------------------
2281 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
2282 // -----------------------------------------------------------------------------------
2283 //
2284 token.updateSupportPcdType(pcdType);
2285
2286 //
2287 // ------------------------------------------------
2288 // 2.1.4), Create an usage instance for this token.
2289 // ------------------------------------------------
2290 //
2291 usageInstance = new UsageInstance(token,
2292 moduleName,
2293 null,
2294 null,
2295 null,
2296 modules.get(index).type,
2297 pcdType,
2298 modules.get(index).module.getArch().toString(),
2299 null,
2300 datum,
2301 maxDatumSize);
2302 token.addUsageInstance(usageInstance);
2303 }
2304 }
2305 }
2306
2307 /**
2308 Verify the datum value according its datum size and datum type, this
2309 function maybe moved to FPD verification tools in future.
2310
2311 @param cName
2312 @param moduleName
2313 @param datum
2314 @param datumType
2315 @param maxDatumSize
2316
2317 @return String
2318 */
2319 /***/
2320 public String verifyDatum(String cName,
2321 String moduleName,
2322 String datum,
2323 Token.DATUM_TYPE datumType,
2324 int maxDatumSize) {
2325 String exceptionString = null;
2326 int value;
2327 BigInteger value64;
2328 String subStr;
2329 int index;
2330
2331 if (moduleName == null) {
2332 moduleName = "section <DynamicPcdBuildDefinitions>";
2333 } else {
2334 moduleName = "module " + moduleName;
2335 }
2336
2337 if (maxDatumSize == 0) {
2338 exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",
2339 cName,
2340 moduleName);
2341 return exceptionString;
2342 }
2343
2344 switch (datumType) {
2345 case UINT8:
2346 if (maxDatumSize != 1) {
2347 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2348 "is UINT8, but datum size is %d, they are not matched!",
2349 cName,
2350 moduleName,
2351 maxDatumSize);
2352 return exceptionString;
2353 }
2354
2355 if (datum != null) {
2356 try {
2357 value = Integer.decode(datum);
2358 } catch (NumberFormatException nfeExp) {
2359 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+
2360 "digital format of UINT8",
2361 cName,
2362 moduleName);
2363 return exceptionString;
2364 }
2365 if (value > 0xFF) {
2366 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+
2367 " the max size of UINT8 - 0xFF",
2368 cName,
2369 moduleName,
2370 datum);
2371 return exceptionString;
2372 }
2373 }
2374 break;
2375 case UINT16:
2376 if (maxDatumSize != 2) {
2377 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2378 "is UINT16, but datum size is %d, they are not matched!",
2379 cName,
2380 moduleName,
2381 maxDatumSize);
2382 return exceptionString;
2383 }
2384 if (datum != null) {
2385 try {
2386 value = Integer.decode(datum);
2387 } catch (NumberFormatException nfeExp) {
2388 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+
2389 "not valid digital of UINT16",
2390 cName,
2391 moduleName);
2392 return exceptionString;
2393 }
2394 if (value > 0xFFFF) {
2395 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
2396 "which exceed the range of UINT16 - 0xFFFF",
2397 cName,
2398 moduleName,
2399 datum);
2400 return exceptionString;
2401 }
2402 }
2403 break;
2404 case UINT32:
2405 if (maxDatumSize != 4) {
2406 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2407 "is UINT32, but datum size is %d, they are not matched!",
2408 cName,
2409 moduleName,
2410 maxDatumSize);
2411 return exceptionString;
2412 }
2413
2414 if (datum != null) {
2415 try {
2416 if (datum.length() > 2) {
2417 if ((datum.charAt(0) == '0') &&
2418 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
2419 subStr = datum.substring(2, datum.length());
2420 value64 = new BigInteger(subStr, 16);
2421 } else {
2422 value64 = new BigInteger(datum);
2423 }
2424 } else {
2425 value64 = new BigInteger(datum);
2426 }
2427 } catch (NumberFormatException nfeExp) {
2428 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+
2429 "valid digital of UINT32",
2430 cName,
2431 moduleName);
2432 return exceptionString;
2433 }
2434
2435 if (value64.bitLength() > 32) {
2436 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+
2437 "exceed the range of UINT32 - 0xFFFFFFFF",
2438 cName,
2439 moduleName,
2440 datum);
2441 return exceptionString;
2442 }
2443 }
2444 break;
2445 case UINT64:
2446 if (maxDatumSize != 8) {
2447 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2448 "is UINT64, but datum size is %d, they are not matched!",
2449 cName,
2450 moduleName,
2451 maxDatumSize);
2452 return exceptionString;
2453 }
2454
2455 if (datum != null) {
2456 try {
2457 if (datum.length() > 2) {
2458 if ((datum.charAt(0) == '0') &&
2459 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
2460 subStr = datum.substring(2, datum.length());
2461 value64 = new BigInteger(subStr, 16);
2462 } else {
2463 value64 = new BigInteger(datum);
2464 }
2465 } else {
2466 value64 = new BigInteger(datum);
2467 }
2468 } catch (NumberFormatException nfeExp) {
2469 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+
2470 " digital of UINT64",
2471 cName,
2472 moduleName);
2473 return exceptionString;
2474 }
2475
2476 if (value64.bitLength() > 64) {
2477 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
2478 "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",
2479 cName,
2480 moduleName,
2481 datum);
2482 return exceptionString;
2483 }
2484 }
2485 break;
2486 case BOOLEAN:
2487 if (maxDatumSize != 1) {
2488 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2489 "is BOOLEAN, but datum size is %d, they are not matched!",
2490 cName,
2491 moduleName,
2492 maxDatumSize);
2493 return exceptionString;
2494 }
2495
2496 if (datum != null) {
2497 if (!(datum.equalsIgnoreCase("TRUE") ||
2498 datum.equalsIgnoreCase("FALSE"))) {
2499 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2500 "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",
2501 cName,
2502 moduleName);
2503 return exceptionString;
2504 }
2505
2506 }
2507 break;
2508 case POINTER:
2509 if (datum == null) {
2510 break;
2511 }
2512
2513 char ch = datum.charAt(0);
2514 int start, end;
2515 String strValue;
2516 //
2517 // For void* type PCD, only three datum is support:
2518 // 1) Unicode: string with start char is "L"
2519 // 2) Ansci: String start char is ""
2520 // 3) byte array: String start char "{"
2521 //
2522 if (ch == 'L') {
2523 start = datum.indexOf('\"');
2524 end = datum.lastIndexOf('\"');
2525 if ((start > end) ||
2526 (end > datum.length())||
2527 ((start == end) && (datum.length() > 0))) {
2528 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+
2529 "a UNICODE string because start with L\", but format maybe"+
2530 "is not right, correct UNICODE string is L\"...\"!",
2531 cName,
2532 moduleName);
2533 return exceptionString;
2534 }
2535
2536 strValue = datum.substring(start + 1, end);
2537 if ((strValue.length() * 2) > maxDatumSize) {
2538 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+
2539 "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",
2540 cName,
2541 moduleName,
2542 strValue.length() * 2,
2543 maxDatumSize);
2544 return exceptionString;
2545 }
2546 } else if (ch == '\"'){
2547 start = datum.indexOf('\"');
2548 end = datum.lastIndexOf('\"');
2549 if ((start > end) ||
2550 (end > datum.length())||
2551 ((start == end) && (datum.length() > 0))) {
2552 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+
2553 "a ANSCII string because start with \", but format maybe"+
2554 "is not right, correct ANSIC string is \"...\"!",
2555 cName,
2556 moduleName);
2557 return exceptionString;
2558 }
2559 strValue = datum.substring(start + 1, end);
2560 if ((strValue.length()) > maxDatumSize) {
2561 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+
2562 "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",
2563 cName,
2564 moduleName,
2565 strValue.length(),
2566 maxDatumSize);
2567 return exceptionString;
2568 }
2569 } else if (ch =='{') {
2570 String[] strValueArray;
2571
2572 start = datum.indexOf('{');
2573 end = datum.lastIndexOf('}');
2574 strValue = datum.substring(start + 1, end);
2575 strValue = strValue.trim();
2576 if (strValue.length() == 0) {
2577 break;
2578 }
2579 strValueArray = strValue.split(",");
2580 for (index = 0; index < strValueArray.length; index ++) {
2581 try{
2582 value = Integer.decode(strValueArray[index].trim());
2583 } catch (NumberFormatException nfeEx) {
2584 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+
2585 "it is byte array in fact. For every byte in array should be a valid"+
2586 "byte digital, but element %s is not a valid byte digital!",
2587 cName,
2588 moduleName,
2589 strValueArray[index]);
2590 return exceptionString;
2591 }
2592 if (value > 0xFF) {
2593 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+
2594 "it is byte array in fact. But the element of %s exceed the byte range",
2595 cName,
2596 moduleName,
2597 strValueArray[index]);
2598 return exceptionString;
2599 }
2600 }
2601
2602 if (strValueArray.length > maxDatumSize) {
2603 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+
2604 "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",
2605 cName,
2606 moduleName,
2607 strValueArray.length,
2608 maxDatumSize);
2609 return exceptionString;
2610 }
2611 } else {
2612 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+
2613 "1) UNICODE string: like L\"xxxx\";\r\n"+
2614 "2) ANSIC string: like \"xxx\";\r\n"+
2615 "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+
2616 "But the datum in seems does not following above format!",
2617 cName,
2618 moduleName);
2619 return exceptionString;
2620 }
2621 break;
2622 default:
2623 exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+
2624 "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",
2625 cName,
2626 moduleName);
2627 return exceptionString;
2628 }
2629 return null;
2630 }
2631
2632 /**
2633 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
2634
2635 This function should be implemented in GlobalData in future.
2636
2637 @param token The token instance which has hold module's PCD information
2638 @param moduleName The name of module who will use this Dynamic PCD.
2639
2640 @return DynamicPcdBuildDefinitions.PcdBuildData
2641 */
2642 /***/
2643 private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,
2644 String moduleName)
2645 throws EntityException {
2646 int index = 0;
2647 String exceptionString = null;
2648 String dynamicPrimaryKey = null;
2649 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
2650 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
2651
2652 //
2653 // If FPD document is not be opened, open and initialize it.
2654 //
2655 if (fpdDocInstance == null) {
2656 try {
2657 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
2658 } catch(IOException ioE) {
2659 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
2660 } catch(XmlException xmlE) {
2661 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
2662 }
2663 }
2664
2665 dynamicPcdBuildDefinitions = fpdDocInstance.getFrameworkPlatformDescription().getDynamicPcdBuildDefinitions();
2666 if (dynamicPcdBuildDefinitions == null) {
2667 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+
2668 "PCD entry %s in module %s!",
2669 token.cName,
2670 moduleName);
2671 throw new EntityException(exceptionString);
2672 }
2673
2674 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
2675 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
2676 //
2677 // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools
2678 // will check that, following checking code could be removed.
2679 //
2680 if (dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid() == null) {
2681 exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in <DynamicPcdBuildDefinitions>! This is required!",
2682 dynamicPcdBuildDataArray.get(index).getCName());
2683 throw new EntityException(exceptionString);
2684 }
2685
2686 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
2687 translateSchemaStringToUUID(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid()));
2688 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {
2689 return dynamicPcdBuildDataArray.get(index);
2690 }
2691 }
2692
2693 return null;
2694 }
2695
2696 /**
2697 Update dynamic information for PCD entry.
2698
2699 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
2700 FPD file.
2701
2702 @param moduleName The name of the module who use this PCD
2703 @param token The token instance
2704 @param datum The <datum> in module's PCD information
2705 @param maxDatumSize The <maxDatumSize> in module's PCD information
2706
2707 @return Token
2708 */
2709 private Token updateDynamicInformation(String moduleName,
2710 Token token,
2711 String datum,
2712 int maxDatumSize)
2713 throws EntityException {
2714 int index = 0;
2715 int offset;
2716 String exceptionString = null;
2717 DynamicTokenValue dynamicValue;
2718 SkuInstance skuInstance = null;
2719 String temp;
2720 boolean hasSkuId0 = false;
2721 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
2722 int tokenNumber = 0;
2723 String hiiDefaultValue = null;
2724 String[] variableGuidString = null;
2725
2726 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;
2727 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;
2728
2729 dynamicInfo = getDynamicInfoFromFPD(token, moduleName);
2730 if (dynamicInfo == null) {
2731 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+
2732 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+
2733 "in FPD file, but it is required!",
2734 token.cName,
2735 moduleName);
2736 throw new EntityException(exceptionString);
2737 }
2738
2739 token.datumSize = dynamicInfo.getMaxDatumSize();
2740
2741 exceptionString = verifyDatum(token.cName,
2742 moduleName,
2743 null,
2744 token.datumType,
2745 token.datumSize);
2746 if (exceptionString != null) {
2747 throw new EntityException(exceptionString);
2748 }
2749
2750 if ((maxDatumSize != 0) &&
2751 (maxDatumSize != token.datumSize)) {
2752 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+
2753 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",
2754 token.cName,
2755 moduleName,
2756 maxDatumSize,
2757 dynamicInfo.getMaxDatumSize());
2758 throw new EntityException(exceptionString);
2759 }
2760 tokenNumber = Integer.decode(dynamicInfo.getToken().toString());
2761 if (tokenNumber != token.tokenNumber) {
2762 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+
2763 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",
2764 token.cName,
2765 moduleName,
2766 token.tokenNumber,
2767 tokenNumber);
2768 throw new EntityException(exceptionString);
2769 }
2770
2771 pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());
2772 if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
2773 token.dynamicExTokenNumber = tokenNumber;
2774 }
2775
2776 skuInfoList = dynamicInfo.getSkuInfoList();
2777
2778 //
2779 // Loop all sku data
2780 //
2781 for (index = 0; index < skuInfoList.size(); index ++) {
2782 skuInstance = new SkuInstance();
2783 //
2784 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
2785 //
2786 temp = skuInfoList.get(index).getSkuId().toString();
2787 skuInstance.id = Integer.decode(temp);
2788 if (skuInstance.id == 0) {
2789 hasSkuId0 = true;
2790 }
2791 //
2792 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
2793 //
2794 if (skuInfoList.get(index).getValue() != null) {
2795 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());
2796 if ((exceptionString = verifyDatum(token.cName,
2797 null,
2798 skuInfoList.get(index).getValue().toString(),
2799 token.datumType,
2800 token.datumSize)) != null) {
2801 throw new EntityException(exceptionString);
2802 }
2803
2804 token.skuData.add(skuInstance);
2805
2806 //
2807 // Judege wether is same of datum between module's information
2808 // and dynamic information.
2809 //
2810 if (datum != null) {
2811 if ((skuInstance.id == 0) &&
2812 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {
2813 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+
2814 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+
2815 " or you could not define value for a dynamic PCD in every <ModuleSA>!";
2816 throw new EntityException(exceptionString);
2817 }
2818 }
2819 continue;
2820 }
2821
2822 //
2823 // Judge whether is HII group case.
2824 //
2825 if (skuInfoList.get(index).getVariableName() != null) {
2826 exceptionString = null;
2827 if (skuInfoList.get(index).getVariableGuid() == null) {
2828 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2829 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
2830 token.cName,
2831 index);
2832 if (exceptionString != null) {
2833 throw new EntityException(exceptionString);
2834 }
2835 }
2836
2837 if (skuInfoList.get(index).getVariableOffset() == null) {
2838 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2839 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
2840 token.cName,
2841 index);
2842 if (exceptionString != null) {
2843 throw new EntityException(exceptionString);
2844 }
2845 }
2846
2847 if (skuInfoList.get(index).getHiiDefaultValue() == null) {
2848 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2849 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
2850 token.cName,
2851 index);
2852 if (exceptionString != null) {
2853 throw new EntityException(exceptionString);
2854 }
2855 }
2856
2857 if (skuInfoList.get(index).getHiiDefaultValue() != null) {
2858 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();
2859 } else {
2860 hiiDefaultValue = null;
2861 }
2862
2863 if ((exceptionString = verifyDatum(token.cName,
2864 null,
2865 hiiDefaultValue,
2866 token.datumType,
2867 token.datumSize)) != null) {
2868 throw new EntityException(exceptionString);
2869 }
2870
2871 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());
2872 if (offset > 0xFFFF) {
2873 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+
2874 "exceed 64K, it is not allowed!",
2875 token.cName,
2876 index));
2877 }
2878
2879 //
2880 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
2881 //
2882 variableGuidString = GlobalData.getGuidInfoGuid(skuInfoList.get(index).getVariableGuid().toString());
2883 if (variableGuidString == null) {
2884 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",
2885 token.cName,
2886 skuInfoList.get(index).getVariableGuid().toString()));
2887 }
2888
2889 skuInstance.value.setHiiData(skuInfoList.get(index).getVariableName(),
2890 translateSchemaStringToUUID(variableGuidString[1]),
2891 skuInfoList.get(index).getVariableOffset(),
2892 skuInfoList.get(index).getHiiDefaultValue().toString());
2893 token.skuData.add(skuInstance);
2894 continue;
2895 }
2896
2897 if (skuInfoList.get(index).getVpdOffset() != null) {
2898 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());
2899 token.skuData.add(skuInstance);
2900 continue;
2901 }
2902
2903 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+
2904 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
2905 token.cName);
2906 throw new EntityException(exceptionString);
2907 }
2908
2909 if (!hasSkuId0) {
2910 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
2911 "no sku id = 0 data, which is required for every dynamic PCD",
2912 token.cName);
2913 throw new EntityException(exceptionString);
2914 }
2915
2916 return token;
2917 }
2918
2919 /**
2920 Translate the schema string to UUID instance.
2921
2922 In schema, the string of UUID is defined as following two types string:
2923 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
2924 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
2925
2926 2) GuidNamingConvention: pattern =
2927 [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}
2928
2929 This function will convert string and create uuid instance.
2930
2931 @param uuidString UUID string in XML file
2932
2933 @return UUID UUID instance
2934 **/
2935 private UUID translateSchemaStringToUUID(String uuidString)
2936 throws EntityException {
2937 String temp;
2938 String[] splitStringArray;
2939 int index;
2940 int chIndex;
2941 int chLen;
2942
2943 if (uuidString == null) {
2944 return null;
2945 }
2946
2947 if (uuidString.length() == 0) {
2948 return null;
2949 }
2950
2951 if (uuidString.equals("0") ||
2952 uuidString.equalsIgnoreCase("0x0")) {
2953 return new UUID(0, 0);
2954 }
2955
2956 uuidString = uuidString.replaceAll("\\{", "");
2957 uuidString = uuidString.replaceAll("\\}", "");
2958
2959 //
2960 // If the UUID schema string is GuidArrayType type then need translate
2961 // to GuidNamingConvention type at first.
2962 //
2963 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
2964 splitStringArray = uuidString.split("," );
2965 if (splitStringArray.length != 11) {
2966 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
2967 }
2968
2969 //
2970 // Remove blank space from these string and remove header string "0x"
2971 //
2972 for (index = 0; index < 11; index ++) {
2973 splitStringArray[index] = splitStringArray[index].trim();
2974 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
2975 }
2976
2977 //
2978 // Add heading '0' to normalize the string length
2979 //
2980 for (index = 3; index < 11; index ++) {
2981 chLen = splitStringArray[index].length();
2982 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
2983 splitStringArray[index] = "0" + splitStringArray[index];
2984 }
2985 }
2986
2987 //
2988 // construct the final GuidNamingConvention string
2989 //
2990 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
2991 splitStringArray[0],
2992 splitStringArray[1],
2993 splitStringArray[2],
2994 splitStringArray[3],
2995 splitStringArray[4],
2996 splitStringArray[5],
2997 splitStringArray[6],
2998 splitStringArray[7],
2999 splitStringArray[8],
3000 splitStringArray[9],
3001 splitStringArray[10]);
3002 uuidString = temp;
3003 }
3004
3005 return UUID.fromString(uuidString);
3006 }
3007
3008 /**
3009 check parameter for this action.
3010
3011 @throws EntityException Bad parameter.
3012 **/
3013 private void checkParameter() throws EntityException {
3014 File file = null;
3015
3016 if((fpdFilePath == null) ||(workspacePath == null)) {
3017 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
3018 }
3019
3020 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
3021 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
3022 }
3023
3024 file = new File(workspacePath);
3025 if(!file.exists()) {
3026 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
3027 }
3028
3029 file = new File(fpdFilePath);
3030
3031 if(!file.exists()) {
3032 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
3033 }
3034 }
3035
3036 /**
3037 Test case function
3038
3039 @param argv parameter from command line
3040 **/
3041 public static void main(String argv[]) throws EntityException {
3042 CollectPCDAction ca = new CollectPCDAction();
3043 ca.setWorkspacePath("m:/tianocore/edk2");
3044 ca.setFPDFilePath("m:/tianocore/edk2/EdkNt32Pkg/Nt32.fpd");
3045 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
3046 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
3047 "m:/tianocore/edk2");
3048 ca.execute();
3049 }
3050 }