X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=Tools%2FSource%2FGenBuild%2Forg%2Ftianocore%2Fbuild%2Fpcd%2Faction%2FCollectPCDAction.java;h=c9d905047640e9af607358cdc191bf62a69711f8;hb=6f7e61a03a654ad08ba198432c2ed196a9df0c3e;hp=7b86e6b88fc4e680bfa83c5828641315862218e6;hpb=6a4cae58979223de2710858bde490d7e24da3e9e;p=mirror_edk2.git diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java index 7b86e6b88f..c9d9050476 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java @@ -17,10 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ package org.tianocore.build.pcd.action; -import java.io.BufferedReader; +import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -31,15 +32,21 @@ import java.util.UUID; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; +import org.tianocore.DynamicPcdBuildDefinitionsDocument; +import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions; +import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData; +import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo; +import org.tianocore.FrameworkModulesDocument; import org.tianocore.FrameworkPlatformDescriptionDocument; +import org.tianocore.FrameworkPlatformDescriptionDocument.FrameworkPlatformDescription; import org.tianocore.ModuleSADocument; +import org.tianocore.ModuleSADocument.ModuleSA; import org.tianocore.PackageSurfaceAreaDocument; -import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData; -import org.tianocore.PcdDefinitionsDocument.PcdDefinitions; -import org.tianocore.build.autogen.CommonDefinition; +import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition; import org.tianocore.build.global.GlobalData; import org.tianocore.build.global.SurfaceAreaQuery; import org.tianocore.build.pcd.action.ActionMessage; +import org.tianocore.build.pcd.entity.DynamicTokenValue; import org.tianocore.build.pcd.entity.MemoryDatabaseManager; import org.tianocore.build.pcd.entity.SkuInstance; import org.tianocore.build.pcd.entity.Token; @@ -416,8 +423,8 @@ class SkuIdTable { int index; - Integer [] skuIds = new Integer[token.maxSkuCount + 1]; - skuIds[0] = new Integer(token.maxSkuCount); + Integer [] skuIds = new Integer[token.skuData.size() + 1]; + skuIds[0] = new Integer(token.skuData.size()); for (index = 1; index < skuIds.length; index++) { skuIds[index] = new Integer(token.skuData.get(index - 1).id); } @@ -442,21 +449,18 @@ class LocalTokenNumberTable { private ArrayList alComment; private String phase; private int len; - private int bodyStart; - private int bodyLineNum; public LocalTokenNumberTable (String phase) { this.phase = phase; al = new ArrayList(); alComment = new ArrayList(); - bodyStart = 0; - bodyLineNum = 0; len = 0; } public String getSizeMacro () { - return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize()); + return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize()) + + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size()); } public int getSize () { @@ -476,7 +480,6 @@ class LocalTokenNumberTable { output.add("/* LocalTokenNumberTable */"); output.add("{"); - bodyStart = 2; if (al.size() == 0) { output.add("0"); @@ -498,8 +501,6 @@ class LocalTokenNumberTable { } - bodyLineNum = al.size(); - output.add("}"); return output; @@ -517,15 +518,15 @@ class LocalTokenNumberTable { str += " | PCD_TYPE_STRING"; } - if (token.skuEnabled) { + if (token.isSkuEnable()) { str += " | PCD_TYPE_SKU_ENABLED"; } - if (token.hiiEnabled) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) { str += " | PCD_TYPE_HII"; } - if (token.vpdEnabled) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) { str += " | PCD_TYPE_VPD"; } @@ -641,16 +642,17 @@ class PcdDatabase { public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n"; public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n"; - public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER];\r\n"; + public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n"; public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n"; - public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER];\r\n"; + public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n"; public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n"; public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n"; public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n"; public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n"; - public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n"; + public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n"; + public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n"; public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n"; public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n"; @@ -723,11 +725,11 @@ class PcdDatabase { } private int getAlignmentSize (Token token) { - if (token.hiiEnabled) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) { return 2; } - if (token.vpdEnabled) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) { return 4; } @@ -760,7 +762,8 @@ class PcdDatabase { return hString; } - public void genCode () { + public void genCode () + throws EntityException { final String newLine = "\r\n"; final String declNewLine = ";\r\n"; @@ -789,16 +792,14 @@ class PcdDatabase { // PEI_PCD_DATABASE_INIT // java.util.Comparator comparator = new AlignmentSizeComp(); - List list = initTokens; - java.util.Collections.sort(list, comparator); + java.util.Collections.sort(initTokens, comparator); initCode = processTokens(initTokens); // // Generate Structure Declaration for PcdTokens without Default Value // PEI_PCD_DATABASE_UNINIT // - list = uninitTokens; - java.util.Collections.sort(list, comparator); + java.util.Collections.sort(uninitTokens, comparator); uninitCode = processTokens(uninitTokens); // @@ -926,7 +927,8 @@ class PcdDatabase { return str; } - private HashMap> processTokens (List alToken) { + private HashMap> processTokens (List alToken) + throws EntityException { HashMap > map = new HashMap>(); @@ -938,7 +940,7 @@ class PcdDatabase { for (int index = 0; index < alToken.size(); index++) { Token token = alToken.get(index); - if (token.skuEnabled) { + if (token.isSkuEnable()) { // // BugBug: Schema only support Data type now // @@ -957,10 +959,10 @@ class PcdDatabase { } } else { - if (token.hiiEnabled) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) { decl.add(getVariableEnableTypeDeclaration(token)); inst.add(getVariableEnableInstantiation(token)); - } else if (token.vpdEnabled) { + } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) { decl.add(getVpdEnableTypeDeclaration(token)); inst.add(getVpdEnableTypeInstantiation(token)); } else if (token.isStringType()) { @@ -977,7 +979,7 @@ class PcdDatabase { sizeTable.add(token); localTokenNumberTable.add(token); - token.assignedtokenNumber = assignedTokenNumber++; + token.tokenNumber = assignedTokenNumber++; } @@ -1013,10 +1015,10 @@ class PcdDatabase { } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) { typeStr = "BOOLEAN %s_%s[%d];\r\n"; } else if (token.datumType == Token.DATUM_TYPE.POINTER) { - return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount); + return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size()); } - return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount); + return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size()); } @@ -1024,12 +1026,12 @@ class PcdDatabase { String str = ""; if (token.datumType == Token.DATUM_TYPE.POINTER) { - return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount); + return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size()); } else { str = "{ "; - for (int idx = 0; idx < token.maxSkuCount; idx++) { + for (int idx = 0; idx < token.skuData.size(); idx++) { str += token.skuData.get(idx).toString(); - if (idx != token.maxSkuCount - 1) { + if (idx != token.skuData.size() - 1) { str += ", "; } } @@ -1043,9 +1045,9 @@ class PcdDatabase { private String getDataTypeInstantiation (Token token) { if (token.datumType == Token.DATUM_TYPE.POINTER) { - return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString()); + return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString()); } else { - return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString()); + return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString()); } } @@ -1077,7 +1079,7 @@ class PcdDatabase { } private String getVpdEnableTypeInstantiation (Token token) { - return String.format("{ %d } /* %s */", token.vpdOffset, + return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset, token.getPrimaryKeyString()); } @@ -1095,10 +1097,14 @@ class PcdDatabase { return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString()); } - private String getVariableEnableInstantiation (Token token) { - return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()), - stringTable.add(token.variableName, token), - token.variableOffset, + private String getVariableEnableInstantiation (Token token) + throws EntityException { + // + // Need scott fix + // + return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()), + stringTable.add(token.getDefaultSku().getStringOfVariableName(), token), + token.getDefaultSku().variableOffset, token.getPrimaryKeyString()); } @@ -1116,7 +1122,6 @@ class PcdDatabase { "Conf" + File.separator + "Pcd" + File.separator + "PcdDatabaseCommonDefinitions.sample"); - System.out.println(GlobalData.getWorkspacePath()); FileReader reader = new FileReader(file); BufferedReader in = new BufferedReader(reader); String str; @@ -1178,6 +1183,16 @@ class PcdDatabase { } +class ModuleInfo { + public ModuleSADocument.ModuleSA module; + public UsageInstance.MODULE_TYPE type; + + public ModuleInfo (ModuleSADocument.ModuleSA module, UsageInstance.MODULE_TYPE type) { + this.module = module; + this.type = type; + } +} + /** This action class is to collect PCD information from MSA, SPD, FPD xml file. This class will be used for wizard and build tools, So it can *not* inherit from buildAction or UIAction. @@ -1195,6 +1210,9 @@ public class CollectPCDAction { /// Message level for CollectPCDAction. private int originalMessageLevel; + /// Cache the fpd docment instance for private usage. + private FrameworkPlatformDescriptionDocument fpdDocInstance; + /** Set WorkspacePath parameter for this action class. @@ -1250,103 +1268,33 @@ public class CollectPCDAction { Core execution function for this action class. This function work flows will be: - 1) Get all token's platform information from FPD, and create token object into memory database. - 2) Get all token's module information from MSA, and create usage instance for every module's PCD entry. - 3) Get all token's inherited information from MSA's library, and create usage instance - for module who consume this library and create usage instance for library for building. - 4) Collect token's package information from SPD, update these information for token in memory - database. - 5) Generate 3 strings for a) All modules using Dynamic(Ex) PCD entry. (Token Number) - b) PEI PCD Database (C Structure) for PCD Service PEIM - c) DXE PCD Database (C structure) for PCD Service DXE + 1) Collect and prepocess PCD information from FPD file, all PCD + information will be stored into memory database. + 2) Generate 3 strings for + a) All modules using Dynamic(Ex) PCD entry.(Token Number) + b) PEI PCDDatabase (C Structure) for PCD Service PEIM. + c) DXE PCD Database (C structure) for PCD Service DXE. @throws EntityException Exception indicate failed to execute this action. **/ private void execute() throws EntityException { - FrameworkPlatformDescriptionDocument fpdDoc = null; - Object[][] modulePCDArray = null; - Map docMap = null; - ModuleSADocument.ModuleSA[] moduleSAs = null; - UsageInstance usageInstance = null; - String packageName = null; - String packageFullPath = null; - int index = 0; - int libraryIndex = 0; - int pcdArrayIndex = 0; - List listLibraryInstance = null; - String componentTypeStr = null; + // + // Get memoryDatabaseManager instance from GlobalData. + // The memoryDatabaseManager should be initialized for whatever build + // tools or wizard tools + // + if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) { + throw new EntityException("The instance of PCD memory database manager is null"); + } // // Collect all PCD information defined in FPD file. // Evenry token defind in FPD will be created as an token into // memory database. // - fpdDoc = createTokenInDBFromFPD(); - - // - // Searching MSA and SPD document. - // The information of MSA will be used to create usage instance into database. - // The information of SPD will be used to update the token information in database. - // - - HashMap map = new HashMap(); - map.put("FrameworkPlatformDescription", fpdDoc); - SurfaceAreaQuery.setDoc(map); - - moduleSAs = SurfaceAreaQuery.getFpdModules(); - for(index = 0; index < moduleSAs.length; index ++) { - // - // Get module document and use SurfaceAreaQuery to get PCD information - // - docMap = GlobalData.getDoc(moduleSAs[index].getModuleName()); - SurfaceAreaQuery.setDoc(docMap); - modulePCDArray = SurfaceAreaQuery.getModulePCDTokenArray(); - componentTypeStr = SurfaceAreaQuery.getComponentType(); - packageName = - GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName()); - packageFullPath = this.workspacePath + File.separator + - GlobalData.getPackagePath(packageName) + - packageName + ".spd"; - - if(modulePCDArray != null) { - // - // If current MSA contains information, then create usage - // instance for PCD information from MSA - // - for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length; - pcdArrayIndex ++) { - usageInstance = - createUsageInstanceFromMSA(moduleSAs[index].getModuleName(), - modulePCDArray[pcdArrayIndex]); - - if(usageInstance == null) { - continue; - } - // - // Get remaining PCD information from the package which this module belongs to - // - updateTokenBySPD(usageInstance, packageFullPath); - } - } - - // - // Get inherit PCD information which inherit from library instance of this module. - // - listLibraryInstance = - SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(), - CommonDefinition.AlwaysConsumed); - if(listLibraryInstance != null) { - for(libraryIndex = 0; libraryIndex < listLibraryInstance.size(); - libraryIndex ++) { - inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex), - moduleSAs[index].getModuleName(), - packageName, - componentTypeStr); - } - } - } + createTokenInDBFromFPD(); // // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver @@ -1363,9 +1311,8 @@ public class CollectPCDAction { @throws EntityException If the token does *not* exist in memory database. **/ - - private void genPcdDatabaseSourceCode () - throws EntityException { + private void genPcdDatabaseSourceCode() + throws EntityException { String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions (); ArrayList alPei = new ArrayList (); @@ -1389,424 +1336,1003 @@ public class CollectPCDAction { } /** - This function will collect inherit PCD information from library for a module. - - This function will create two usage instance for inherited PCD token, one is - for module and another is for library. - For module, if it inherited a PCD token from library, this PCD token's value - should be instanced in module level, and belongs to module. - For library, it also need a usage instance for build. + Get component array from FPD. - @param libraryName The name of library instance. - @param moduleName The name of module. - @param packageName The name of package while module belongs to. - @param parentcomponentType The component type of module. + This function maybe provided by some Global class. - @throws EntityException If the token does *not* exist in memory database. + @return List the component array. - **/ - private void inheritPCDFromLibraryInstance(String libraryName, - String moduleName, - String packageName, - String parentcomponentType) + */ + private List getComponentsFromFPD() throws EntityException { - Map docMap = null; - String primaryKeyString = null; - Object[][] libPcdDataArray = null; - UUID nullUUID = new UUID(0,0); - UUID platformUUID = nullUUID; - UUID tokenSpaceGuid = null; - int tokenIndex = 0; - Token token = null; - Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN; - UsageInstance usageInstance = null; - String packageFullPath = null; + HashMap map = new HashMap(); + List allModules = new ArrayList(); + ModuleInfo current = null; + int index = 0; + org.tianocore.Components components = null; + FrameworkModulesDocument.FrameworkModules fModules = null; + java.util.List modules = null; + - // - // Query PCD information from library's document. - // - docMap = GlobalData.getDoc(libraryName); - SurfaceAreaQuery.setDoc(docMap); - libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray(); + if (fpdDocInstance == null) { + try { + fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath)); + } catch(IOException ioE) { + throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage()); + } catch(XmlException xmlE) { + throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage()); + } - if(libPcdDataArray == null) { - return; } - for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) { - tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ? - nullUUID :(UUID)libPcdDataArray[tokenIndex][2]; + // + // Check whether FPD contians + // + fModules = fpdDocInstance.getFrameworkPlatformDescription().getFrameworkModules(); + if (fModules == null) { + return null; + } - // - // Get token from memory database. The token must be created from FPD already. - // - primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0], - tokenSpaceGuid, - platformUUID - ); + // + // BUGBUG: The following is work around code, the final component type should be get from + // GlobalData class. + // + components = fModules.getSEC(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.SEC)); + } + } - if(dbManager.isTokenInDatabase(primaryKeyString)) { - token = dbManager.getTokenByKey(primaryKeyString); - } else { - throw new EntityException("The PCD token " + primaryKeyString + - " defined in module " + moduleName + - " does not exist in FPD file!"); - } + components = fModules.getPEICORE(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEI_CORE)); + } + } - // - // Create usage instance for module. - // - pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]); - usageInstance = new UsageInstance(token, - Token.PCD_USAGE.ALWAYS_CONSUMED, - pcdType, - CommonDefinition.getComponentType(parentcomponentType), - libPcdDataArray[tokenIndex][3], - null, - (String) libPcdDataArray[tokenIndex][5], - "", - moduleName, - packageName, - true); - if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) { - token.addUsageInstance(usageInstance); + components = fModules.getPEIM(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEIM)); + } + } - packageFullPath = this.workspacePath + File.separator + - GlobalData.getPackagePath(packageName) + - packageName + ".spd"; - updateTokenBySPD(usageInstance, packageFullPath); + components = fModules.getDXECORE(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_CORE)); } + } - // - // We need create second usage instance for inherited case, which - // add library as an usage instance, because when build a module, and - // if module inherited from base library, then build process will build - // library at first. - // - if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) { - packageName = GlobalData.getPackageNameForModule(libraryName); - usageInstance = new UsageInstance(token, - Token.PCD_USAGE.ALWAYS_CONSUMED, - pcdType, - CommonDefinition.ComponentTypeLibrary, - libPcdDataArray[tokenIndex][3], - null, - (String)libPcdDataArray[tokenIndex][5], - "", - libraryName, - packageName, - false); - token.addUsageInstance(usageInstance); + components = fModules.getDXEDRIVERS(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_DRIVERS)); + } + } + + components = fModules.getOTHERCOMPONENTS(); + if (components != null) { + modules = components.getModuleSAList(); + for (index = 0; index < modules.size(); index ++) { + allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.OTHER_COMPONENTS)); } } + + return allModules; } /** - Create usage instance for PCD token defined in MSA document - - A PCD token maybe used by many modules, and every module is one of usage - instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is - consumer type usage instance of this token, and for ALWAYS_PRODUCED, - SOMETIMES_PRODUCED, it is produce type usage instance. - - @param moduleName The name of module - @param tokenInfoInMsa The PCD token information array retrieved from MSA. + Create token instance object into memory database, the token information + comes for FPD file. Normally, FPD file will contain all token platform + informations. - @return UsageInstance The usage instance created in memroy database. + @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage. - @throws EntityException If token did not exist in database yet. + @throws EntityException Failed to parse FPD xml file. **/ - private UsageInstance createUsageInstanceFromMSA(String moduleName, - Object[] tokenInfoInMsa) + private void createTokenInDBFromFPD() throws EntityException { - String packageName = null; - UsageInstance usageInstance = null; - UUID tokenSpaceGuid = null; - UUID nullUUID = new UUID(0,0); - String primaryKeyString = null; - UUID platformTokenSpace = nullUUID; - Token token = null; - Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN; - Token.PCD_USAGE pcdUsage = Token.PCD_USAGE.UNKNOWN; - - tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2]; - - primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0], - tokenSpaceGuid, - platformTokenSpace); + int index = 0; + int index2 = 0; + int pcdIndex = 0; + List pcdBuildDataArray = new ArrayList(); + PcdBuildDefinition.PcdData pcdBuildData = null; + Token token = null; + SkuInstance skuInstance = null; + int skuIndex = 0; + List modules = null; + String primaryKey = null; + String exceptionString = null; + UsageInstance usageInstance = null; + String primaryKey1 = null; + String primaryKey2 = null; + boolean isDuplicate = false; + Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN; + Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN; + int tokenNumber = 0; + String moduleName = null; + String datum = null; + int maxDatumSize = 0; // - // Get token object from memory database firstly. - // - if(dbManager.isTokenInDatabase(primaryKeyString)) { - token = dbManager.getTokenByKey(primaryKeyString); - } else { - throw new EntityException("The PCD token " + primaryKeyString + " defined in module " + - moduleName + " does not exist in FPD file!" ); + // ---------------------------------------------- + // 1), Get all from FPD file. + // ---------------------------------------------- + // + modules = getComponentsFromFPD(); + + if (modules == null) { + throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in in FPD file!"); } - pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]); - pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]); - packageName = GlobalData.getPackageNameForModule(moduleName); + // + // ------------------------------------------------------------------- + // 2), Loop all modules to process for each module. + // ------------------------------------------------------------------- + // + for (index = 0; index < modules.size(); index ++) { + isDuplicate = false; + for (index2 = 0; index2 < index; index2 ++) { + // + // BUGBUG: For transition schema, we can *not* get module's version from + // , It is work around code. + // + primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(), + null, + null, + null, + modules.get(index).module.getArch().toString(), + null); + primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(), + null, + null, + null, + modules.get(index2).module.getArch().toString(), + null); + if (primaryKey1.equalsIgnoreCase(primaryKey2)) { + isDuplicate = true; + break; + } + } + + if (isDuplicate) { + continue; + } + + // + // It is legal for a module does not contains ANY pcd build definitions. + // + if (modules.get(index).module.getPcdBuildDefinition() == null) { + continue; + } + + pcdBuildDataArray = modules.get(index).module.getPcdBuildDefinition().getPcdDataList(); + + moduleName = modules.get(index).module.getModuleName(); - if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) { - // - // BUGBUG: It is legal that same base name exist in one FPD file. In furture - // we should use "Guid, Version, Package" and "Arch" to differ a module. - // So currently, warning should be disabled. // - //ActionMessage.warning(this, - // "In module " + moduleName + " exist more than one PCD token " + token.cName - // ); - return null; + // ---------------------------------------------------------------------- + // 2.1), Loop all Pcd entry for a module and add it into memory database. + // ---------------------------------------------------------------------- + // + for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) { + pcdBuildData = pcdBuildDataArray.get(pcdIndex); + primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(), + translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid())); + pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()); + datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString()); + tokenNumber = Integer.decode(pcdBuildData.getToken().toString()); + datum = pcdBuildData.getValue(); + maxDatumSize = pcdBuildData.getMaxDatumSize(); + + // + // Check is exist? In future, because all schema verification will tools + // will check that, following checking code could be removed. + // + if (pcdBuildData.getTokenSpaceGuid() == null) { + exceptionString = String.format("[FPD file error] There is no for PCD %s in module %s! This is required!", + pcdBuildData.getCName(), + moduleName); + throw new EntityException(exceptionString); + } + + // + // ------------------------------------------------------------------------------------------- + // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule + // ------------------------------------------------------------------------------------------- + // + if (!Token.isDynamic(pcdType)) { + // + // Value is required. + // + if (datum == null) { + exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!", + pcdBuildData.getCName(), + moduleName); + throw new EntityException(exceptionString); + } + + // + // Check whether the datum size is matched datum type. + // + if ((exceptionString = verifyDatum(pcdBuildData.getCName(), + moduleName, + datum, + datumType, + maxDatumSize)) != null) { + throw new EntityException(exceptionString); + } + } + + // + // --------------------------------------------------------------------------------- + // 2.1.2), Create token or update token information for current anaylized PCD data. + // --------------------------------------------------------------------------------- + // + if (dbManager.isTokenInDatabase(primaryKey)) { + // + // If the token is already exist in database, do some necessary checking + // and add a usage instance into this token in database + // + token = dbManager.getTokenByKey(primaryKey); + + // + // checking for DatumType, DatumType should be unique for one PCD used in different + // modules. + // + if (token.datumType != datumType) { + exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!", + pcdBuildData.getCName(), + pcdBuildData.getDatumType().toString(), + Token.getStringOfdatumType(token.datumType)); + throw new EntityException(exceptionString); + } + + // + // Check token number is valid + // + if (tokenNumber != token.tokenNumber) { + 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!", + pcdBuildData.getCName(), + moduleName); + throw new EntityException(exceptionString); + } + + // + // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic. + // + if (token.isDynamicPCD != Token.isDynamic(pcdType)) { + exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+ + "is different with others module's", + token.cName, + moduleName); + throw new EntityException(exceptionString); + } + + if (token.isDynamicPCD) { + // + // Check datum is equal the datum in dynamic information. + // For dynamic PCD, you can do not write in sperated every in different , + // But if you write, the must be same as the value in . + // + if (!token.isSkuEnable() && + (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) && + (datum != null)) { + if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) { + exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in is "+ + "not equal to the datum in , it is "+ + "illega! You could no set in for a dynamic PCD!", + token.cName, + moduleName); + throw new EntityException(exceptionString); + } + } + + if ((maxDatumSize != 0) && + (maxDatumSize != token.datumSize)){ + exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+ + "is different with %d defined in !", + token.cName, + moduleName, + maxDatumSize, + token.datumSize); + throw new EntityException(exceptionString); + } + } + + } else { + // + // If the token is not in database, create a new token instance and add + // a usage instance into this token in database. + // + token = new Token(pcdBuildData.getCName(), + translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid())); + + token.datumType = datumType; + token.tokenNumber = tokenNumber; + token.isDynamicPCD = Token.isDynamic(pcdType); + token.datumSize = maxDatumSize; + + if (token.isDynamicPCD) { + // + // For Dynamic and Dynamic Ex type, need find the dynamic information + // in section in FPD file. + // + updateDynamicInformation(moduleName, + token, + datum, + maxDatumSize); + } + + dbManager.addTokenToDatabase(primaryKey, token); + } + + // + // ----------------------------------------------------------------------------------- + // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type. + // ----------------------------------------------------------------------------------- + // + token.updateSupportPcdType(pcdType); + + // + // ------------------------------------------------ + // 2.1.4), Create an usage instance for this token. + // ------------------------------------------------ + // + usageInstance = new UsageInstance(token, + moduleName, + null, + null, + null, + modules.get(index).type, + pcdType, + modules.get(index).module.getArch().toString(), + null, + datum, + maxDatumSize); + token.addUsageInstance(usageInstance); + } } + } - // - // BUGBUG: following code could be enabled at current schema. Because - // current schema does not provide usage information. - // - // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his - // usage is always ALWAYS_CONSUMED - // - //if((pcdType != Token.PCD_TYPE.DYNAMIC) && - // (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) { - pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED; - //} - - usageInstance = new UsageInstance(token, - pcdUsage, - pcdType, - CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()), - tokenInfoInMsa[3], - null, - (String) tokenInfoInMsa[5], - "", - moduleName, - packageName, - false); + /** + Verify the datum value according its datum size and datum type, this + function maybe moved to FPD verification tools in future. + + @param cName + @param moduleName + @param datum + @param datumType + @param maxDatumSize + + @return String + */ + /***/ + public String verifyDatum(String cName, + String moduleName, + String datum, + Token.DATUM_TYPE datumType, + int maxDatumSize) { + String exceptionString = null; + int value; + BigInteger value64; + String subStr; + + if (moduleName == null) { + moduleName = "section "; + } else { + moduleName = "module " + moduleName; + } - // - // Use default value defined in MSA to update datum of token, - // if datum of token does not defined in FPD file. - // - if((token.datum == null) &&(tokenInfoInMsa[3] != null)) { - token.datum = tokenInfoInMsa[3]; + if (maxDatumSize == 0) { + exceptionString = String.format("[FPD file error] You maybe miss for PCD %s in %s", + cName, + moduleName); + return exceptionString; } - token.addUsageInstance(usageInstance); + switch (datumType) { + case UINT8: + if (maxDatumSize != 1) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is UINT8, but datum size is %d, they are not matched!", + cName, + moduleName, + maxDatumSize); + return exceptionString; + } + + if (datum != null) { + try { + value = Integer.decode(datum); + } catch (NumberFormatException nfeExp) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+ + "digital format of UINT8", + cName, + moduleName); + return exceptionString; + } + if (value > 0xFF) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+ + " the max size of UINT8 - 0xFF", + cName, + moduleName, + datum); + return exceptionString; + } + } + break; + case UINT16: + if (maxDatumSize != 2) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is UINT16, but datum size is %d, they are not matched!", + cName, + moduleName, + maxDatumSize); + return exceptionString; + } + if (datum != null) { + try { + value = Integer.decode(datum); + } catch (NumberFormatException nfeExp) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+ + "not valid digital of UINT16", + cName, + moduleName); + return exceptionString; + } + if (value > 0xFFFF) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+ + "which exceed the range of UINT16 - 0xFFFF", + cName, + moduleName, + datum); + return exceptionString; + } + } + break; + case UINT32: + if (maxDatumSize != 4) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is UINT32, but datum size is %d, they are not matched!", + cName, + moduleName, + maxDatumSize); + return exceptionString; + } + + if (datum != null) { + try { + if (datum.length() > 2) { + if ((datum.charAt(0) == '0') && + ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){ + subStr = datum.substring(2, datum.length()); + value64 = new BigInteger(subStr, 16); + } else { + value64 = new BigInteger(datum); + } + } else { + value64 = new BigInteger(datum); + } + } catch (NumberFormatException nfeExp) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+ + "valid digital of UINT32", + cName, + moduleName); + return exceptionString; + } + + if (value64.bitLength() > 32) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+ + "exceed the range of UINT32 - 0xFFFFFFFF", + cName, + moduleName, + datum); + return exceptionString; + } + } + break; + case UINT64: + if (maxDatumSize != 8) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is UINT64, but datum size is %d, they are not matched!", + cName, + moduleName, + maxDatumSize); + return exceptionString; + } + + if (datum != null) { + try { + if (datum.length() > 2) { + if ((datum.charAt(0) == '0') && + ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){ + subStr = datum.substring(2, datum.length()); + value64 = new BigInteger(subStr, 16); + } else { + value64 = new BigInteger(datum); + } + } else { + value64 = new BigInteger(datum); + } + } catch (NumberFormatException nfeExp) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+ + " digital of UINT64", + cName, + moduleName); + return exceptionString; + } + + if (value64.bitLength() > 64) { + exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+ + "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF", + cName, + moduleName, + datum); + return exceptionString; + } + } + break; + case BOOLEAN: + if (maxDatumSize != 1) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is BOOLEAN, but datum size is %d, they are not matched!", + cName, + moduleName, + maxDatumSize); + return exceptionString; + } + + if (datum != null) { + if (!(datum.equalsIgnoreCase("TRUE") || + datum.equalsIgnoreCase("FALSE"))) { + exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+ + "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'", + cName, + moduleName); + return exceptionString; + } - return usageInstance; + } + break; + case POINTER: + if (datum == null) { + break; + } + + char ch = datum.charAt(0); + int start, end; + String strValue; + // + // For void* type PCD, only three datum is support: + // 1) Unicode: string with start char is "L" + // 2) Ansci: String start char is "" + // 3) byte array: String start char "{" + // + if (ch == 'L') { + start = datum.indexOf('\"'); + end = datum.lastIndexOf('\"'); + if ((start > end) || + (end > datum.length())|| + ((start == end) && (datum.length() > 0))) { + exceptionString = String.format("The datum type of PCD %s in %s is VOID* and datum is "+ + "a UNICODE string because start with L\", but format maybe"+ + "is not right, correct UNICODE string is L\"...\"!", + cName, + moduleName); + return exceptionString; + } + + strValue = datum.substring(start + 1, end); + if ((strValue.length() * 2) > maxDatumSize) { + exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is "+ + "a UNICODE string, but the datum size is %d exceed to : %d", + cName, + moduleName, + strValue.length() * 2, + maxDatumSize); + return exceptionString; + } + } else if (ch == '\"'){ + start = datum.indexOf('\"'); + end = datum.lastIndexOf('\"'); + if ((start > end) || + (end > datum.length())|| + ((start == end) && (datum.length() > 0))) { + exceptionString = String.format("The datum type of PCD %s in %s is VOID* and datum is "+ + "a ANSCII string because start with \", but format maybe"+ + "is not right, correct ANSIC string is \"...\"!", + cName, + moduleName); + return exceptionString; + } + strValue = datum.substring(start + 1, end); + if ((strValue.length()) > maxDatumSize) { + exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is "+ + "a ANSCI string, but the datum size is %d which exceed to : %d", + cName, + moduleName, + strValue.length(), + maxDatumSize); + return exceptionString; + } + } else if (ch =='{') { + String[] strValueArray; + + start = datum.indexOf('{'); + end = datum.lastIndexOf('}'); + strValue = datum.substring(start, end); + strValueArray = strValue.split(","); + if (strValueArray.length > maxDatumSize) { + exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is byte"+ + "array, but the number of bytes is %d which exceed to : %d!", + cName, + moduleName, + strValueArray.length, + maxDatumSize); + return exceptionString; + } + } else { + exceptionString = String.format("The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+ + "1) UNICODE string: like L\"xxxx\";\r\n"+ + "2) ANSIC string: like \"xxx\";\r\n"+ + "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+ + "But the datum in seems does not following above format!", + cName, + moduleName); + return exceptionString; + } + break; + default: + exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+ + "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN", + cName, + moduleName); + return exceptionString; + } + return null; } /** - Create token instance object into memory database, the token information - comes for FPD file. Normally, FPD file will contain all token platform - informations. - - This fucntion should be executed at firsly before others collection work - such as searching token information from MSA, SPD. - - @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage. - - @throws EntityException Failed to parse FPD xml file. - - **/ - private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD() + Get dynamic information for a dynamic PCD from seciton in FPD file. + + This function should be implemented in GlobalData in future. + + @param token The token instance which has hold module's PCD information + @param moduleName The name of module who will use this Dynamic PCD. + + @return DynamicPcdBuildDefinitions.PcdBuildData + */ + /***/ + private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token, + String moduleName) throws EntityException { - XmlObject doc = null; - FrameworkPlatformDescriptionDocument fpdDoc = null; - int index = 0; - List pcdBuildDataArray = new ArrayList(); - PcdBuildData pcdBuildData = null; - Token token = null; - UUID nullUUID = new UUID(0,0); - UUID platformTokenSpace= nullUUID; - List skuDataArray = new ArrayList(); - SkuInstance skuInstance = null; - int skuIndex = 0; + int index = 0; + String exceptionString = null; + String dynamicPrimaryKey = null; + DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null; + List dynamicPcdBuildDataArray = null; // - // Get all tokens from FPD file and create token into database. + // If FPD document is not be opened, open and initialize it. // + if (fpdDocInstance == null) { + try { + fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath)); + } catch(IOException ioE) { + throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage()); + } catch(XmlException xmlE) { + throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage()); + } + } - try { - doc = XmlObject.Factory.parse(new File(fpdFilePath)); - } catch(IOException ioE) { - throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath); - } catch(XmlException xmlE) { - throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath); + dynamicPcdBuildDefinitions = fpdDocInstance.getFrameworkPlatformDescription().getDynamicPcdBuildDefinitions(); + if (dynamicPcdBuildDefinitions == null) { + exceptionString = String.format("[FPD file error] There are no in FPD file but contains Dynamic type "+ + "PCD entry %s in module %s!", + token.cName, + moduleName); + throw new EntityException(exceptionString); } - // - // Get memoryDatabaseManager instance from GlobalData. - // - if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) { - throw new EntityException("The instance of PCD memory database manager is null"); + dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList(); + for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) { + // + // Check is exist? In future, because all schema verification will tools + // will check that, following checking code could be removed. + // + if (dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid() == null) { + exceptionString = String.format("[FPD file error] There is no for PCD %s in ! This is required!", + dynamicPcdBuildDataArray.get(index).getCName()); + throw new EntityException(exceptionString); + } + + dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(), + translateSchemaStringToUUID(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid())); + if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) { + return dynamicPcdBuildDataArray.get(index); + } } - dbManager = new MemoryDatabaseManager(); + return null; + } - if(!(doc instanceof FrameworkPlatformDescriptionDocument)) { - throw new EntityException("File " + fpdFilePath + - " is not a FrameworkPlatformDescriptionDocument"); + /** + Update dynamic information for PCD entry. + + Dynamic information is retrieved from in + FPD file. + + @param moduleName The name of the module who use this PCD + @param token The token instance + @param datum The in module's PCD information + @param maxDatumSize The in module's PCD information + + @return Token + */ + private Token updateDynamicInformation(String moduleName, + Token token, + String datum, + int maxDatumSize) + throws EntityException { + int index = 0; + int offset; + String exceptionString = null; + DynamicTokenValue dynamicValue; + SkuInstance skuInstance = null; + String temp; + boolean hasSkuId0 = false; + + List skuInfoList = null; + DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null; + + dynamicInfo = getDynamicInfoFromFPD(token, moduleName); + if (dynamicInfo == null) { + exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+ + "there is no dynamic information in "+ + "in FPD file, but it is required!", + token.cName, + moduleName); + throw new EntityException(exceptionString); } - fpdDoc =(FrameworkPlatformDescriptionDocument)doc; + token.datumSize = dynamicInfo.getMaxDatumSize(); + + exceptionString = verifyDatum(token.cName, + moduleName, + null, + token.datumType, + token.datumSize); + if (exceptionString != null) { + throw new EntityException(exceptionString); + } + + if ((maxDatumSize != 0) && + (maxDatumSize != token.datumSize)) { + exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+ + "the datum size in is %d, they are not match!", + token.cName, + moduleName, + maxDatumSize, + dynamicInfo.getMaxDatumSize()); + throw new EntityException(exceptionString); + } + + skuInfoList = dynamicInfo.getSkuInfoList(); // - // Add all tokens in FPD into Memory Database. - // - pcdBuildDataArray = - fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList(); - for(index = 0; - index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray(); - index ++) { - pcdBuildData = pcdBuildDataArray.get(index); - token = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0)); + // Loop all sku data + // + for (index = 0; index < skuInfoList.size(); index ++) { + skuInstance = new SkuInstance(); // - // BUGBUG: in FPD, should be defined as + // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value. + // + temp = skuInfoList.get(index).getSkuId().toString(); + skuInstance.id = Integer.decode(temp); + if (skuInstance.id == 0) { + hasSkuId0 = true; + } // - token.datum = pcdBuildData.getDefaultValue(); - token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue()); - token.hiiEnabled = pcdBuildData.getHiiEnable(); - token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid()); - token.variableName = pcdBuildData.getVariableName(); - token.variableOffset = Integer.decode(pcdBuildData.getDataOffset()); - token.skuEnabled = pcdBuildData.getSkuEnable(); - token.maxSkuCount = Integer.decode(pcdBuildData.getMaxSku()); - token.skuId = Integer.decode(pcdBuildData.getSkuId()); - token.skuDataArrayEnabled = pcdBuildData.getSkuDataArrayEnable(); - token.assignedtokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue()); - skuDataArray = pcdBuildData.getSkuDataArray1(); - token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString()); - token.datumSize = pcdBuildData.getDatumSize(); - - if(skuDataArray != null) { - for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) { - // - // BUGBUG: Now in current schema, The value is defined as String type, - // it is not correct, the type should be same as the datumType - // - skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(), - ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue()); - token.skuData.add(skuInstance); + // Judge whether is DefaultGroup at first, because most case is DefautlGroup. + // + if (skuInfoList.get(index).getValue() != null) { + skuInstance.value.setValue(skuInfoList.get(index).getValue()); + if ((exceptionString = verifyDatum(token.cName, + null, + skuInfoList.get(index).getValue(), + token.datumType, + token.datumSize)) != null) { + throw new EntityException(exceptionString); } - } - if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName, - token.tokenSpaceName, - platformTokenSpace))) { - // - // If found duplicate token, Should tool be hold? + token.skuData.add(skuInstance); + // - ActionMessage.warning(this, - "Token " + token.cName + " exists in token database"); + // Judege wether is same of datum between module's information + // and dynamic information. + // + if (datum != null) { + if ((skuInstance.id == 0) && + !datum.equalsIgnoreCase(skuInfoList.get(index).getValue())) { + exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+ + "value of sku 0 data in is " + skuInstance.value.value + ". They are must be same!"+ + " or you could not define value for a dynamic PCD in every !"; + throw new EntityException(exceptionString); + } + } + continue; + } + + // + // Judge whether is HII group case. + // + if (skuInfoList.get(index).getVariableName() != null) { + exceptionString = null; + if (skuInfoList.get(index).getVariableGuid() == null) { + exceptionString = String.format("[FPD file error] For dynamic PCD %s in section in FPD "+ + "file, who use HII, but there is no defined for Sku %d data!", + token.cName, + index); + + } + + if (skuInfoList.get(index).getVariableOffset() == null) { + exceptionString = String.format("[FPD file error] For dynamic PCD %s in section in FPD "+ + "file, who use HII, but there is no defined for Sku %d data!", + token.cName, + index); + } + + if (skuInfoList.get(index).getHiiDefaultValue() == null) { + exceptionString = String.format("[FPD file error] For dynamic PCD %s in section in FPD "+ + "file, who use HII, but there is no defined for Sku %d data!", + token.cName, + index); + } + + if (exceptionString != null) { + throw new EntityException(exceptionString); + } + + if ((exceptionString = verifyDatum(token.cName, + null, + skuInfoList.get(index).getHiiDefaultValue(), + token.datumType, + token.datumSize)) != null) { + throw new EntityException(exceptionString); + } + + offset = Integer.decode(skuInfoList.get(index).getVariableOffset()); + if (offset > 0xFFFF) { + throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+ + "exceed 64K, it is not allowed!", + token.cName, + index)); + } + + skuInstance.value.setHiiData(skuInfoList.get(index).getVariableName(), + translateSchemaStringToUUID(skuInfoList.get(index).getVariableGuid().toString()), + skuInfoList.get(index).getVariableOffset(), + skuInfoList.get(index).getHiiDefaultValue()); + token.skuData.add(skuInstance); + continue; + } + + if (skuInfoList.get(index).getVpdOffset() != null) { + skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset()); + token.skuData.add(skuInstance); continue; } - token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()); - dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName, - token.tokenSpaceName, - platformTokenSpace), - token); + + exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+ + "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.", + token.cName); + throw new EntityException(exceptionString); } - return fpdDoc; + if (!hasSkuId0) { + exceptionString = String.format("[FPD file error] For dynamic PCD %s in , there are "+ + "no sku id = 0 data, which is required for every dynamic PCD", + token.cName); + throw new EntityException(exceptionString); + } + + return token; } /** - Update PCD token in memory database by help information in SPD. - - After create token from FPD and create usage instance from MSA, we should collect - PCD package level information from SPD and update token information in memory - database. - - @param usageInstance The usage instance defined in MSA and want to search in SPD. - @param packageFullPath The SPD file path. - - @throws EntityException Failed to parse SPD xml file. - + Translate the schema string to UUID instance. + + In schema, the string of UUID is defined as following two types string: + 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( + )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})? + + 2) GuidNamingConvention: pattern = + [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} + + This function will convert string and create uuid instance. + + @param uuidString UUID string in XML file + + @return UUID UUID instance **/ - private void updateTokenBySPD(UsageInstance usageInstance, - String packageFullPath) + private UUID translateSchemaStringToUUID(String uuidString) throws EntityException { - PackageSurfaceAreaDocument pkgDoc = null; - PcdDefinitions pcdDefinitions = null; - List pcdEntryArray = new ArrayList(); - int index = 0; - boolean isFoundInSpd = false; - Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN; + String temp; + String[] splitStringArray; + int index; + int chIndex; + int chLen; - try { - pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath)); - } catch(IOException ioE) { - throw new EntityException("Can't find the FPD xml fle:" + packageFullPath); - } catch(XmlException xmlE) { - throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath); - } - pcdDefinitions = pkgDoc.getPackageSurfaceArea().getPcdDefinitions(); - // - // It is illege for SPD file does not contains any PCD information. - // - if (pcdDefinitions == null) { - return; + if (uuidString == null) { + return null; } - pcdEntryArray = pcdDefinitions.getPcdEntryList(); - if (pcdEntryArray == null) { - return; + if (uuidString.length() == 0) { + return null; } - for(index = 0; index < pcdEntryArray.size(); index ++) { - if(pcdEntryArray.get(index).getCName().equalsIgnoreCase( - usageInstance.parentToken.cName)) { - isFoundInSpd = true; - // - // From SPD file , we can get following information. - // Token: Token number defined in package level. - // PcdItemType: This item does not single one. It means all supported item type. - // datumType: UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN - // datumSize: The size of default value or maxmine size. - // defaultValue: This value is defined in package level. - // HelpText: The help text is provided in package level. - // - usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken()); - - if(pcdEntryArray.get(index).getDatumType() != null) { - datumType = Token.getdatumTypeFromString( - pcdEntryArray.get(index).getDatumType().toString()); - if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) { - usageInstance.parentToken.datumType = datumType; - } else { - if(datumType != usageInstance.parentToken.datumType) { - throw new EntityException("Different datum types are defined for Token :" + - usageInstance.parentToken.cName); - } - } + if (uuidString.equals("0") || + uuidString.equalsIgnoreCase("0x0")) { + return new UUID(0, 0); + } - } else { - throw new EntityException("The datum type for token " + usageInstance.parentToken.cName + - " is not defind in SPD file " + packageFullPath); - } + // + // If the UUID schema string is GuidArrayType type then need translate + // to GuidNamingConvention type at first. + // + if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) { + splitStringArray = uuidString.split("," ); + if (splitStringArray.length != 11) { + throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString); + } - usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue(); - usageInstance.helpTextInSPD = "Help Text in SPD"; + // + // Remove blank space from these string and remove header string "0x" + // + for (index = 0; index < 11; index ++) { + splitStringArray[index] = splitStringArray[index].trim(); + splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length()); + } - // - // If token's datum is not valid, it indicate that datum is not provided - // in FPD and defaultValue is not provided in MSA, then use defaultValue - // in SPD as the datum of token. - // - if(usageInstance.parentToken.datum == null) { - if(pcdEntryArray.get(index).getDefaultValue() != null) { - usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue(); - } else { - throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName + - ", MSA and SPD also does not provide for this token!"); - } + // + // Add heading '0' to normalize the string length + // + for (index = 3; index < 11; index ++) { + chLen = splitStringArray[index].length(); + for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) { + splitStringArray[index] = "0" + splitStringArray[index]; } } + + // + // construct the final GuidNamingConvention string + // + temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s", + splitStringArray[0], + splitStringArray[1], + splitStringArray[2], + splitStringArray[3], + splitStringArray[4], + splitStringArray[5], + splitStringArray[6], + splitStringArray[7], + splitStringArray[8], + splitStringArray[9], + splitStringArray[10]); + uuidString = temp; } + + return UUID.fromString(uuidString); } /** @@ -1844,11 +2370,11 @@ public class CollectPCDAction { **/ public static void main(String argv[]) throws EntityException { CollectPCDAction ca = new CollectPCDAction(); - ca.setWorkspacePath("G:/mdk"); - ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/Nt32.fpd"); + ca.setWorkspacePath("m:/tianocore_latest/edk2"); + ca.setFPDFilePath("m:/tianocore_latest/edk2/EdkNt32Pkg/Nt32.fpd"); ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL); GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db", - "G:/mdk"); + "m:/tianocore_latest/edk2"); ca.execute(); } }