2 CollectPCDAction class.
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.
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
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.
18 package org
.tianocore
.build
.pcd
.action
;
20 import java
.io
.BufferedReader
;
22 import java
.io
.FileReader
;
23 import java
.io
.IOException
;
24 import java
.util
.ArrayList
;
25 import java
.util
.Collections
;
26 import java
.util
.Comparator
;
27 import java
.util
.HashMap
;
28 import java
.util
.List
;
30 import java
.util
.UUID
;
32 import org
.apache
.xmlbeans
.XmlException
;
33 import org
.apache
.xmlbeans
.XmlObject
;
34 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
;
35 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
;
36 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
;
37 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
.PcdBuildData
;
38 import org
.tianocore
.FrameworkModulesDocument
;
39 import org
.tianocore
.FrameworkPlatformDescriptionDocument
;
40 import org
.tianocore
.FrameworkPlatformDescriptionDocument
.FrameworkPlatformDescription
;
41 import org
.tianocore
.ModuleSADocument
;
42 import org
.tianocore
.ModuleSADocument
.ModuleSA
;
43 import org
.tianocore
.PackageSurfaceAreaDocument
;
44 import org
.tianocore
.PcdBuildDefinitionDocument
.PcdBuildDefinition
;
45 import org
.tianocore
.build
.global
.GlobalData
;
46 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
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
;
56 private ArrayList
<String
> al
;
57 private ArrayList
<String
> alComments
;
63 public StringTable (String phase
) {
65 al
= new ArrayList
<String
>();
66 alComments
= new ArrayList
<String
>();
72 public String
getSizeMacro () {
73 return String
.format(PcdDatabase
.StringTableSizeMacro
, phase
, getSize());
76 private int getSize () {
78 // We have at least one Unicode Character in the table.
80 return len
== 0 ?
1 : len
;
83 public int getTableLen () {
84 return al
.size() == 0 ?
1 : al
.size();
87 public String
getExistanceMacro () {
88 return String
.format(PcdDatabase
.StringTableExistenceMacro
, phase
, (al
.size() == 0)?
"TRUE":"FALSE");
91 public String
getTypeDeclaration () {
95 final String stringTable
= "StringTable";
96 final String tab
= "\t";
97 final String newLine
= ";\r\n";
99 output
= "/* StringTable */\r\n";
101 if (al
.size() == 0) {
102 output
+= tab
+ String
.format("UINT16 %s[1] /* StringTable is Empty */", stringTable
) + newLine
;
105 for (int i
= 0; i
< al
.size(); i
++) {
106 String str
= al
.get(i
);
110 // StringTable is a well-known name in the PCD DXE driver
112 output
+= tab
+ String
.format("UINT16 %s[%d] /* %s */", stringTable
, str
.length() + 1, alComments
.get(i
)) + newLine
;
114 output
+= tab
+ String
.format("UINT16 %s_%d[%d] /* %s */", stringTable
, i
, str
.length() + 1, alComments
.get(i
)) + newLine
;
122 public ArrayList
<String
> getInstantiation () {
123 ArrayList
<String
> output
= new ArrayList
<String
>();
125 output
.add("/* StringTable */");
127 if (al
.size() == 0) {
132 for (int i
= 0; i
< al
.size(); i
++) {
133 str
= String
.format("L\"%s\" /* %s */", al
.get(i
), alComments
.get(i
));
134 if (i
!= al
.size() - 1) {
144 public int add (String str
, Token token
) {
149 // Include the NULL character at the end of String
151 len
+= str
.length() + 1;
153 alComments
.add(token
.getPrimaryKeyString());
160 private ArrayList
<Integer
> al
;
161 private ArrayList
<String
> alComments
;
162 private String phase
;
164 private int bodyStart
;
165 private int bodyLineNum
;
167 public SizeTable (String phase
) {
169 al
= new ArrayList
<Integer
>();
170 alComments
= new ArrayList
<String
>();
176 public String
getTypeDeclaration () {
177 return String
.format(PcdDatabase
.SizeTableDeclaration
, phase
);
180 public ArrayList
<String
> getInstantiation () {
181 ArrayList
<String
> Output
= new ArrayList
<String
>();
183 Output
.add("/* SizeTable */");
187 if (al
.size() == 0) {
190 for (int index
= 0; index
< al
.size(); index
++) {
191 Integer n
= al
.get(index
);
192 String str
= n
.toString();
194 if (index
!= (al
.size() - 1)) {
198 str
+= " /* " + alComments
.get(index
) + " */";
209 public int getBodyStart() {
213 public int getBodyLineNum () {
217 public int add (Token token
) {
221 al
.add(token
.datumSize
);
222 alComments
.add(token
.getPrimaryKeyString());
227 private int getDatumSize(Token token
) {
229 switch (token.datumType) {
230 case Token.DATUM_TYPE.UINT8:
239 public int getTableLen () {
240 return al
.size() == 0 ?
1 : al
.size();
246 private ArrayList
<UUID
> al
;
247 private ArrayList
<String
> alComments
;
248 private String phase
;
250 private int bodyStart
;
251 private int bodyLineNum
;
253 public GuidTable (String phase
) {
255 al
= new ArrayList
<UUID
>();
256 alComments
= new ArrayList
<String
>();
262 public String
getSizeMacro () {
263 return String
.format(PcdDatabase
.GuidTableSizeMacro
, phase
, getSize());
266 private int getSize () {
267 return (al
.size() == 0)?
1 : al
.size();
270 public String
getExistanceMacro () {
271 return String
.format(PcdDatabase
.GuidTableExistenceMacro
, phase
, (al
.size() == 0)?
"TRUE":"FALSE");
274 public String
getTypeDeclaration () {
275 return String
.format(PcdDatabase
.GuidTableDeclaration
, phase
);
278 private String
getUuidCString (UUID uuid
) {
279 String
[] guidStrArray
;
281 guidStrArray
=(uuid
.toString()).split("-");
283 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 } }",
287 (guidStrArray
[3].substring(0, 2)),
288 (guidStrArray
[3].substring(2, 4)),
289 (guidStrArray
[4].substring(0, 2)),
290 (guidStrArray
[4].substring(2, 4)),
291 (guidStrArray
[4].substring(4, 6)),
292 (guidStrArray
[4].substring(6, 8)),
293 (guidStrArray
[4].substring(8, 10)),
294 (guidStrArray
[4].substring(10, 12))
298 public ArrayList
<String
> getInstantiation () {
299 ArrayList
<String
> Output
= new ArrayList
<String
>();
301 Output
.add("/* GuidTable */");
305 if (al
.size() == 0) {
306 Output
.add(getUuidCString(new UUID(0, 0)));
309 for (Object u
: al
) {
311 String str
= getUuidCString(uuid
);
313 if (al
.indexOf(u
) != (al
.size() - 1)) {
325 public int getBodyStart() {
329 public int getBodyLineNum () {
333 public int add (UUID uuid
, String name
) {
336 // Include the NULL character at the end of String
344 public int getTableLen () {
345 return al
.size() == 0 ?
0 : al
.size();
351 private ArrayList
<Integer
[]> al
;
352 private ArrayList
<String
> alComment
;
353 private String phase
;
355 private int bodyStart
;
356 private int bodyLineNum
;
358 public SkuIdTable (String phase
) {
360 al
= new ArrayList
<Integer
[]>();
361 alComment
= new ArrayList
<String
>();
367 public String
getSizeMacro () {
368 return String
.format(PcdDatabase
.SkuIdTableSizeMacro
, phase
, getSize());
371 private int getSize () {
372 return (al
.size() == 0)?
1 : al
.size();
375 public String
getExistanceMacro () {
376 return String
.format(PcdDatabase
.SkuTableExistenceMacro
, phase
, (al
.size() == 0)?
"TRUE":"FALSE");
379 public String
getTypeDeclaration () {
380 return String
.format(PcdDatabase
.SkuIdTableDeclaration
, phase
);
383 public ArrayList
<String
> getInstantiation () {
384 ArrayList
<String
> Output
= new ArrayList
<String
> ();
386 Output
.add("/* SkuIdTable */");
390 if (al
.size() == 0) {
394 for (int index
= 0; index
< al
.size(); index
++) {
397 str
= "/* " + alComment
.get(index
) + "*/ ";
398 str
+= "/* MaxSku */ ";
401 Integer
[] ia
= al
.get(index
);
403 str
+= ia
[0].toString() + ", ";
404 for (int index2
= 1; index2
< ia
.length
; index2
++) {
405 str
+= ia
[index2
].toString();
406 if (index
!= al
.size() - 1) {
421 public int add (Token token
) {
425 Integer
[] skuIds
= new Integer
[token
.skuData
.size() + 1];
426 skuIds
[0] = new Integer(token
.skuData
.size());
427 for (index
= 1; index
< skuIds
.length
; index
++) {
428 skuIds
[index
] = new Integer(token
.skuData
.get(index
- 1).id
);
433 len
+= skuIds
.length
;
435 alComment
.add(token
.getPrimaryKeyString());
440 public int getTableLen () {
441 return al
.size() == 0 ?
1 : al
.size();
446 class LocalTokenNumberTable
{
447 private ArrayList
<String
> al
;
448 private ArrayList
<String
> alComment
;
449 private String phase
;
452 public LocalTokenNumberTable (String phase
) {
454 al
= new ArrayList
<String
>();
455 alComment
= new ArrayList
<String
>();
460 public String
getSizeMacro () {
461 return String
.format(PcdDatabase
.LocalTokenNumberTableSizeMacro
, phase
, getSize())
462 + String
.format(PcdDatabase
.LocalTokenNumberSizeMacro
, phase
, al
.size());
465 public int getSize () {
466 return (al
.size() == 0)?
1 : al
.size();
469 public String
getExistanceMacro () {
470 return String
.format(PcdDatabase
.DatabaseExistenceMacro
, phase
, (al
.size() == 0)?
"TRUE":"FALSE");
473 public String
getTypeDeclaration () {
474 return String
.format(PcdDatabase
.LocalTokenNumberTableDeclaration
, phase
);
477 public ArrayList
<String
> getInstantiation () {
478 ArrayList
<String
> output
= new ArrayList
<String
>();
480 output
.add("/* LocalTokenNumberTable */");
483 if (al
.size() == 0) {
487 for (int index
= 0; index
< al
.size(); index
++) {
490 str
= (String
)al
.get(index
);
492 str
+= " /* " + alComment
.get(index
) + " */ ";
495 if (index
!= (al
.size() - 1)) {
508 public int add (Token token
) {
514 str
= String
.format(PcdDatabase
.offsetOfStrTemplate
, phase
, token
.hasDefaultValue() ?
"Init" : "Uninit", token
.getPrimaryKeyString());
516 if (token
.isStringType()) {
517 str
+= " | PCD_TYPE_STRING";
520 if (token
.isSkuEnable()) {
521 str
+= " | PCD_TYPE_SKU_ENABLED";
524 if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
525 str
+= " | PCD_TYPE_HII";
528 if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
529 str
+= " | PCD_TYPE_VPD";
533 alComment
.add(token
.getPrimaryKeyString());
542 public Integer guidTableIdx
;
543 public Long exTokenNumber
;
544 public Long localTokenIdx
;
546 public ExTriplet (int guidTableIdx
, long exTokenNumber
, long localTokenIdx
) {
547 this.guidTableIdx
= new Integer(guidTableIdx
);
548 this.exTokenNumber
= new Long(exTokenNumber
);
549 this.localTokenIdx
= new Long(localTokenIdx
);
553 private ArrayList
<ExTriplet
> al
;
554 private ArrayList
<String
> alComment
;
555 private String phase
;
557 private int bodyStart
;
558 private int bodyLineNum
;
561 public ExMapTable (String phase
) {
563 al
= new ArrayList
<ExTriplet
>();
564 alComment
= new ArrayList
<String
>();
570 public String
getSizeMacro () {
571 return String
.format(PcdDatabase
.ExMapTableSizeMacro
, phase
, getTableLen())
572 + String
.format(PcdDatabase
.ExTokenNumber
, phase
, al
.size());
575 private int getSize () {
576 return (al
.size() == 0)?
1 : al
.size();
579 public String
getExistanceMacro () {
580 return String
.format(PcdDatabase
.ExMapTableExistenceMacro
, phase
, (al
.size() == 0)?
"TRUE":"FALSE");
583 public String
getTypeDeclaration () {
584 return String
.format(PcdDatabase
.ExMapTableDeclaration
, phase
);
587 public ArrayList
<String
> getInstantiation () {
588 ArrayList
<String
> Output
= new ArrayList
<String
>();
590 Output
.add("/* ExMapTable */");
594 if (al
.size() == 0) {
595 Output
.add("{0, 0, 0}");
599 for (index
= 0; index
< al
.size(); index
++) {
602 ExTriplet e
= (ExTriplet
)al
.get(index
);
604 str
= "{ " + e
.exTokenNumber
.toString() + ", ";
605 str
+= e
.localTokenIdx
.toString() + ", ";
606 str
+= e
.guidTableIdx
.toString();
608 str
+= " /* " + alComment
.get(index
) + " */";
610 if (index
!= al
.size() - 1) {
624 public int add (int localTokenIdx
, long exTokenNum
, int guidTableIdx
, String name
) {
628 al
.add(new ExTriplet(guidTableIdx
, exTokenNum
, localTokenIdx
));
634 public int getTableLen () {
635 return al
.size() == 0 ?
1 : al
.size();
642 public final static String ExMapTableDeclaration
= "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
643 public final static String GuidTableDeclaration
= "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
644 public final static String LocalTokenNumberTableDeclaration
= "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
645 public final static String StringTableDeclaration
= "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
646 public final static String SizeTableDeclaration
= "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
647 public final static String SkuIdTableDeclaration
= "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
650 public final static String ExMapTableSizeMacro
= "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
651 public final static String ExTokenNumber
= "#define %s_EX_TOKEN_NUMBER %d\r\n";
652 public final static String GuidTableSizeMacro
= "#define %s_GUID_TABLE_SIZE %d\r\n";
653 public final static String LocalTokenNumberTableSizeMacro
= "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
654 public final static String LocalTokenNumberSizeMacro
= "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
655 public final static String StringTableSizeMacro
= "#define %s_STRING_TABLE_SIZE %d\r\n";
656 public final static String SkuIdTableSizeMacro
= "#define %s_SKUID_TABLE_SIZE %d\r\n";
659 public final static String ExMapTableExistenceMacro
= "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
660 public final static String GuidTableExistenceMacro
= "#define %s_GUID_TABLE_EMPTY %s\r\n";
661 public final static String DatabaseExistenceMacro
= "#define %s_DATABASE_EMPTY %s\r\n";
662 public final static String StringTableExistenceMacro
= "#define %s_STRING_TABLE_EMPTY %s\r\n";
663 public final static String SkuTableExistenceMacro
= "#define %s_SKUID_TABLE_EMPTY %s\r\n";
665 public final static String offsetOfSkuHeadStrTemplate
= "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
666 public final static String offsetOfStrTemplate
= "offsetof(%s_PCD_DATABASE, %s.%s)";
668 private StringTable stringTable
;
669 private GuidTable guidTable
;
670 private LocalTokenNumberTable localTokenNumberTable
;
671 private SkuIdTable skuIdTable
;
672 private SizeTable sizeTable
;
673 private ExMapTable exMapTable
;
675 private ArrayList
<Token
> alTokens
;
676 private String phase
;
677 private int assignedTokenNumber
;
680 // After Major changes done to the PCD
681 // database generation class PcdDatabase
682 // Please increment the version and please
683 // also update the version number in PCD
684 // service PEIM and DXE driver accordingly.
686 private final int version
= 1;
688 private String hString
;
689 private String cString
;
692 class AlignmentSizeComp
implements Comparator
<Token
> {
693 public int compare (Token a
, Token b
) {
694 return getAlignmentSize(b
)
695 - getAlignmentSize(a
);
699 public PcdDatabase (ArrayList
<Token
> alTokens
, String exePhase
, int startLen
) {
702 stringTable
= new StringTable(phase
);
703 guidTable
= new GuidTable(phase
);
704 localTokenNumberTable
= new LocalTokenNumberTable(phase
);
705 skuIdTable
= new SkuIdTable(phase
);
706 sizeTable
= new SizeTable(phase
);
707 exMapTable
= new ExMapTable(phase
);
709 assignedTokenNumber
= startLen
;
710 this.alTokens
= alTokens
;
713 private void getTwoGroupsOfTokens (ArrayList
<Token
> alTokens
, List
<Token
> initTokens
, List
<Token
> uninitTokens
) {
714 for (int i
= 0; i
< alTokens
.size(); i
++) {
715 Token t
= (Token
)alTokens
.get(i
);
716 if (t
.hasDefaultValue()) {
726 private int getAlignmentSize (Token token
) {
727 if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
731 if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
735 if (token
.isStringType()) {
739 switch (token
.datumType
) {
756 public String
getCString () {
760 public String
getHString () {
764 public void genCode ()
765 throws EntityException
{
767 final String newLine
= "\r\n";
768 final String declNewLine
= ";\r\n";
769 final String tab
= "\t";
770 final String commaNewLine
= ", \r\n";
773 ArrayList
<String
> decla
;
774 ArrayList
<String
> inst
;
776 String macroStr
= "";
777 String initDeclStr
= "";
778 String initInstStr
= "";
779 String uninitDeclStr
= "";
781 List
<Token
> initTokens
= new ArrayList
<Token
> ();
782 List
<Token
> uninitTokens
= new ArrayList
<Token
> ();
784 HashMap
<String
, ArrayList
<String
>> initCode
= new HashMap
<String
, ArrayList
<String
>> ();
785 HashMap
<String
, ArrayList
<String
>> uninitCode
= new HashMap
<String
, ArrayList
<String
>> ();
787 getTwoGroupsOfTokens (alTokens
, initTokens
, uninitTokens
);
790 // Generate Structure Declaration for PcdTokens without Default Value
791 // PEI_PCD_DATABASE_INIT
793 java
.util
.Comparator
<Token
> comparator
= new AlignmentSizeComp();
794 java
.util
.Collections
.sort(initTokens
, comparator
);
795 initCode
= processTokens(initTokens
);
798 // Generate Structure Declaration for PcdTokens without Default Value
799 // PEI_PCD_DATABASE_UNINIT
801 java
.util
.Collections
.sort(uninitTokens
, comparator
);
802 uninitCode
= processTokens(uninitTokens
);
805 // Generate size info Macro for all Tables
807 macroStr
+= guidTable
.getSizeMacro();
808 macroStr
+= stringTable
.getSizeMacro();
809 macroStr
+= skuIdTable
.getSizeMacro();
810 macroStr
+= localTokenNumberTable
.getSizeMacro();
811 macroStr
+= exMapTable
.getSizeMacro();
814 // Generate existance info Macro for all Tables
816 macroStr
+= guidTable
.getExistanceMacro();
817 macroStr
+= stringTable
.getExistanceMacro();
818 macroStr
+= skuIdTable
.getExistanceMacro();
819 macroStr
+= localTokenNumberTable
.getExistanceMacro();
820 macroStr
+= exMapTable
.getExistanceMacro();
823 // Generate Structure Declaration for PcdTokens with Default Value
824 // for example PEI_PCD_DATABASE_INIT
826 initDeclStr
+= "typedef struct {" + newLine
;
828 initDeclStr
+= tab
+ exMapTable
.getTypeDeclaration();
829 initDeclStr
+= tab
+ guidTable
.getTypeDeclaration();
830 initDeclStr
+= tab
+ localTokenNumberTable
.getTypeDeclaration();
831 initDeclStr
+= tab
+ stringTable
.getTypeDeclaration();
832 initDeclStr
+= tab
+ sizeTable
.getTypeDeclaration();
833 initDeclStr
+= tab
+ skuIdTable
.getTypeDeclaration();
834 if (phase
.equalsIgnoreCase("PEI")) {
835 initDeclStr
+= tab
+ "SKU_ID SystemSkuId;" + newLine
;
838 decla
= initCode
.get(new String("Declaration"));
839 for (i
= 0; i
< decla
.size(); i
++) {
840 initDeclStr
+= tab
+ decla
.get(i
) + declNewLine
;
844 // Generate Structure Declaration for PcdToken with SkuEnabled
846 decla
= initCode
.get("DeclarationForSku");
848 for (i
= 0; i
< decla
.size(); i
++) {
849 initDeclStr
+= tab
+ decla
.get(i
) + declNewLine
;
852 initDeclStr
+= String
.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase
);
855 // Generate MACRO for structure intialization of PCDTokens with Default Value
856 // The sequence must match the sequence of declaration of the memembers in the structure
857 String tmp
= String
.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase
.toUpperCase(), phase
.toUpperCase());
858 initInstStr
+= tmp
+ newLine
;
859 initInstStr
+= tab
+ genInstantiationStr(exMapTable
.getInstantiation()) + commaNewLine
;
860 initInstStr
+= tab
+ genInstantiationStr(guidTable
.getInstantiation()) + commaNewLine
;
861 initInstStr
+= tab
+ genInstantiationStr(localTokenNumberTable
.getInstantiation()) + commaNewLine
;
862 initInstStr
+= tab
+ genInstantiationStr(stringTable
.getInstantiation()) + commaNewLine
;
863 initInstStr
+= tab
+ genInstantiationStr(sizeTable
.getInstantiation()) + commaNewLine
;
864 initInstStr
+= tab
+ genInstantiationStr(skuIdTable
.getInstantiation()) + commaNewLine
;
868 if (phase
.equalsIgnoreCase("PEI")) {
869 initInstStr
+= tab
+ "0" + tab
+ "/* SystemSkuId */" + commaNewLine
;
872 inst
= initCode
.get("Instantiation");
873 for (i
= 0; i
< inst
.size(); i
++) {
874 initInstStr
+= tab
+ inst
.get(i
) + commaNewLine
;
877 inst
= initCode
.get("InstantiationForSku");
878 for (i
= 0; i
< inst
.size(); i
++) {
879 initInstStr
+= tab
+ inst
.get(i
);
880 if (i
!= inst
.size() - 1) {
881 initInstStr
+= commaNewLine
;
887 uninitDeclStr
+= "typedef struct {" + newLine
;
889 decla
= uninitCode
.get("Declaration");
890 if (decla
.size() == 0) {
891 uninitDeclStr
+= "UINT8 dummy /* The UINT struct is empty */" + declNewLine
;
894 for (i
= 0; i
< decla
.size(); i
++) {
895 uninitDeclStr
+= tab
+ decla
.get(i
) + declNewLine
;
898 decla
= uninitCode
.get("DeclarationForSku");
900 for (i
= 0; i
< decla
.size(); i
++) {
901 uninitDeclStr
+= tab
+ decla
.get(i
) + declNewLine
;
905 uninitDeclStr
+= String
.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase
);
907 cString
= initInstStr
+ newLine
;
908 hString
= macroStr
+ newLine
909 + initDeclStr
+ newLine
910 + uninitDeclStr
+ newLine
913 hString
+= String
.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase
, version
);
917 private String
genInstantiationStr (ArrayList
<String
> alStr
) {
919 for (int i
= 0; i
< alStr
.size(); i
++) {
920 str
+= "\t" + alStr
.get(i
);
921 if (i
!= alStr
.size() - 1) {
929 private HashMap
<String
, ArrayList
<String
>> processTokens (List
<Token
> alToken
)
930 throws EntityException
{
932 HashMap
<String
, ArrayList
<String
>> map
= new HashMap
<String
, ArrayList
<String
>>();
934 ArrayList
<String
> decl
= new ArrayList
<String
>();
935 ArrayList
<String
> declForSkuEnableType
= new ArrayList
<String
>();
936 ArrayList
<String
> inst
= new ArrayList
<String
>();
937 ArrayList
<String
> instForSkuEnableType
= new ArrayList
<String
>();
939 for (int index
= 0; index
< alToken
.size(); index
++) {
940 Token token
= alToken
.get(index
);
942 if (token
.isSkuEnable()) {
944 // BugBug: Schema only support Data type now
948 tableIdx
= skuIdTable
.add(token
);
950 decl
.add(getSkuEnabledTypeDeclaration(token
));
951 if (token
.hasDefaultValue()) {
952 inst
.add(getSkuEnabledTypeInstantiaion(token
, tableIdx
));
955 declForSkuEnableType
.add(getDataTypeDeclarationForSkuEnabled(token
));
956 if (token
.hasDefaultValue()) {
957 instForSkuEnableType
.add(getDataTypeInstantiationForSkuEnabled(token
));
961 if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
962 decl
.add(getVariableEnableTypeDeclaration(token
));
963 inst
.add(getVariableEnableInstantiation(token
));
964 } else if (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
965 decl
.add(getVpdEnableTypeDeclaration(token
));
966 inst
.add(getVpdEnableTypeInstantiation(token
));
967 } else if (token
.isStringType()) {
968 decl
.add(getStringTypeDeclaration(token
));
969 inst
.add(getStringTypeInstantiation(stringTable
.add(token
.getStringTypeString(), token
), token
));
972 decl
.add(getDataTypeDeclaration(token
));
973 if (token
.hasDefaultValue()) {
974 inst
.add(getDataTypeInstantiation(token
));
979 sizeTable
.add(token
);
980 localTokenNumberTable
.add(token
);
981 token
.tokenNumber
= assignedTokenNumber
++;
985 map
.put("Declaration", decl
);
986 map
.put("DeclarationForSku", declForSkuEnableType
);
987 map
.put("Instantiation", inst
);
988 map
.put("InstantiationForSku", instForSkuEnableType
);
993 private String
getSkuEnabledTypeDeclaration (Token token
) {
994 return String
.format("SKU_HEAD %s;\r\n", token
.getPrimaryKeyString());
997 private String
getSkuEnabledTypeInstantiaion (Token token
, int SkuTableIdx
) {
999 String offsetof
= String
.format(PcdDatabase
.offsetOfSkuHeadStrTemplate
, phase
, token
.hasDefaultValue()?
"Init" : "Uninit", token
.getPrimaryKeyString());
1000 return String
.format("{ %s, %d }", offsetof
, SkuTableIdx
);
1003 private String
getDataTypeDeclarationForSkuEnabled (Token token
) {
1004 String typeStr
= "";
1006 if (token
.datumType
== Token
.DATUM_TYPE
.UINT8
) {
1007 typeStr
= "UINT8 %s_%s[%d];\r\n";
1008 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT16
) {
1009 typeStr
= "UINT16 %s_%s[%d];\r\n";
1010 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT32
) {
1011 typeStr
= "UINT32 %s_%s[%d];\r\n";
1012 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT64
) {
1013 typeStr
= "UINT64 %s_%s[%d];\r\n";
1014 } else if (token
.datumType
== Token
.DATUM_TYPE
.BOOLEAN
) {
1015 typeStr
= "BOOLEAN %s_%s[%d];\r\n";
1016 } else if (token
.datumType
== Token
.DATUM_TYPE
.POINTER
) {
1017 return String
.format("UINT8 %s_%s[%d];\r\n", token
.getPrimaryKeyString(), "SkuDataTable", token
.datumSize
* token
.skuData
.size());
1020 return String
.format(typeStr
, token
.getPrimaryKeyString(), "SkuDataTable", token
.skuData
.size());
1024 private String
getDataTypeInstantiationForSkuEnabled (Token token
) {
1027 if (token
.datumType
== Token
.DATUM_TYPE
.POINTER
) {
1028 return String
.format("UINT8 %s_%s[%d]", token
.getPrimaryKeyString(), "SkuDataTable", token
.datumSize
* token
.skuData
.size());
1031 for (int idx
= 0; idx
< token
.skuData
.size(); idx
++) {
1032 str
+= token
.skuData
.get(idx
).toString();
1033 if (idx
!= token
.skuData
.size() - 1) {
1044 private String
getDataTypeInstantiation (Token token
) {
1046 if (token
.datumType
== Token
.DATUM_TYPE
.POINTER
) {
1047 return String
.format("%s /* %s */", token
.getDefaultSku().value
, token
.getPrimaryKeyString());
1049 return String
.format("%s /* %s */", token
.getDefaultSku().value
, token
.getPrimaryKeyString());
1054 private String
getDataTypeDeclaration (Token token
) {
1056 String typeStr
= "";
1058 if (token
.datumType
== Token
.DATUM_TYPE
.UINT8
) {
1060 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT16
) {
1062 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT32
) {
1064 } else if (token
.datumType
== Token
.DATUM_TYPE
.UINT64
) {
1066 } else if (token
.datumType
== Token
.DATUM_TYPE
.BOOLEAN
) {
1067 typeStr
= "BOOLEAN";
1068 } else if (token
.datumType
== Token
.DATUM_TYPE
.POINTER
) {
1069 return String
.format("UINT8 %s[%d]", token
.getPrimaryKeyString(), token
.datumSize
);
1073 return String
.format("%s %s", typeStr
, token
.getPrimaryKeyString());
1076 private String
getVpdEnableTypeDeclaration (Token token
) {
1077 return String
.format("VPD_HEAD %s", token
.getPrimaryKeyString());
1080 private String
getVpdEnableTypeInstantiation (Token token
) {
1081 return String
.format("{ %s } /* %s */", token
.getDefaultSku().vpdOffset
,
1082 token
.getPrimaryKeyString());
1085 private String
getStringTypeDeclaration (Token token
) {
1086 return String
.format("UINT16 %s", token
.getPrimaryKeyString());
1089 private String
getStringTypeInstantiation (int StringTableIdx
, Token token
) {
1090 return String
.format ("%d /* %s */", StringTableIdx
,
1091 token
.getPrimaryKeyString());
1095 private String
getVariableEnableTypeDeclaration (Token token
) {
1096 return String
.format("VARIABLE_HEAD %s", token
.getPrimaryKeyString());
1099 private String
getVariableEnableInstantiation (Token token
)
1100 throws EntityException
{
1104 return String
.format("{ %d, %d, %s } /* %s */", guidTable
.add(token
.getDefaultSku().variableGuid
, token
.getPrimaryKeyString()),
1105 stringTable
.add(token
.getDefaultSku().getStringOfVariableName(), token
),
1106 token
.getDefaultSku().variableOffset
,
1107 token
.getPrimaryKeyString());
1110 public int getTotalTokenNumber () {
1111 return sizeTable
.getTableLen();
1114 public static String
getPcdDatabaseCommonDefinitions ()
1115 throws EntityException
{
1119 File file
= new File(GlobalData
.getWorkspacePath() + File
.separator
+
1120 "Tools" + File
.separator
+
1121 "Conf" + File
.separator
+
1122 "Pcd" + File
.separator
+
1123 "PcdDatabaseCommonDefinitions.sample");
1124 FileReader reader
= new FileReader(file
);
1125 BufferedReader in
= new BufferedReader(reader
);
1127 while ((str
= in
.readLine()) != null) {
1128 retStr
= retStr
+"\r\n" + str
;
1130 } catch (Exception ex
) {
1131 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1137 public static String
getPcdDxeDatabaseDefinitions ()
1138 throws EntityException
{
1142 File file
= new File(GlobalData
.getWorkspacePath() + File
.separator
+
1143 "Tools" + File
.separator
+
1144 "Conf" + File
.separator
+
1145 "Pcd" + File
.separator
+
1146 "PcdDatabaseDxeDefinitions.sample");
1147 FileReader reader
= new FileReader(file
);
1148 BufferedReader in
= new BufferedReader(reader
);
1150 while ((str
= in
.readLine()) != null) {
1151 retStr
= retStr
+"\r\n" + str
;
1153 } catch (Exception ex
) {
1154 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1160 public static String
getPcdPeiDatabaseDefinitions ()
1161 throws EntityException
{
1165 File file
= new File(GlobalData
.getWorkspacePath() + File
.separator
+
1166 "Tools" + File
.separator
+
1167 "Conf" + File
.separator
+
1168 "Pcd" + File
.separator
+
1169 "PcdDatabasePeiDefinitions.sample");
1170 FileReader reader
= new FileReader(file
);
1171 BufferedReader in
= new BufferedReader(reader
);
1173 while ((str
= in
.readLine()) != null) {
1174 retStr
= retStr
+"\r\n" + str
;
1176 } catch (Exception ex
) {
1177 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1186 public ModuleSADocument
.ModuleSA module
;
1187 public UsageInstance
.MODULE_TYPE type
;
1189 public ModuleInfo (ModuleSADocument
.ModuleSA module
, UsageInstance
.MODULE_TYPE type
) {
1190 this.module
= module
;
1195 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1196 This class will be used for wizard and build tools, So it can *not* inherit
1197 from buildAction or UIAction.
1199 public class CollectPCDAction
{
1200 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1201 private MemoryDatabaseManager dbManager
;
1203 /// Workspacepath hold the workspace information.
1204 private String workspacePath
;
1206 /// FPD file is the root file.
1207 private String fpdFilePath
;
1209 /// Message level for CollectPCDAction.
1210 private int originalMessageLevel
;
1212 /// Cache the fpd docment instance for private usage.
1213 private FrameworkPlatformDescriptionDocument fpdDocInstance
;
1216 Set WorkspacePath parameter for this action class.
1218 @param workspacePath parameter for this action
1220 public void setWorkspacePath(String workspacePath
) {
1221 this.workspacePath
= workspacePath
;
1225 Set action message level for CollectPcdAction tool.
1227 The message should be restored when this action exit.
1229 @param actionMessageLevel parameter for this action
1231 public void setActionMessageLevel(int actionMessageLevel
) {
1232 originalMessageLevel
= ActionMessage
.messageLevel
;
1233 ActionMessage
.messageLevel
= actionMessageLevel
;
1237 Set FPDFileName parameter for this action class.
1239 @param fpdFilePath fpd file path
1241 public void setFPDFilePath(String fpdFilePath
) {
1242 this.fpdFilePath
= fpdFilePath
;
1246 Common function interface for outer.
1248 @param workspacePath The path of workspace of current build or analysis.
1249 @param fpdFilePath The fpd file path of current build or analysis.
1250 @param messageLevel The message level for this Action.
1252 @throws Exception The exception of this function. Because it can *not* be predict
1253 where the action class will be used. So only Exception can be throw.
1256 public void perform(String workspacePath
, String fpdFilePath
,
1257 int messageLevel
) throws Exception
{
1258 setWorkspacePath(workspacePath
);
1259 setFPDFilePath(fpdFilePath
);
1260 setActionMessageLevel(messageLevel
);
1263 ActionMessage
.messageLevel
= originalMessageLevel
;
1267 Core execution function for this action class.
1269 This function work flows will be:
1270 1) Collect and prepocess PCD information from FPD file, all PCD
1271 information will be stored into memory database.
1272 2) Generate 3 strings for
1273 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
1274 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
1275 c) DXE PCD Database (C structure) for PCD Service DXE.
1278 @throws EntityException Exception indicate failed to execute this action.
1281 private void execute() throws EntityException
{
1283 // Get memoryDatabaseManager instance from GlobalData.
1284 // The memoryDatabaseManager should be initialized for whatever build
1285 // tools or wizard tools
1287 if((dbManager
= GlobalData
.getPCDMemoryDBManager()) == null) {
1288 throw new EntityException("The instance of PCD memory database manager is null");
1292 // Collect all PCD information defined in FPD file.
1293 // Evenry token defind in FPD will be created as an token into
1296 createTokenInDBFromFPD();
1299 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1300 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1302 genPcdDatabaseSourceCode ();
1307 This function generates source code for PCD Database.
1310 @throws EntityException If the token does *not* exist in memory database.
1313 private void genPcdDatabaseSourceCode()
1314 throws EntityException
{
1315 String PcdCommonHeaderString
= PcdDatabase
.getPcdDatabaseCommonDefinitions ();
1317 ArrayList
<Token
> alPei
= new ArrayList
<Token
> ();
1318 ArrayList
<Token
> alDxe
= new ArrayList
<Token
> ();
1320 dbManager
.getTwoPhaseDynamicRecordArray(alPei
, alDxe
);
1321 PcdDatabase pcdPeiDatabase
= new PcdDatabase (alPei
, "PEI", 0);
1322 pcdPeiDatabase
.genCode();
1323 dbManager
.PcdPeimHString
= PcdCommonHeaderString
+ pcdPeiDatabase
.getHString()
1324 + PcdDatabase
.getPcdPeiDatabaseDefinitions();
1325 dbManager
.PcdPeimCString
= pcdPeiDatabase
.getCString();
1327 PcdDatabase pcdDxeDatabase
= new PcdDatabase (alDxe
,
1331 pcdDxeDatabase
.genCode();
1332 dbManager
.PcdDxeHString
= dbManager
.PcdPeimHString
+ pcdDxeDatabase
.getHString()
1333 + PcdDatabase
.getPcdDxeDatabaseDefinitions();
1334 dbManager
.PcdDxeCString
= pcdDxeDatabase
.getCString();
1338 Get component array from FPD.
1340 This function maybe provided by some Global class.
1342 @return List<ModuleInfo> the component array.
1345 private List
<ModuleInfo
> getComponentsFromFPD()
1346 throws EntityException
{
1347 HashMap
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
1348 List
<ModuleInfo
> allModules
= new ArrayList
<ModuleInfo
>();
1349 ModuleInfo current
= null;
1351 org
.tianocore
.Components components
= null;
1352 FrameworkModulesDocument
.FrameworkModules fModules
= null;
1353 java
.util
.List
<ModuleSADocument
.ModuleSA
> modules
= null;
1356 if (fpdDocInstance
== null) {
1358 fpdDocInstance
= (FrameworkPlatformDescriptionDocument
)XmlObject
.Factory
.parse(new File(fpdFilePath
));
1359 } catch(IOException ioE
) {
1360 throw new EntityException("File IO error for xml file:" + fpdFilePath
+ "\n" + ioE
.getMessage());
1361 } catch(XmlException xmlE
) {
1362 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath
+ "\n" + xmlE
.getMessage());
1368 // Check whether FPD contians <FramworkModules>
1370 fModules
= fpdDocInstance
.getFrameworkPlatformDescription().getFrameworkModules();
1371 if (fModules
== null) {
1376 // BUGBUG: The following is work around code, the final component type should be get from
1377 // GlobalData class.
1379 components
= fModules
.getSEC();
1380 if (components
!= null) {
1381 modules
= components
.getModuleSAList();
1382 for (index
= 0; index
< modules
.size(); index
++) {
1383 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.SEC
));
1387 components
= fModules
.getPEICORE();
1388 if (components
!= null) {
1389 modules
= components
.getModuleSAList();
1390 for (index
= 0; index
< modules
.size(); index
++) {
1391 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.PEI_CORE
));
1395 components
= fModules
.getPEIM();
1396 if (components
!= null) {
1397 modules
= components
.getModuleSAList();
1398 for (index
= 0; index
< modules
.size(); index
++) {
1399 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.PEIM
));
1403 components
= fModules
.getDXECORE();
1404 if (components
!= null) {
1405 modules
= components
.getModuleSAList();
1406 for (index
= 0; index
< modules
.size(); index
++) {
1407 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.DXE_CORE
));
1411 components
= fModules
.getDXEDRIVERS();
1412 if (components
!= null) {
1413 modules
= components
.getModuleSAList();
1414 for (index
= 0; index
< modules
.size(); index
++) {
1415 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.DXE_DRIVERS
));
1419 components
= fModules
.getOTHERCOMPONENTS();
1420 if (components
!= null) {
1421 modules
= components
.getModuleSAList();
1422 for (index
= 0; index
< modules
.size(); index
++) {
1423 allModules
.add(new ModuleInfo(modules
.get(index
), UsageInstance
.MODULE_TYPE
.OTHER_COMPONENTS
));
1431 Create token instance object into memory database, the token information
1432 comes for FPD file. Normally, FPD file will contain all token platform
1435 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
1437 @throws EntityException Failed to parse FPD xml file.
1440 private void createTokenInDBFromFPD()
1441 throws EntityException
{
1445 List
<PcdBuildDefinition
.PcdData
> pcdBuildDataArray
= new ArrayList
<PcdBuildDefinition
.PcdData
>();
1446 PcdBuildDefinition
.PcdData pcdBuildData
= null;
1448 SkuInstance skuInstance
= null;
1450 List
<ModuleInfo
> modules
= null;
1451 String primaryKey
= null;
1452 String exceptionString
= null;
1453 UsageInstance usageInstance
= null;
1454 String primaryKey1
= null;
1455 String primaryKey2
= null;
1456 boolean isDuplicate
= false;
1457 Token
.PCD_TYPE pcdType
= Token
.PCD_TYPE
.UNKNOWN
;
1458 Token
.DATUM_TYPE datumType
= Token
.DATUM_TYPE
.UNKNOWN
;
1459 int tokenNumber
= 0;
1460 String moduleName
= null;
1461 String datum
= null;
1462 int maxDatumSize
= 0;
1465 // ----------------------------------------------
1466 // 1), Get all <ModuleSA> from FPD file.
1467 // ----------------------------------------------
1469 modules
= getComponentsFromFPD();
1471 if (modules
== null) {
1472 throw new EntityException("No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
1476 // -------------------------------------------------------------------
1477 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
1478 // -------------------------------------------------------------------
1480 for (index
= 0; index
< modules
.size(); index
++) {
1481 isDuplicate
= false;
1482 for (index2
= 0; index2
< index
; index2
++) {
1484 // BUGBUG: For transition schema, we can *not* get module's version from
1485 // <ModuleSAs>, It is work around code.
1487 primaryKey1
= UsageInstance
.getPrimaryKey(modules
.get(index
).module
.getModuleName(),
1488 translateSchemaStringToUUID(modules
.get(index
).module
.getModuleGuid()),
1489 modules
.get(index
).module
.getPackageName(),
1490 translateSchemaStringToUUID(modules
.get(index
).module
.getPackageGuid()),
1491 modules
.get(index
).module
.getArch().toString(),
1493 primaryKey2
= UsageInstance
.getPrimaryKey(modules
.get(index2
).module
.getModuleName(),
1494 translateSchemaStringToUUID(modules
.get(index2
).module
.getModuleGuid()),
1495 modules
.get(index2
).module
.getPackageName(),
1496 translateSchemaStringToUUID(modules
.get(index2
).module
.getPackageGuid()),
1497 modules
.get(index2
).module
.getArch().toString(),
1499 if (primaryKey1
.equalsIgnoreCase(primaryKey2
)) {
1510 // It is legal for a module does not contains ANY pcd build definitions.
1512 if (modules
.get(index
).module
.getPcdBuildDefinition() == null) {
1516 pcdBuildDataArray
= modules
.get(index
).module
.getPcdBuildDefinition().getPcdDataList();
1518 moduleName
= modules
.get(index
).module
.getModuleName();
1521 // ----------------------------------------------------------------------
1522 // 2.1), Loop all Pcd entry for a module and add it into memory database.
1523 // ----------------------------------------------------------------------
1525 for (pcdIndex
= 0; pcdIndex
< pcdBuildDataArray
.size(); pcdIndex
++) {
1526 pcdBuildData
= pcdBuildDataArray
.get(pcdIndex
);
1527 primaryKey
= Token
.getPrimaryKeyString(pcdBuildData
.getCName(),
1528 translateSchemaStringToUUID(pcdBuildData
.getTokenSpaceGuid()));
1529 pcdType
= Token
.getpcdTypeFromString(pcdBuildData
.getItemType().toString());
1530 datumType
= Token
.getdatumTypeFromString(pcdBuildData
.getDatumType().toString());
1531 tokenNumber
= Integer
.decode(pcdBuildData
.getToken().toString());
1532 datum
= pcdBuildData
.getValue();
1533 maxDatumSize
= pcdBuildData
.getMaxDatumSize();
1536 // -------------------------------------------------------------------------------------------
1537 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
1538 // -------------------------------------------------------------------------------------------
1540 if (!Token
.isDynamic(pcdType
)) {
1542 // Value is required.
1544 if (datum
== null) {
1545 exceptionString
= String
.format("There is no value for PCD entry %s in module %s!",
1546 pcdBuildData
.getCName(),
1548 throw new EntityException(exceptionString
);
1552 // Check whether the datum size is matched datum type.
1554 if ((exceptionString
= verifyDatumSize(pcdBuildData
.getCName(),
1557 datumType
)) != null) {
1558 throw new EntityException(exceptionString
);
1563 // ---------------------------------------------------------------------------------
1564 // 2.1.2), Create token or update token information for current anaylized PCD data.
1565 // ---------------------------------------------------------------------------------
1567 if (dbManager
.isTokenInDatabase(primaryKey
)) {
1569 // If the token is already exist in database, do some necessary checking
1570 // and add a usage instance into this token in database
1572 token
= dbManager
.getTokenByKey(primaryKey
);
1575 // checking for DatumType, DatumType should be unique for one PCD used in different
1578 if (token
.datumType
!= datumType
) {
1579 exceptionString
= String
.format("The datum type of PCD entry %s is %s, which is different with %s defined in before!",
1580 pcdBuildData
.getCName(),
1581 pcdBuildData
.getDatumType().toString(),
1582 Token
.getStringOfdatumType(token
.datumType
));
1583 throw new EntityException(exceptionString
);
1587 // Check token number is valid
1589 if (tokenNumber
!= token
.tokenNumber
) {
1590 exceptionString
= String
.format("The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",
1591 pcdBuildData
.getCName(),
1593 throw new EntityException(exceptionString
);
1597 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
1599 if (token
.isDynamicPCD
!= Token
.isDynamic(pcdType
)) {
1600 exceptionString
= String
.format("For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+
1601 "is different with others module's",
1604 throw new EntityException(exceptionString
);
1607 if (token
.isDynamicPCD
) {
1609 // Check datum is equal the datum in dynamic information.
1610 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,
1611 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.
1613 if (!token
.isSkuEnable() &&
1614 (token
.skuData
.get(0).value
.type
== DynamicTokenValue
.VALUE_TYPE
.DEFAULT_TYPE
)) {
1615 if (!datum
.equalsIgnoreCase(token
.skuData
.get(0).value
.value
)) {
1616 exceptionString
= String
.format("For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+
1617 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+
1618 "illega! You can choose no <Value> in <ModuleSA>!",
1627 // If the token is not in database, create a new token instance and add
1628 // a usage instance into this token in database.
1630 token
= new Token(pcdBuildData
.getCName(),
1631 translateSchemaStringToUUID(pcdBuildData
.getTokenSpaceGuid()));
1633 token
.datumType
= datumType
;
1634 token
.tokenNumber
= tokenNumber
;
1635 token
.isDynamicPCD
= Token
.isDynamic(pcdType
);
1636 token
.datumSize
= maxDatumSize
;
1638 if (token
.isDynamicPCD
) {
1640 // For Dynamic and Dynamic Ex type, need find the dynamic information
1641 // in <DynamicPcdBuildDefinition> section in FPD file.
1643 updateDynamicInformation(moduleName
,
1649 dbManager
.addTokenToDatabase(primaryKey
, token
);
1653 // -----------------------------------------------------------------------------------
1654 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
1655 // -----------------------------------------------------------------------------------
1657 token
.updateSupportPcdType(pcdType
);
1660 // ------------------------------------------------
1661 // 2.1.4), Create an usage instance for this token.
1662 // ------------------------------------------------
1664 usageInstance
= new UsageInstance(token
,
1666 translateSchemaStringToUUID(modules
.get(index
).module
.getModuleGuid()),
1667 modules
.get(index
).module
.getPackageName(),
1668 translateSchemaStringToUUID(modules
.get(index
).module
.getPackageGuid()),
1669 modules
.get(index
).type
,
1671 modules
.get(index
).module
.getArch().toString(),
1675 token
.addUsageInstance(usageInstance
);
1681 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
1683 This function should be implemented in GlobalData in future.
1685 @param token The token instance which has hold module's PCD information
1686 @param moduleName The name of module who will use this Dynamic PCD.
1688 @return DynamicPcdBuildDefinitions.PcdBuildData
1691 private DynamicPcdBuildDefinitions
.PcdBuildData
getDynamicInfoFromFPD(Token token
,
1693 throws EntityException
{
1695 String exceptionString
= null;
1696 String dynamicPrimaryKey
= null;
1697 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions
= null;
1698 List
<DynamicPcdBuildDefinitions
.PcdBuildData
> dynamicPcdBuildDataArray
= null;
1701 // If FPD document is not be opened, open and initialize it.
1703 if (fpdDocInstance
== null) {
1705 fpdDocInstance
= (FrameworkPlatformDescriptionDocument
)XmlObject
.Factory
.parse(new File(fpdFilePath
));
1706 } catch(IOException ioE
) {
1707 throw new EntityException("File IO error for xml file:" + fpdFilePath
+ "\n" + ioE
.getMessage());
1708 } catch(XmlException xmlE
) {
1709 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath
+ "\n" + xmlE
.getMessage());
1713 dynamicPcdBuildDefinitions
= fpdDocInstance
.getFrameworkPlatformDescription().getDynamicPcdBuildDefinitions();
1714 if (dynamicPcdBuildDefinitions
== null) {
1715 exceptionString
= String
.format("There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+
1716 "PCD entry %s in module %s!",
1719 throw new EntityException(exceptionString
);
1722 dynamicPcdBuildDataArray
= dynamicPcdBuildDefinitions
.getPcdBuildDataList();
1723 for (index
= 0; index
< dynamicPcdBuildDataArray
.size(); index
++) {
1724 dynamicPrimaryKey
= Token
.getPrimaryKeyString(dynamicPcdBuildDataArray
.get(index
).getCName(),
1725 translateSchemaStringToUUID(dynamicPcdBuildDataArray
.get(index
).getTokenSpaceGuid()));
1726 if (dynamicPrimaryKey
.equalsIgnoreCase(token
.getPrimaryKeyString())) {
1727 return dynamicPcdBuildDataArray
.get(index
);
1735 Verify the maxDatumSize for a PCD data is matched to Datum type.
1737 @param token The token instance
1738 @param moduleName The module name who use this PCD data.
1739 @param maxDatumSize The value of max datum size in FPD file
1740 @param datumType The datum type
1742 @return String if is unmatched, set the exception information
1743 as return value, otherwice is null.
1745 private String
verifyDatumSize(String cName
,
1748 Token
.DATUM_TYPE datumType
) {
1749 String exceptionString
= null;
1750 switch (datumType
) {
1752 if (maxDatumSize
!= 1) {
1753 exceptionString
= String
.format("In FPD file, the datum type of PCD data %s in module %s "+
1754 "is UINT8, but datum size is %d, they are not matched!",
1761 if (maxDatumSize
!= 2) {
1762 exceptionString
= String
.format("In FPD file, the datum type of PCD data %s in module %s "+
1763 "is UINT16, but datum size is %d, they are not matched!",
1770 if (maxDatumSize
!= 4) {
1771 exceptionString
= String
.format("In FPD file, the datum type of PCD data %s in module %s "+
1772 "is UINT32, but datum size is %d, they are not matched!",
1779 if (maxDatumSize
!= 8) {
1780 exceptionString
= String
.format("In FPD file, the datum type of PCD data %s in module %s "+
1781 "is UINT64, but datum size is %d, they are not matched!",
1788 if (maxDatumSize
!= 1) {
1789 exceptionString
= String
.format("In FPD file, the datum type of PCD data %s in module %s "+
1790 "is BOOLEAN, but datum size is %d, they are not matched!",
1798 return exceptionString
;
1802 Update dynamic information for PCD entry.
1804 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
1807 @param moduleName The name of the module who use this PCD
1808 @param token The token instance
1809 @param datum The <datum> in module's PCD information
1810 @param maxDatumSize The <maxDatumSize> in module's PCD information
1814 private Token
updateDynamicInformation(String moduleName
,
1818 throws EntityException
{
1821 String exceptionString
= null;
1822 DynamicTokenValue dynamicValue
;
1823 SkuInstance skuInstance
= null;
1825 boolean hasSkuId0
= false;
1827 List
<DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
> skuInfoList
= null;
1828 DynamicPcdBuildDefinitions
.PcdBuildData dynamicInfo
= null;
1830 dynamicInfo
= getDynamicInfoFromFPD(token
, moduleName
);
1831 if (dynamicInfo
== null) {
1832 exceptionString
= String
.format("For Dynamic PCD %s used by module %s, "+
1833 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+
1834 "in FPD file, but it is required!",
1837 throw new EntityException(exceptionString
);
1840 skuInfoList
= dynamicInfo
.getSkuInfoList();
1843 // Loop all sku data
1845 for (index
= 0; index
< skuInfoList
.size(); index
++) {
1846 skuInstance
= new SkuInstance();
1848 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
1850 temp
= skuInfoList
.get(index
).getSkuId().toString();
1851 skuInstance
.id
= Integer
.decode(temp
);
1853 if (skuInstance
.id
== 0) {
1857 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
1859 if (skuInfoList
.get(index
).getValue() != null) {
1860 skuInstance
.value
.setValue(skuInfoList
.get(index
).getValue());
1861 token
.skuData
.add(skuInstance
);
1864 // Judege wether is same of datum between module's information
1865 // and dynamic information.
1867 if (datum
!= null) {
1868 if ((skuInstance
.id
== 0) &&
1869 !datum
.equalsIgnoreCase(skuInfoList
.get(index
).getValue())) {
1870 exceptionString
= String
.format("For dynamic PCD %s, module %s give <datum> as %s which is different with "+
1871 "Sku 0's <datum> %s defined in <DynamicPcdBuildDefinitions>! Please sync them at first!",
1874 skuInfoList
.get(index
).getValue());
1875 throw new EntityException(exceptionString
);
1882 // Judge whether is HII group case.
1884 if (skuInfoList
.get(index
).getVariableName() != null) {
1885 exceptionString
= null;
1886 if (skuInfoList
.get(index
).getVariableGuid() == null) {
1887 exceptionString
= String
.format("For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
1888 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
1894 if (skuInfoList
.get(index
).getVariableOffset() == null) {
1895 exceptionString
= String
.format("For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
1896 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
1901 if (skuInfoList
.get(index
).getHiiDefaultValue() == null) {
1902 exceptionString
= String
.format("For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
1903 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
1908 if (exceptionString
!= null) {
1909 throw new EntityException(exceptionString
);
1911 offset
= Integer
.decode(skuInfoList
.get(index
).getVariableOffset());
1912 if (offset
> 0xFFFF) {
1913 throw new EntityException(String
.format("For dynamic PCD %s , the variable offset defined in sku %d data "+
1914 "exceed 64K, it is not allowed!",
1919 skuInstance
.value
.setHiiData(skuInfoList
.get(index
).getVariableName(),
1920 translateSchemaStringToUUID(skuInfoList
.get(index
).getVariableGuid().toString()),
1921 skuInfoList
.get(index
).getVariableOffset(),
1922 skuInfoList
.get(index
).getHiiDefaultValue());
1923 token
.skuData
.add(skuInstance
);
1927 if (skuInfoList
.get(index
).getVpdOffset() != null) {
1928 skuInstance
.value
.setVpdData(skuInfoList
.get(index
).getVpdOffset());
1929 token
.skuData
.add(skuInstance
);
1933 exceptionString
= String
.format("For dynamic PCD %s, the dynamic info must "+
1934 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
1936 throw new EntityException(exceptionString
);
1940 exceptionString
= String
.format("For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
1941 "no sku id = 0 data, which is required for every dynamic PCD",
1949 Translate the schema string to UUID instance.
1951 In schema, the string of UUID is defined as following two types string:
1952 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
1953 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
1955 2) GuidNamingConvention: pattern =
1956 [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}
1958 This function will convert string and create uuid instance.
1960 @param uuidString UUID string in XML file
1962 @return UUID UUID instance
1964 private UUID
translateSchemaStringToUUID(String uuidString
)
1965 throws EntityException
{
1967 String
[] splitStringArray
;
1972 if (uuidString
== null) {
1976 if (uuidString
.length() == 0) {
1980 if (uuidString
.equals("0") ||
1981 uuidString
.equalsIgnoreCase("0x0")) {
1982 return new UUID(0, 0);
1986 // If the UUID schema string is GuidArrayType type then need translate
1987 // to GuidNamingConvention type at first.
1989 if ((uuidString
.charAt(0) == '0') && ((uuidString
.charAt(1) == 'x') || (uuidString
.charAt(1) == 'X'))) {
1990 splitStringArray
= uuidString
.split("," );
1991 if (splitStringArray
.length
!= 11) {
1992 throw new EntityException ("Wrong format for UUID string: " + uuidString
);
1996 // Remove blank space from these string and remove header string "0x"
1998 for (index
= 0; index
< 11; index
++) {
1999 splitStringArray
[index
] = splitStringArray
[index
].trim();
2000 splitStringArray
[index
] = splitStringArray
[index
].substring(2, splitStringArray
[index
].length());
2004 // Add heading '0' to normalize the string length
2006 for (index
= 3; index
< 11; index
++) {
2007 chLen
= splitStringArray
[index
].length();
2008 for (chIndex
= 0; chIndex
< 2 - chLen
; chIndex
++) {
2009 splitStringArray
[index
] = "0" + splitStringArray
[index
];
2014 // construct the final GuidNamingConvention string
2016 temp
= String
.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
2017 splitStringArray
[0],
2018 splitStringArray
[1],
2019 splitStringArray
[2],
2020 splitStringArray
[3],
2021 splitStringArray
[4],
2022 splitStringArray
[5],
2023 splitStringArray
[6],
2024 splitStringArray
[7],
2025 splitStringArray
[8],
2026 splitStringArray
[9],
2027 splitStringArray
[10]);
2031 return UUID
.fromString(uuidString
);
2035 check parameter for this action.
2037 @throws EntityException Bad parameter.
2039 private void checkParameter() throws EntityException
{
2042 if((fpdFilePath
== null) ||(workspacePath
== null)) {
2043 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
2046 if(fpdFilePath
.length() == 0 || workspacePath
.length() == 0) {
2047 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
2050 file
= new File(workspacePath
);
2051 if(!file
.exists()) {
2052 throw new EntityException("WorkpacePath " + workspacePath
+ " does not exist!");
2055 file
= new File(fpdFilePath
);
2057 if(!file
.exists()) {
2058 throw new EntityException("FPD File " + fpdFilePath
+ " does not exist!");
2065 @param argv parameter from command line
2067 public static void main(String argv
[]) throws EntityException
{
2068 CollectPCDAction ca
= new CollectPCDAction();
2069 ca
.setWorkspacePath("m:/tianocore/edk2");
2070 ca
.setFPDFilePath("m:/tianocore/edk2/EdkNt32Pkg/Nt32.fpd");
2071 ca
.setActionMessageLevel(ActionMessage
.MAX_MESSAGE_LEVEL
);
2072 GlobalData
.initInfo("Tools" + File
.separator
+ "Conf" + File
.separator
+ "FrameworkDatabase.db",
2073 "m:/tianocore/edk2");