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