From 8840ad589e758e0aa57982f5b7acfa898c63c409 Mon Sep 17 00:00:00 2001 From: klu2 Date: Sun, 4 Jun 2006 10:00:41 +0000 Subject: [PATCH] PCD tools update: 1) CollectPCDAction will get all PCD information from FPD file but *not* search SPD and MSA file. 2) ALL PcdBuildDeclaration in FPD file has been moved from common to seperated module's . Common was removed from FPD file. 3) The platform information for Dyanmic and DynamicEx type PCD should be record into now. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@415 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/EdkModulePkg-All-Archs.fpd | 208 +--- EdkModulePkg/EdkModulePkg.fpd | 203 ---- EdkNt32Pkg/Nt32.fpd | 598 ------------ MdePkg/MdePkg-All-Archs.fpd | 182 ---- MdePkg/MdePkg.fpd | 182 ---- .../org/tianocore/build/autogen/AutoGen.java | 20 +- .../tianocore/build/fpd/FpdParserTask.java | 8 +- .../build/pcd/action/CollectPCDAction.java | 887 +++++++++--------- .../build/pcd/action/PCDAutoGenAction.java | 335 +++---- .../pcd/action/ShowPCDDatabaseAction.java | 7 +- .../pcd/entity/MemoryDatabaseManager.java | 221 ++--- .../org/tianocore/build/pcd/entity/Token.java | 213 ++--- .../build/pcd/entity/UsageInstance.java | 597 +++++------- .../build/pcd/exception/EntityException.java | 2 +- .../build/pcd/ui/PCDDatabaseFrame.java | 26 +- 15 files changed, 978 insertions(+), 2711 deletions(-) diff --git a/EdkModulePkg/EdkModulePkg-All-Archs.fpd b/EdkModulePkg/EdkModulePkg-All-Archs.fpd index 4dcf32449b..dd4b712a0f 100644 --- a/EdkModulePkg/EdkModulePkg-All-Archs.fpd +++ b/EdkModulePkg/EdkModulePkg-All-Archs.fpd @@ -14671,7 +14671,7 @@ - + PcdMaximumUnicodeStringLength @@ -14794,7 +14794,7 @@ - + PcdMaximumUnicodeStringLength @@ -14934,7 +14934,7 @@ - + PcdMaximumUnicodeStringLength @@ -15074,7 +15074,7 @@ - + PcdMaximumUnicodeStringLength @@ -15214,7 +15214,7 @@ - + PcdMaximumUnicodeStringLength @@ -15354,7 +15354,7 @@ - + PcdMaximumUnicodeStringLength @@ -15494,7 +15494,7 @@ - + PcdMaximumUnicodeStringLength @@ -15651,7 +15651,7 @@ - + PcdMaximumUnicodeStringLength @@ -15808,7 +15808,7 @@ - + PcdMaximumUnicodeStringLength @@ -15948,7 +15948,7 @@ - + PcdMaximumUnicodeStringLength @@ -16088,7 +16088,7 @@ - + PcdMaximumUnicodeStringLength @@ -16228,7 +16228,7 @@ - + PcdMaximumUnicodeStringLength @@ -16368,7 +16368,7 @@ - + PcdMaximumUnicodeStringLength @@ -16508,7 +16508,7 @@ - + PcdMaximumUnicodeStringLength @@ -16648,7 +16648,7 @@ - + PcdMaximumUnicodeStringLength @@ -16788,7 +16788,7 @@ - + PcdMaximumUnicodeStringLength @@ -16928,7 +16928,7 @@ - + PcdMaxPeiPcdCallBackNumberPerPcdEntry @@ -17102,7 +17102,7 @@ - + PcdMaximumUnicodeStringLength @@ -17242,7 +17242,7 @@ - + PcdMaximumUnicodeStringLength @@ -17382,7 +17382,7 @@ - + PcdMaximumUnicodeStringLength @@ -17522,7 +17522,7 @@ - + PcdMaximumUnicodeStringLength @@ -17663,7 +17663,7 @@ - - - PcdMaximumUnicodeStringLength - 0x00000001 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumAsciiStringLength - 0x00000002 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumLinkedListLength - 0x00000003 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdSpinLockTimeout - 0x00000004 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 10000000 - - - PcdDebugPropertyMask - 0x00000005 - UINT8 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x1f - - - PcdDebugPrintErrorLevel - 0x00000006 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x80000000 - - - PcdReportStatusCodePropertyMask - 0x00000007 - UINT8 - false - false - false - false - false - 0x00 - 0x00 - 1 - 0 - L"" - 0 - 0 - 0x07 - - - PcdDebugClearMemoryValue - 0x00000008 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0xAF - - - PcdPerformanceLibraryPropertyMask - 0x00000009 - UINT8 - false - false - false - false - false - 0x00 - 0x00 - 1 - 0 - L"" - 0 - 0 - 0 - - - PcdWinNtPhysicalDisk - 0x00001000 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 24 - 0 - L"" - 0 - 0 - L"FW;40960;512" - - - PcdWinNtVirtualDisk - 0x00001001 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 24 - 0 - L"" - 0 - 0 - L"FW;40960;512" - - - PcdWinNtSerialPort - 0x00001002 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 20 - 0 - L"" - 0 - 0 - L"COM1!COM2" - - - PcdWinNtUga - 0x00001003 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 50 - 0 - L"" - 0 - 0 - L"UGA Window 1!UGA Window 2" - - - PcdWinNtFileSystem - 0x00001004 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 120 - 0 - L"" - 0 - 0 - L".!C:\\D\\work\\Remodel\\mdk\\EdkShellBinPkg\\bin\\ia32\\Apps" - - - PcdWinNtMemorySize - 0x00001005 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 10 - 0 - L"" - 0 - 0 - L"64!64" - - - PcdWinNtMemorySizeForSecMain - 0x00001005 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 10 - 0 - L"" - 0 - 0 - L"64!64" - - - PcdWinNtBootMode - 0x00001006 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 1 - - - PcdWinNtCpuModel - 0x00001007 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 48 - 0 - L"" - 0 - 0 - L"Intel(R) Processor Model" - - - PcdWinNtCpuSpeed - 0x00001008 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 8 - 0 - L"" - 0 - 0 - L"3000" - - - PcdWinNtFirmwareVolume - 0x00001009 - VOID* - false - false - false - false - false - 0x00 - 0x00 - 44 - 0 - L"" - 0 - 0 - L"..\\..\\Fv\\Fv_Recovery.fd" - - - PcdWinNtConsole - 0x0000100a - VOID* - false - false - false - false - false - 0x00 - 0x00 - 50 - 0 - L"" - 0 - 0 - L"Bus Driver Console Window" - - - PcdRothmanTest - 0x0000100b - UINT32 - true - false - false - false - false - 0x00 - 0x00 - 4 - 0B3ADA4F-AE56-4c24-8DEA-F03B7558AE50 - RothmanVariable - 0 - 0 - 0 - - - PcdWinNtBinaryPatch1 - 0x0001000b - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x1234 - - - PcdWinNtBinaryPatch2 - 0x0001000c - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x5678 - - - PcdWinNtFeatureFlag1 - 0x0001000d - BOOLEAN - false - false - false - false - false - 0x00 - 0x00 - 1 - 0 - L"" - 0 - 0 - 0x1 - - - PcdWinNtDynamicUINT32 - 0x0001000e - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x0 - - - PcdMaxPeiPcdCallBackNumberPerPcdEntry - 0x0001000f - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x8 - - - PcdVpdBaseAddress - 0x00010010 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - 0x0 - - - PcdTestDynamicUint8 - 0x00011000 - UINT8 - false - false - false - false - false - 0x00 - 0x00 - 1 - 0 - L"" - 0 - 0 - 0x1 - - - PcdTestDynamicUint16 - 0x00011001 - UINT16 - false - false - false - false - false - 0x00 - 0x00 - 2 - 0 - L"" - 0 - 0 - 0x1234 - - - PcdTestDynamicUint32 - 0x00011002 - UINT32 - false - false - false - false - false - 0x00 - 0x00 - 4 - 0 - L"" - 0 - 0 - NoDefault - - - PcdTestDynamicUint64 - 0x00011003 - UINT64 - false - false - false - false - false - 0x00 - 0x00 - 8 - 0 - L"" - 0 - 0 - NoDefault - - - PcdTestDynamicBoolean - 0x00011004 - BOOLEAN - false - false - false - false - false - 0x00 - 0x00 - 1 - 0 - L"" - 0 - 0 - NoDefault - - PcdWinNtMemorySize diff --git a/MdePkg/MdePkg-All-Archs.fpd b/MdePkg/MdePkg-All-Archs.fpd index 2be9874ef8..392c239f87 100644 --- a/MdePkg/MdePkg-All-Archs.fpd +++ b/MdePkg/MdePkg-All-Archs.fpd @@ -2793,188 +2793,6 @@ - - - PcdMaximumUnicodeStringLength - 0x00000001 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumAsciiStringLength - 0x00000002 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumLinkedListLength - 0x00000003 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdSpinLockTimeout - 0x00000004 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 10000000 - - - PcdDebugPropertyMask - 0x00000005 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0 - - - PcdDebugPrintErrorLevel - 0x00000006 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 0x80000000 - - - PcdReportStatusCodePropertyMask - 0x00000007 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0 - - - PcdDebugClearMemoryValue - 0x00000008 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0xAF - - - PcdPerformanceLibraryPropertyMask - 0x00000009 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0x0 - - - PcdPciExpressBaseAddress - 0x0000000A - UINT64 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 0xE0000000 - - diff --git a/MdePkg/MdePkg.fpd b/MdePkg/MdePkg.fpd index d19cd89acb..e514d44159 100644 --- a/MdePkg/MdePkg.fpd +++ b/MdePkg/MdePkg.fpd @@ -1005,188 +1005,6 @@ - - - PcdMaximumUnicodeStringLength - 0x00000001 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumAsciiStringLength - 0x00000002 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdMaximumLinkedListLength - 0x00000003 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 1000000 - - - PcdSpinLockTimeout - 0x00000004 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 10000000 - - - PcdDebugPropertyMask - 0x00000005 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0 - - - PcdDebugPrintErrorLevel - 0x00000006 - UINT32 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 0x80000000 - - - PcdReportStatusCodePropertyMask - 0x00000007 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0 - - - PcdDebugClearMemoryValue - 0x00000008 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0xAF - - - PcdPerformanceLibraryPropertyMask - 0x00000009 - UINT8 - false - false - false - false - false - 0 - 0 - 1 - 0 - L"" - 0 - 0 - 0x0 - - - PcdPciExpressBaseAddress - 0x0000000A - UINT64 - false - false - false - false - false - 0 - 0 - 4 - 0 - L"" - 0 - 0 - 0xE0000000 - - diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java index f1e9c5b4ec..62bb4c6b59 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java +++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java @@ -408,8 +408,14 @@ public class AutoGen { // isPCDEmulatedDriver parameter will be removed. // try { - this.myPcdAutogen = new PCDAutoGenAction(baseName, - baseName.equalsIgnoreCase("PcdEmulatorPeim")); + this.myPcdAutogen = new PCDAutoGenAction(baseName, + null, + null, + null, + this.arch, + null, + baseName.equalsIgnoreCase("PcdEmulatorPeim"), + false); this.myPcdAutogen.execute(); } catch (Exception e) { throw new BuildException("PCD Autogen failed:" + e.getMessage()); @@ -543,8 +549,14 @@ public class AutoGen { // isPCDEmulatedDriver parameter will be removed. // try { - this.myPcdAutogen = new PCDAutoGenAction(baseName, baseName - .equalsIgnoreCase("PcdEmulatorPeim")); + this.myPcdAutogen = new PCDAutoGenAction(baseName, + null, + null, + null, + this.arch, + null, + baseName.equalsIgnoreCase("PcdEmulatorPeim"), + true); this.myPcdAutogen.execute(); } catch (Exception e) { throw new BuildException(e.getMessage()); diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java index 1de29ea373..1e3de2a4e6 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java +++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java @@ -785,12 +785,6 @@ public class FpdParserTask extends Task { public void collectPCDInformation() { CollectPCDAction collectAction = new CollectPCDAction (); // - // Set memory database log file path. It should be put into same directory with FPD file. - // - GlobalData.getPCDMemoryDBManager().setLogFileName( - fpdFilename.getPath() + ".PCDMemroyDatabaseLog.txt" - ); - // // Collect all PCD information from FPD to MSA, and get help information from SPD. // These all information will be stored into memory database for future usage such // as autogen. @@ -802,7 +796,7 @@ public class FpdParserTask extends Task { ActionMessage.MAX_MESSAGE_LEVEL ); } catch (Exception exp) { - throw new BuildException (exp.getMessage()); + throw new BuildException (String.format("Fail to do PCD preprocess from FPD file, the cause is %s", exp.getMessage())); } } } 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 1eb060b6a6..4001558ef6 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java @@ -31,11 +31,16 @@ import java.util.UUID; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; +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.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData.SkuData; import org.tianocore.PcdDefinitionsDocument.PcdDefinitions; +import org.tianocore.PcdDynamicBuildDeclarationsDocument.PcdDynamicBuildDeclarations; import org.tianocore.build.autogen.CommonDefinition; import org.tianocore.build.global.GlobalData; import org.tianocore.build.global.SurfaceAreaQuery; @@ -706,7 +711,7 @@ class PcdDatabase { private void getTwoGroupsOfTokens (ArrayList alTokens, List initTokens, List uninitTokens) { for (int i = 0; i < alTokens.size(); i++) { - Token t = alTokens.get(i); + Token t = (Token)alTokens.get(i); if (t.hasDefaultValue()) { initTokens.add(t); } else { @@ -970,7 +975,7 @@ class PcdDatabase { sizeTable.add(token); localTokenNumberTable.add(token); - token.assignedtokenNumber = assignedTokenNumber++; + token.tokenNumber = assignedTokenNumber++; } @@ -1109,7 +1114,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; @@ -1171,6 +1175,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. @@ -1188,6 +1202,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. @@ -1243,103 +1260,34 @@ 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); - } - } + createTokenInDBFromFPD(); - // - // 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); - } - } - } // // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver @@ -1356,9 +1304,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 (); @@ -1382,424 +1329,488 @@ 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]; - - // - // Get token from memory database. The token must be created from FPD already. - // - primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0], - tokenSpaceGuid, - platformUUID - ); - - 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!"); - } - - // - // 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); + // + // Check whether FPD contians + // + fModules = fpdDocInstance.getFrameworkPlatformDescription().getFrameworkModules(); + if (fModules == null) { + return null; + } - packageFullPath = this.workspacePath + File.separator + - GlobalData.getPackagePath(packageName) + - packageName + ".spd"; - updateTokenBySPD(usageInstance, packageFullPath); + // + // 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)); } + } - // - // 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.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 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. - - @return UsageInstance The usage instance created in memroy database. - - @throws EntityException If token did not exist in database yet. - - **/ - private UsageInstance createUsageInstanceFromMSA(String moduleName, - Object[] tokenInfoInMsa) - 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); - - // - // 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!" ); + 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)); + } } - pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]); - pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]); - - packageName = GlobalData.getPackageNameForModule(moduleName); - 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; + 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)); + } } - // - // 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); - - // - // 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]; + 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)); + } } - token.addUsageInstance(usageInstance); - - return usageInstance; + 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 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() + private void createTokenInDBFromFPD() 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; + int index2 = 0; + int pcdIndex = 0; + List pcdBuildDataArray = new ArrayList(); + PcdBuildData pcdBuildData = null; + Token token = null; + UUID nullUUID = new UUID(0,0); + UUID platformTokenSpace= nullUUID; + SkuInstance skuInstance = null; + int skuIndex = 0; + List modules = null; + String primaryKey = null; + PcdBuildData.SkuData[] skuDataArray = null; + String exceptionString = null; + UsageInstance usageInstance = null; + String primaryKey1 = null; + String primaryKey2 = null; + boolean isDuplicate = false; + java.util.List tokenGuidStringArray = null; // - // Get all tokens from FPD file and create token into database. + // Get all from FPD file. // + modules = getComponentsFromFPD(); - 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); + if (modules == null) { + throw new EntityException("No modules in FPD file, Please check whether there are elements in in FPD file!"); } // - // Get memoryDatabaseManager instance from GlobalData. - // - if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) { - throw new EntityException("The instance of PCD memory database manager is null"); - } - - dbManager = new MemoryDatabaseManager(); + // 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(), + translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()), + modules.get(index).module.getPackageName(), + translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()), + modules.get(index).module.getArch().toString(), + null); + primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(), + translateSchemaStringToUUID(modules.get(index2).module.getModuleGuid()), + modules.get(index2).module.getPackageName(), + translateSchemaStringToUUID(modules.get(index2).module.getPackageGuid()), + modules.get(index2).module.getArch().toString(), + null); + if (primaryKey1.equalsIgnoreCase(primaryKey2)) { + isDuplicate = true; + break; + } + } - if(!(doc instanceof FrameworkPlatformDescriptionDocument)) { - throw new EntityException("File " + fpdFilePath + - " is not a FrameworkPlatformDescriptionDocument"); - } + if (isDuplicate) { + continue; + } - fpdDoc =(FrameworkPlatformDescriptionDocument)doc; + if (modules.get(index).module.getPcdBuildDeclarations() == null) { + continue; + } + pcdBuildDataArray = modules.get(index).module.getPcdBuildDeclarations().getPcdBuildDataList(); + if (pcdBuildDataArray == null) { + continue; + } + if (pcdBuildDataArray.size() == 0) { + continue; + } - // - // 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)); - // - // BUGBUG: in FPD, should be defined as // - 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 ++) { + // 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())); + + + 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); + // - // BUGBUG: Now in current schema, The value is defined as String type, - // it is not correct, the type should be same as the datumType + // Checking for DatumSize + // + if (token.datumSize != pcdBuildData.getDatumSize()) { + exceptionString = String.format("The datum size of PCD entry %s is %d, which is different with %d defined in before!", + pcdBuildData.getCName(), pcdBuildData.getDatumSize(), token.datumSize); + throw new EntityException(exceptionString); + } + // - skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(), - ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue()); - token.skuData.add(skuInstance); + // checking for DatumType + // + if (token.datumType != Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString())) { + exceptionString = String.format("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); + } + } 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.datum = pcdBuildData.getDefaultValue(); + token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()); + token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString()); + token.datumSize = pcdBuildData.getDatumSize(); + token.skuId = Integer.decode(pcdBuildData.getSkuId()); + + if (pcdBuildData.getToken() == null) { + exceptionString = String.format("In FPD file, No defined for PCD entry %s in module %s", + token.cName, + modules.get(index).module.getModuleName()); + throw new EntityException(exceptionString); + } + token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue()); + + if ((token.pcdType == Token.PCD_TYPE.DYNAMIC) || + (token.pcdType == Token.PCD_TYPE.DYNAMIC_EX)) { + updateDynamicInformation(modules.get(index).module.getModuleName(), token); + } + + dbManager.addTokenToDatabase(primaryKey, token); } - } - if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName, - token.tokenSpaceName, - platformTokenSpace))) { - // - // If found duplicate token, Should tool be hold? // - ActionMessage.warning(this, - "Token " + token.cName + " exists in token database"); - continue; + // Create an usage instance for this token + // + usageInstance = new UsageInstance(token, + Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()), + modules.get(index).module.getModuleName(), + translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()), + modules.get(index).module.getPackageName(), + translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()), + modules.get(index).type, + Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()), + modules.get(index).module.getArch().toString(), + null, + pcdBuildData.getDefaultValue()); + token.addUsageInstance(usageInstance); } - token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()); - dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName, - token.tokenSpaceName, - platformTokenSpace), - token); } - - return fpdDoc; } /** - 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. - + Update dynamic information for PCD entry. + + Dynamic information is retrieved from in + FPD file. + + @param moduleName + @param token + + @return Token **/ - private void updateTokenBySPD(UsageInstance usageInstance, - String packageFullPath) + private Token updateDynamicInformation(String moduleName, Token token) 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; + PcdDynamicBuildDeclarations pcdDynamicBuildDescriptions = null; + + boolean isFound = false; + int index = 0; + String primaryKey = null; + SkuInstance skuInstance = null; + int skuIndex = 0; + String exceptionString = null; + PcdDynamicBuildDeclarations.PcdBuildData.SkuData[] skuDataArray = null; + List pcdDynamicBuildDataArray = null; - 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 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()); + } } - pcdEntryArray = pcdDefinitions.getPcdEntryList(); - if (pcdEntryArray == null) { - return; + pcdDynamicBuildDescriptions = fpdDocInstance.getFrameworkPlatformDescription().getPcdDynamicBuildDeclarations(); + if (pcdDynamicBuildDescriptions == null) { + throw new EntityException(String.format("There are no in FPD file but contains Dynamic type "+ + "PCD entry %s in module %s!", + token.cName, + moduleName)); } - 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. + + pcdDynamicBuildDataArray = pcdDynamicBuildDescriptions.getPcdBuildDataList(); + if (pcdDynamicBuildDataArray == null) { + throw new EntityException(String.format("There are no PcdDynamicBuildData in section but contains Dynamic type"+ + "PCD entry %s in module %s.!", + token.cName, + moduleName)); + } + + isFound = false; + for (index = 0; index < pcdDynamicBuildDataArray.size(); index ++) { + if (pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().size() != 0) { + primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), + translateSchemaStringToUUID(pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().get(0))); + } else { + primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), + translateSchemaStringToUUID(null)); + } + + if (primaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) { + isFound = true; + // + // For Hii related value + // + token.hiiEnabled = pcdDynamicBuildDataArray.get(index).getHiiEnable(); + if (token.hiiEnabled) { + token.variableGuid = Token.getGUIDFromSchemaObject(pcdDynamicBuildDataArray.get(index).getVariableGuid()); + if (token.variableGuid == null) { + throw new EntityException(String.format("In for PCD entry %s, HiiEnable is true" + + "but no is found! Please fix the FPD file!", + token.cName)); - 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); - } + } + token.variableName = pcdDynamicBuildDataArray.get(index).getVariableName(); + if (token.variableName == null) { + throw new EntityException(String.format("In for PCD entry %s, HiiEnable is true" + + "but no is found! Please fix the FPD file!", + token.cName)); } - } else { - throw new EntityException("The datum type for token " + usageInstance.parentToken.cName + - " is not defind in SPD file " + packageFullPath); + if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) { + throw new EntityException(String.format("In for PCD entry %s, HiiEnable is true" + + "but no is found! Please fix the FPD file!", + token.cName)); + } + token.variableOffset = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset()); } - usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue(); - usageInstance.helpTextInSPD = "Help Text in SPD"; - // - // 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. + // For Vpd related value + // + token.vpdEnabled = pcdDynamicBuildDataArray.get(index).getVpdEnable(); + if (token.vpdEnabled) { + if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) { + throw new EntityException(String.format("In for PCD entry %s, VpdEnable is true" + + "but no is found! Please fix the FPD file!", + token.cName)); + } + token.vpdOffset = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset()); + } + // - 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!"); + // For SkuData + // + token.skuEnabled = pcdDynamicBuildDataArray.get(index).getSkuEnable(); + if (token.skuEnabled) { + skuDataArray = (PcdDynamicBuildDeclarations.PcdBuildData.SkuData[])pcdDynamicBuildDataArray.get(index).getSkuDataList().toArray(); + token.maxSkuCount = Integer.decode(pcdDynamicBuildDataArray.get(index).getMaxSku()); + if (skuDataArray == null) { + exceptionString = String.format("In FPD file, the is true for PCD entry %s in module %s, But no any sku data.", + token.cName, moduleName); + throw new EntityException(exceptionString); + } + if (token.maxSkuCount != pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray()) { + exceptionString = String.format("In FPD file, is not equal to the size of for PCD entry %s in module %s", + token.cName, moduleName); + throw new EntityException(exceptionString); + } + + for (skuIndex = 0; skuIndex < pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray(); skuIndex ++) { + skuInstance = new SkuInstance(skuDataArray[skuIndex].getId(), + skuDataArray[skuIndex].getValue()); + token.skuData.add(skuInstance); } } + break; } } + if (!isFound) { + exceptionString = String.format("In FPD file, No dynamic PCD data for PCD entry %s in module %s", + token.cName, + moduleName); + throw new EntityException(exceptionString); + } + + return token; + } + + /** + 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 UUID translateSchemaStringToUUID(String uuidString) + throws EntityException { + String temp; + String[] splitStringArray; + int index; + int chIndex; + int chLen; + + if (uuidString == null) { + return null; + } + + if (uuidString.length() == 0) { + return null; + } + + // + // 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 ("Wrong format for UUID string: " + uuidString); + } + + // + // 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()); + } + + // + // 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); } /** @@ -1837,11 +1848,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:/ForPcd/edk2"); + ca.setFPDFilePath("M:/ForPcd/edk2/EdkNt32Pkg/Nt32.fpd"); ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL); GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db", - "G:/mdk"); + "M:/ForPcd/edk2"); ca.execute(); } } diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java index 63698b1473..04e585be3b 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java @@ -18,6 +18,7 @@ package org.tianocore.build.pcd.action; import java.io.File; import java.util.List; +import java.util.UUID; import org.tianocore.build.global.GlobalData; import org.tianocore.build.pcd.entity.MemoryDatabaseManager; @@ -39,11 +40,35 @@ public class PCDAutoGenAction extends BuildAction { /// private String moduleName; /// + /// The Guid of module which is analyzed currently. + /// + private UUID moduleGuid; + /// + /// The name of package whose module is analysized currently. + /// + private String packageName; + /// + /// The Guid of package whose module is analyszed curretnly. + /// + private UUID packageGuid; + /// + /// The arch of current module + /// + private String arch; + /// + /// The version of current module + /// + private String version; + /// /// Wheter current module is PCD emulated driver. It is only for /// emulated PCD driver and will be kept until PCD IMAGE tool ready. /// private boolean isEmulatedPCDDriver; /// + /// Whether current autogen is for building library used by current module. + /// + private boolean isBuildUsedLibrary; + /// /// The generated string for header file. /// private String hAutoGenString; @@ -61,6 +86,26 @@ public class PCDAutoGenAction extends BuildAction { this.moduleName = moduleName; } + public void setModuleGuid(UUID moduleGuid) { + this.moduleGuid = moduleGuid; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void setPackageGuid(UUID packageGuid) { + this.packageGuid = packageGuid; + } + + public void setArch(String arch) { + this.arch = arch; + } + + public void setVersion(String version) { + this.version = version; + } + /** Set parameter isEmulatedPCDDriver @@ -70,6 +115,10 @@ public class PCDAutoGenAction extends BuildAction { this.isEmulatedPCDDriver = isEmulatedPCDDriver; } + public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) { + this.isBuildUsedLibrary = isBuildUsedLibrary; + } + /** Get the output of generated string for header file. @@ -96,10 +145,26 @@ public class PCDAutoGenAction extends BuildAction { @param moduleName Parameter of this action class. @param isEmulatedPCDDriver Parameter of this action class. **/ - public PCDAutoGenAction(String moduleName, boolean isEmulatedPCDDriver) { - dbManager = null; + public PCDAutoGenAction(String moduleName, + UUID moduleGuid, + String packageName, + UUID packageGuid, + String arch, + String version, + boolean isEmulatedPCDDriver, + boolean isBuildUsedLibrary) { + dbManager = null; + hAutoGenString = ""; + cAutoGenString = ""; + setIsEmulatedPCDDriver(isEmulatedPCDDriver); setModuleName(moduleName); + setModuleGuid(moduleGuid); + setPackageName(packageName); + setPackageGuid(packageGuid); + setArch(arch); + setVersion(version); + setIsBuildUsedLibrary(isBuildUsedLibrary); } /** @@ -130,7 +195,6 @@ public class PCDAutoGenAction extends BuildAction { void performAction() throws BuildActionException { ActionMessage.debug(this, "Starting PCDAutoGenAction to generate autogen.h and autogen.c!..."); - // // Check the PCD memory database manager is valid. // @@ -141,20 +205,15 @@ public class PCDAutoGenAction extends BuildAction { dbManager = GlobalData.getPCDMemoryDBManager(); if(dbManager.getDBSize() == 0) { - return; + return; } ActionMessage.debug(this, "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens"); - hAutoGenString = ""; - cAutoGenString = ""; - if(isEmulatedPCDDriver) { - generateAutogenForPCDEmulatedDriver(); - } else { - generateAutogenForModule(); - } + + generateAutogenForModule(); } /** @@ -168,7 +227,30 @@ public class PCDAutoGenAction extends BuildAction { int index; List usageInstanceArray; - usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName); + if (!isBuildUsedLibrary) { + usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName, + moduleGuid, + packageName, + packageGuid, + arch, + version); + dbManager.UsageInstanceContext = usageInstanceArray; + dbManager.CurrentModuleName = moduleName; + } else { + usageInstanceArray = dbManager.UsageInstanceContext; + // + // For building MDE package, although all module are library, but PCD entries of + // these library should be used to autogen. + // + if (usageInstanceArray == null) { + usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName, + moduleGuid, + packageName, + packageGuid, + arch, + version); + } + } if(usageInstanceArray.size() != 0) { // @@ -182,7 +264,7 @@ public class PCDAutoGenAction extends BuildAction { "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) + "]: " + usageInstanceArray.get(index).parentToken.cName); try { - usageInstanceArray.get(index).generateAutoGen(); + usageInstanceArray.get(index).generateAutoGen(isBuildUsedLibrary); hAutoGenString += usageInstanceArray.get(index).getHAutogenStr() + "\r\n"; cAutoGenString += usageInstanceArray.get(index).getCAutogenStr() + "\r\n"; } catch(EntityException exp) { @@ -190,6 +272,10 @@ public class PCDAutoGenAction extends BuildAction { } } + // + // Work around code, In furture following code should be modified that get + // these information from Uplevel Autogen tools. + // if (moduleName.equalsIgnoreCase("PcdPeim")) { hAutoGenString += dbManager.PcdPeimHString; cAutoGenString += dbManager.PcdPeimCString; @@ -206,64 +292,6 @@ public class PCDAutoGenAction extends BuildAction { ); } - /** - Generate all PCD autogen string and the emulated PCD IMAGE array for emulated driver. - - Currently, we should generated all PCD information(maybe all dynamic) as array - in Pei emulated driver for simulating PCD runtime database. - - **/ - private void generateAutogenForPCDEmulatedDriver() { - int index; - Token[] tokenArray; - UsageInstance usageInstance; - - // - // Add "#include 'PcdLib.h'" for Header file - // - hAutoGenString = "#include \r\n"; - - tokenArray = dbManager.getRecordArray(); - for(index = 0; index < tokenArray.length; index ++) { - // - // Get one consumer instance and generate autogen for this token. - // - if(tokenArray[index].consumers != null ) { - if(tokenArray[index].consumers.size() != 0) { - usageInstance = tokenArray[index].consumers.get(0); - try { - usageInstance.generateAutoGen(); - } catch(EntityException exp) { - throw new BuildActionException(exp.getMessage()); - } - - hAutoGenString += usageInstance.getHAutogenStr(); - cAutoGenString += usageInstance.getCAutogenStr(); - - hAutoGenString += "\r\n"; - cAutoGenString += "\r\n"; - } else { - // - // If the PCD does *not* usded by any module, also generate - // it into autogen.h/autogen.c in Pcd driver according the - // information in FPD file. - // - generateUnReferencePcdAutogenString(tokenArray[index]); - } - } - } - - generatePCDEmulatedArray(tokenArray); - - ActionMessage.debug(this, - "PCD emulated driver's header: \r\n" + hAutoGenString + "\r\n" - ); - ActionMessage.debug(this, - "PCD emulated driver's C code: \r\n" + cAutoGenString + "\r\n" - ); - - } - /** Generate unreference token definition string for PCD emulated string. @@ -369,157 +397,6 @@ public class PCDAutoGenAction extends BuildAction { cAutoGenString += "\r\n"; } - /** - Generate PCDEmulated array in PCDEmulated driver for emulated runtime database. - - @param tokenArray All PCD token in memory database. - - @throws BuildActionException Unknown PCD_TYPE - **/ - private void generatePCDEmulatedArray(Token[] tokenArray) - throws BuildActionException { - int index; - Token token; - String[] guidStrArray; - String value; - - // - // The value of String type of PCD entry maybe use byte array but not string direcly - // such as {0x1, 0x2, 0x3}, and define PCD1_STRING_Value as L"string define here" - // For this case, we should generate a string array to C output and use the address - // of generated string array. - // - for(index = 0; index < tokenArray.length; index ++) { - token = tokenArray[index]; - - value = token.datum.toString(); - if(token.datumType == Token.DATUM_TYPE.POINTER) { - if(!((value.charAt(0) == 'L' && value.charAt(1) == '"') ||(value.charAt(0) == '"'))) { - cAutoGenString += String.format("UINT8 _mPcdArray%08x[] = %s;\r\n", - index, - value - ); - } - } - } - - // - // Output emulated PCD entry array - // - cAutoGenString += "\r\nEMULATED_PCD_ENTRY gEmulatedPcdEntry[] = {\r\n"; - - for(index = 0; index < tokenArray.length; index ++) { - token = tokenArray[index]; - - if(index != 0) { - cAutoGenString += ",\r\n"; - } - - // - // Print Start "{" for a Token item in array - // - cAutoGenString += " {\r\n"; - - // - // Print Token Name - // - cAutoGenString += String.format(" _PCD_TOKEN_%s,\r\n", token.cName); - - // - // Print Hii information - // - if(token.hiiEnabled) { - cAutoGenString += String.format(" TRUE,\r\n"); - } else { - cAutoGenString += String.format(" FALSE,\r\n"); - } - - // - // Print sku information - // - if(token.skuEnabled) { - cAutoGenString += String.format(" TRUE,\r\n"); - } else { - cAutoGenString += String.format(" FALSE,\r\n"); - } - - // - // Print maxSkuCount - // - cAutoGenString += String.format(" %d,\r\n", token.maxSkuCount); - - cAutoGenString += String.format(" %d,\r\n", token.skuId); - - if(token.variableGuid == null) { - cAutoGenString += " { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\r\n"; - } else { - guidStrArray =(token.variableGuid.toString()).split("-"); - - cAutoGenString += String.format(" { 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } },\r\n", - guidStrArray[0], - guidStrArray[1], - guidStrArray[2], - (guidStrArray[3].substring(0, 2)), - (guidStrArray[3].substring(2, 4)), - (guidStrArray[4].substring(0, 2)), - (guidStrArray[4].substring(2, 4)), - (guidStrArray[4].substring(4, 6)), - (guidStrArray[4].substring(6, 8)), - (guidStrArray[4].substring(8, 10)), - (guidStrArray[4].substring(10, 12)) - ); - - } - - value = token.datum.toString(); - if(token.datumType == Token.DATUM_TYPE.POINTER) { - if((value.charAt(0) == 'L' && value.charAt(1) == '"') || value.charAt(0) == '"') { - cAutoGenString += String.format(" sizeof(_PCD_VALUE_%s),\r\n", token.cName); - cAutoGenString += String.format(" 0, %s, %s,\r\n", token.variableName, value); - } else { - cAutoGenString += String.format(" sizeof(_mPcdArray%08x),\r\n", index); - cAutoGenString += String.format(" 0, &_mPcdArray%08x, %s,\r\n", index, token.variableName); - } - } else { - switch(token.datumType) { - case UINT8: - cAutoGenString += " 1,\r\n"; - break; - case UINT16: - cAutoGenString += " 2,\r\n"; - break; - case UINT32: - cAutoGenString += " 4,\r\n"; - break; - case UINT64: - cAutoGenString += " 8,\r\n"; - break; - case BOOLEAN: - cAutoGenString += " 1,\r\n"; - break; - default: - throw new BuildActionException("Unknown datum size"); - } - cAutoGenString += String.format(" %s, %s, NULL,\r\n", value, token.variableName); - } - - // - // Print end "}" for a token item in array - // - cAutoGenString += " }"; - } - - cAutoGenString += "\r\n};\r\n"; - cAutoGenString += "\r\n"; - cAutoGenString += "UINTN\r\n"; - cAutoGenString += "GetPcdDataBaseSize(\r\n"; - cAutoGenString += " VOID\r\n"; - cAutoGenString += " )\r\n"; - cAutoGenString += "{\r\n"; - cAutoGenString += " return sizeof(gEmulatedPcdEntry);\r\n"; - cAutoGenString += "}\r\n"; - } - /** Test case function @@ -527,8 +404,8 @@ public class PCDAutoGenAction extends BuildAction { **/ public static void main(String argv[]) { - String WorkSpace = "X:/edk2"; - String logFilePath = WorkSpace + "/EdkNt32Pkg/Nt32.fpd"; + String WorkSpace = "M:/ForPcd/edk2"; + String logFilePath = WorkSpace + "/MdePkg/MdePkg.fpd"; // // At first, CollectPCDAction should be invoked to collect @@ -538,8 +415,6 @@ public class PCDAutoGenAction extends BuildAction { GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db", WorkSpace); - GlobalData.getPCDMemoryDBManager().setLogFileName(logFilePath + ".PCDMemroyDatabaseLog.txt"); - try { collectionAction.perform(WorkSpace, logFilePath, @@ -551,7 +426,13 @@ public class PCDAutoGenAction extends BuildAction { // // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c // - PCDAutoGenAction autogenAction = new PCDAutoGenAction("PcdDxe", + PCDAutoGenAction autogenAction = new PCDAutoGenAction("BaseLib", + null, + null, + null, + null, + null, + false, false ); autogenAction.execute(); diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java index cd67dd46c9..8af812347f 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java @@ -93,7 +93,6 @@ public class ShowPCDDatabaseAction extends UIAction { // GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db", workspacePath); - GlobalData.getPCDMemoryDBManager().setLogFileName(fpdFilePath + ".PCDMemroyDatabaseLog.txt"); // // Collect PCD information. @@ -123,8 +122,10 @@ public class ShowPCDDatabaseAction extends UIAction { **/ public static void main(String[] argv) throws UIException { ShowPCDDatabaseAction showAction = new ShowPCDDatabaseAction(); - showAction.setWorkspacePath(argv[0]); - showAction.setFPDFilePath(argv[1]); + //showAction.setWorkspacePath(argv[0]); + //showAction.setFPDFilePath(argv[1]); + showAction.setWorkspacePath("M:/tianocore/edk2/trunk/edk2"); + showAction.setFPDFilePath("EdkNt32Pkg/Nt32.fpd"); showAction.execute(); } } diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java index 0acdad0948..b03cddeed4 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java @@ -26,8 +26,8 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.UUID; -import org.tianocore.build.autogen.CommonDefinition; import org.tianocore.build.pcd.action.ActionMessage; /** Database hold all PCD information comes from SPD, MSA, FPD file in memory. @@ -37,12 +37,18 @@ public class MemoryDatabaseManager { /// Memory database. The string "cName + SpaceNameGuid" is primary key. /// memory database is in global scope, and it will be used for others PCD tools. /// - private static Map memoryDatabase = null; + private static Map memoryDatabase = null; + /// - /// The log file name for dumping memory database. + /// Before build a module, the used libary will be build firstly, the PCD of these + /// libarry is inheritted by the module, so stored module's PCD information as PCD + /// context of building libary. + /// + public static List UsageInstanceContext = null; /// - private static String logFileName = null; - + /// + /// + public static String CurrentModuleName = null; public static String PcdPeimHString = ""; public static String PcdPeimCString = ""; public static String PcdDxeHString = ""; @@ -60,22 +66,6 @@ public class MemoryDatabaseManager { } } - /** - Get the log file name. - **/ - public String getLogFileName() { - return logFileName; - } - - /** - Set parameter log file name. - - @param fileName log file name parameter. - **/ - public void setLogFileName(String fileName) { - logFileName = fileName; - } - /** Judege whether token exists in memory database @@ -143,8 +133,12 @@ public class MemoryDatabaseManager { return tokenArray; } - - private ArrayList getDynamicRecordArray() { + /** + Get record array only contains DYNAMIC or DYNAMIC_EX type PCD. + + @return ArrayList + */ + private ArrayList getDynamicRecordArray() { Token[] tokenArray = getRecordArray(); int index = 0; int count = 0; @@ -170,40 +164,28 @@ public class MemoryDatabaseManager { public void getTwoPhaseDynamicRecordArray(ArrayList pei, ArrayList dxe) { int usageInstanceIndex = 0; int index = 0; - ArrayList tokenArrayList = getDynamicRecordArray(); - List usageInstanceArray = null; + ArrayList tokenArrayList = getDynamicRecordArray(); + Object[] usageInstanceArray = null; UsageInstance usageInstance = null; + //pei = new ArrayList(); + //dxe = new ArrayList(); + for (index = 0; index < tokenArrayList.size(); index++) { boolean found = false; Token token = (Token) tokenArrayList.get(index); - if (token.producers != null) { - usageInstanceArray = token.producers; - for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex++) { - usageInstance = (UsageInstance) usageInstanceArray.get(usageInstanceIndex); - if (CommonDefinition.isPeiPhaseComponent(usageInstance.componentType)) { + if (token.consumers != null) { + usageInstanceArray = token.consumers.entrySet().toArray(); + for (usageInstanceIndex = 0; usageInstanceIndex < token.consumers.size(); usageInstanceIndex ++) { + usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue()); + if (usageInstance.isPeiPhaseComponent()) { pei.add(token); found = true; break; } } - - } - if (!found) { - if (token.consumers != null) { - usageInstanceArray = token.consumers; - for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) { - usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex); - if (CommonDefinition.isPeiPhaseComponent(usageInstance.componentType)) { - pei.add(token); - found = true; - break; - } - } - } } - // // If no PEI components reference the PCD entry, we insert it to DXE list // if (!found) { @@ -215,17 +197,40 @@ public class MemoryDatabaseManager { } /** - Get all PCD record for a module according to module's name. + Get all PCD record for a module according to module's name, module's GUID, + package name, package GUID, arch, version information. @param moduleName the name of module. @return all usage instance for this module in memory database. **/ - public List getUsageInstanceArrayByModuleName(String moduleName) { + public List getUsageInstanceArrayByModuleName(String moduleName, + UUID moduleGuid, + String packageName, + UUID packageGuid, + String arch, + String version) { + + String primaryKey = UsageInstance.getPrimaryKey(moduleName, + moduleGuid, + packageName, + packageGuid, + arch, + version); + + return getUsageInstanceArrayByKeyString(primaryKey); + } + + /** + Get all PCD token for a usage instance according to primary key. + + @param primaryKey the primary key of usage instance. + + @return List + */ + public List getUsageInstanceArrayByKeyString(String primaryKey) { Token[] tokenArray = null; int recordIndex = 0; - int usageInstanceIndex = 0; - List usageInstanceArray = null; UsageInstance usageInstance = null; List returnArray = new ArrayList(); @@ -235,31 +240,14 @@ public class MemoryDatabaseManager { // Loop to find all PCD record related to current module // for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) { - if (tokenArray[recordIndex].producers != null) { - usageInstanceArray = tokenArray[recordIndex].producers; - for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) { - usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - returnArray.add(usageInstance); - } - } - } - - if (tokenArray[recordIndex].consumers != null) { - usageInstanceArray = tokenArray[recordIndex].consumers; - for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) { - usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - returnArray.add(usageInstance); - } + if (tokenArray[recordIndex].consumers.size() != 0) { + usageInstance = tokenArray[recordIndex].consumers.get(primaryKey); + if (usageInstance != null) { + returnArray.add(usageInstance); } } } - if (returnArray.size() == 0) { - ActionMessage.warning(this, "Can *not* find any usage instance for " + moduleName + " !"); - } - return returnArray; } @@ -274,112 +262,31 @@ public class MemoryDatabaseManager { int usageIndex = 0; int moduleIndex = 0; Token[] tokenArray = null; + Object[] usageInstanceArray = null; List moduleNames = new ArrayList(); UsageInstance usageInstance = null; boolean bFound = false; - tokenArray = this.getRecordArray(); - // - // Find all producer usage instance for retrieving module's name - // - for (indexToken = 0; indexToken < getDBSize(); indexToken ++) { - for (usageIndex = 0; usageIndex < tokenArray[indexToken].producers.size(); usageIndex ++) { - usageInstance = tokenArray[indexToken].producers.get(usageIndex); - bFound = false; - for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) { - if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) { - bFound = true; - break; - } - } - if (!bFound) { - moduleNames.add(usageInstance.moduleName); - } - } - } - + tokenArray = getRecordArray(); // // Find all consumer usage instance for retrieving module's name // for (indexToken = 0; indexToken < getDBSize(); indexToken ++) { + usageInstanceArray = tokenArray[indexToken].consumers.entrySet().toArray(); for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) { - usageInstance = tokenArray[indexToken].consumers.get(usageIndex); + usageInstance = (UsageInstance)((Map.Entry)usageInstanceArray[usageIndex]).getValue(); bFound = false; for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) { - if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) { + if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.getPrimaryKey())) { bFound = true; break; } } if (!bFound) { - moduleNames.add(usageInstance.moduleName); + moduleNames.add(usageInstance.getPrimaryKey()); } } } return moduleNames; } - - /** - Dump all PCD record into file for reviewing. - **/ - public void DumpAllRecords() { - BufferedWriter bWriter = null; - Object[] tokenArray = null; - Map.Entry entry = null; - Token token = null; - int index = 0; - int usageIndex = 0; - UsageInstance usageInstance = null; - String inheritString = null; - String componentTypeName = null; - - try { - bWriter = new BufferedWriter(new FileWriter(new File(logFileName))); - tokenArray = memoryDatabase.entrySet().toArray(); - for (index = 0; index < memoryDatabase.size(); index ++) { - entry =(Map.Entry) tokenArray [index]; - token =(Token) entry.getValue(); - bWriter.write("****** token [" + Integer.toString(index) + "] ******\r\n"); - bWriter.write(" cName:" + token.cName + "\r\n"); - for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) { - usageInstance =(UsageInstance)token.producers.get(usageIndex); - componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType); - - if (usageInstance.isInherit) { - inheritString = "Inherit"; - } else { - inheritString = ""; - } - bWriter.write(String.format(" (Producer)#%d: %s:%s Package:%s %s\r\n", - usageIndex, - componentTypeName, - usageInstance.moduleName, - usageInstance.packageName, - inheritString - ) - ); - } - for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) { - usageInstance =(UsageInstance)token.consumers.get(usageIndex); - componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType); - if (usageInstance.isInherit) { - inheritString = "Inherit"; - } else { - inheritString = ""; - } - bWriter.write(String.format(" (Consumer)#%d: %s:%s Package:%s %s\r\n", - usageIndex, - componentTypeName, - usageInstance.moduleName, - usageInstance.packageName, - inheritString - ) - ); - } - } - bWriter.close(); - } catch (IOException exp) { - ActionMessage.warning(this, "Failed to open database log file: " + logFileName); - } - } } diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java index 5931b8bceb..3136864872 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java @@ -18,8 +18,11 @@ package org.tianocore.build.pcd.entity; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.Map; +import java.util.HashMap; import org.tianocore.build.pcd.action.ActionMessage; +import org.tianocore.build.pcd.exception.EntityException; /** This class is to descript a PCD token object. The information of a token mainly comes from MSA, SPD and setting produced by platform developer. @@ -66,30 +69,11 @@ public class Token { /// public int tokenNumber; - /// - /// The token space name assigned by platform. For Non-DynamicEx driver this value is same. - /// assignedtokenSpaceName is defined in FPD. - /// - public UUID assignedtokenSpaceName; - - /// - /// The token number assigned by platform. The number indiect the offset of this token in platform - /// token space. - /// AssgiendtokenNumber is defined in FPD. - /// - public int assignedtokenNumber; - /// /// pcdType is the PCD item type defined by platform developer. /// public PCD_TYPE pcdType; - /// - /// PCDtype is set by platform developer. It is final PCD type of this token. - /// SupportedPcdType is defined in SPD. - /// - public PCD_TYPE[] supportedpcdType; - /// /// datumSize is to descript the fix size or max size for this token. /// datumSize is defined in SPD. @@ -102,13 +86,6 @@ public class Token { /// public DATUM_TYPE datumType; - /// - /// Isplatform is to descript whether this token is defined in platform level. - /// If token is belong to platform level. The value can be different for every - /// module. All are determined by platform developer. - /// - public boolean isPlatform; - /// /// hiiEnabled is to indicate whether the token support Hii functionality. /// hiiEnabled is defined in FPD. @@ -140,11 +117,6 @@ public class Token { /// public boolean skuEnabled; - /// - /// skuDataArrayEnabled is to indicate wheter use the skuData array or default value. - /// - public boolean skuDataArrayEnabled; - /// /// skuData contains all value for SkuNumber of token. /// skuData is defined in FPD. @@ -169,12 +141,6 @@ public class Token { /// public Object datum; - /// - /// Default value of this token. - /// This default value is defined in SPD level. - /// - public Object defaultValue; - /// /// BUGBUG: fix comment /// vpdEnabled is defined in FPD. @@ -187,55 +153,33 @@ public class Token { /// public long vpdOffset; - /// - /// producers array record all module private information who produce this PCD token. - /// - public List producers; - /// /// consumers array record all module private information who consume this PCD token. /// - public List consumers; + public Map consumers; - /** - Constructure function. - - Initialize the value of token. - - @param cName The cName of this token - @param tokenSpaceName The tokenSpaceName of this token, it is a GUID. - @param assignedtokenSpaceName The assignedtokenSpaceName of this token, it is a GUID. - - **/ - public Token(String cName, UUID tokenSpaceName, UUID assignedtokenSpaceName) { + public Token(String cName, UUID tokenSpaceName) { UUID nullUUID = new UUID(0, 0); this.cName = cName; - this.tokenSpaceName =(tokenSpaceName == null) ? nullUUID : tokenSpaceName; - this.assignedtokenSpaceName =(assignedtokenSpaceName == null) ? nullUUID : assignedtokenSpaceName; + this.tokenSpaceName = (tokenSpaceName == null) ? nullUUID : tokenSpaceName; this.tokenNumber = 0; - this.assignedtokenNumber = 0; this.pcdType = PCD_TYPE.UNKNOWN; - this.supportedpcdType = null; - this.isPlatform = false; this.datumType = DATUM_TYPE.UNKNOWN; this.datumSize = -1; - this.defaultValue = null; this.datum = null; this.hiiEnabled = false; this.variableGuid = null; this.variableName = ""; this.variableOffset = -1; this.skuEnabled = false; - this.skuDataArrayEnabled = false; this.skuId = -1; this.maxSkuCount = -1; this.skuData = new ArrayList(); this.vpdEnabled = false; this.vpdOffset = -1; - this.producers = new ArrayList(); - this.consumers = new ArrayList(); + this.consumers = new HashMap(); } /** @@ -247,19 +191,23 @@ public class Token { @return primary key for this token in token database. **/ - public static String getPrimaryKeyString(String cName, UUID tokenSpaceName, - UUID platformtokenSpaceName) { + public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) { UUID nullUUID = new UUID(0, 0); - if (platformtokenSpaceName == nullUUID) { - return cName + "_" + tokenSpaceName.toString().replace('-', '_'); + if (tokenSpaceName == null) { + return cName + "_" + nullUUID.toString().replace('-', '_'); } else { - return cName + "_" + platformtokenSpaceName.toString().replace('-', '_'); + return cName + "_" + tokenSpaceName.toString().replace('-', '_'); } } + /** + Get the token primary key in token database. + + @return String + */ public String getPrimaryKeyString () { - return cName + "_" + tokenSpaceName.toString().replace('-', '_'); + return Token.getPrimaryKeyString(cName, tokenSpaceName); } /** @@ -302,99 +250,52 @@ public class Token { @retval TRUE - Success to add usage instance. @retval FALSE - Fail to add usage instance **/ - public boolean addUsageInstance(UsageInstance usageInstance) { - if (usageInstance.usage == PCD_USAGE.UNKNOWN) { - return false; + public boolean addUsageInstance(UsageInstance usageInstance) + throws EntityException { + String exceptionStr; + + if (isUsageInstanceExist(usageInstance.moduleName, + usageInstance.moduleGUID, + usageInstance.packageName, + usageInstance.packageGUID, + usageInstance.arch, + usageInstance.version)) { + exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+ + "in modules PcdPeim in to make sure no duplicated definitions!", + usageInstance.parentToken.cName, + usageInstance.moduleName); + throw new EntityException(exceptionStr); } - if ((usageInstance.usage == PCD_USAGE.ALWAYS_PRODUCED) || - (usageInstance.usage == PCD_USAGE.SOMETIMES_PRODUCED)) { - producers.add(usageInstance); - } else { - consumers.add(usageInstance); - } + consumers.put(usageInstance.getPrimaryKey(), usageInstance); return true; } /** - Judge whether exist an usage instance for this token - - @param moduleName Use xmlFilePath as keyword to search the usage instance - - @retval PCD_USAGE - if UsageInstance exists. - @retval UNKNOWN - if UsageInstance does not exist, return UNKONW. - **/ - public PCD_USAGE isUsageInstanceExist(String moduleName) { - int index; - UsageInstance usageInstance; - - if (moduleName == null) { - ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!"); - return PCD_USAGE.UNKNOWN; - } - - if (moduleName.length() == 0) { - return PCD_USAGE.UNKNOWN; - } - - // - // Searching the usage instance in module's producer and consumer according to - // module's name. - // - for (index = 0; index < producers.size(); index ++) { - usageInstance =(UsageInstance)producers.get(index); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - return usageInstance.usage; - } - } - - for (index = 0; index < consumers.size(); index ++) { - usageInstance =(UsageInstance)consumers.get(index); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - return usageInstance.usage; - } - } - return PCD_USAGE.UNKNOWN; - } - - /** - Get usage instance according to a MSA file name - - @param moduleName The file path string of MSA file. - - @return usage instance object. - **/ - public UsageInstance getUsageInstance(String moduleName) { - int usageIndex; - UsageInstance usageInstance; - - if (moduleName == null) { - ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!"); - return null; - } - - if (moduleName.length() == 0) { - return null; - } - - if (producers.size() != 0) { - for (usageIndex = 0; usageIndex < producers.size(); usageIndex ++) { - usageInstance =(UsageInstance)producers.get(usageIndex); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - return usageInstance; - } - } - } - - if (consumers.size() != 0) { - for (usageIndex = 0; usageIndex < consumers.size(); usageIndex ++) { - usageInstance =(UsageInstance)consumers.get(usageIndex); - if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) { - return usageInstance; - } - } - } - return null; + Judge whether exist an usage instance for this token + + @param moduleName the name of module + @param moduleGuid the GUID name of modules + @param packageName the name of package contains this module + @param packageGuid the GUID name of package contains this module + @param arch the architecture string + @param version the version string + + @return boolean whether exist an usage instance for this token. + */ + public boolean isUsageInstanceExist(String moduleName, + UUID moduleGuid, + String packageName, + UUID packageGuid, + String arch, + String version) { + String keyStr = UsageInstance.getPrimaryKey(moduleName, + moduleGuid, + packageName, + packageGuid, + arch, + version); + return (consumers.get(keyStr) != null); } /** diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java index 2bd704d913..90c0f6322f 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java @@ -18,10 +18,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. package org.tianocore.build.pcd.entity; -import org.tianocore.build.pcd.exception.EntityException; -import org.tianocore.build.pcd.action.ActionMessage; +import java.util.UUID; import org.tianocore.build.autogen.CommonDefinition; +import org.tianocore.build.pcd.action.ActionMessage; +import org.tianocore.build.pcd.exception.EntityException; /** This class indicate an usage instance for a PCD token. This instance maybe a module @@ -29,50 +30,50 @@ import org.tianocore.build.autogen.CommonDefinition; is an usage instance for this PCD token. **/ public class UsageInstance { + /// + /// The module type of usage instance. + /// + public enum MODULE_TYPE {SEC, PEI_CORE, PEIM, DXE_CORE, DXE_DRIVERS, OTHER_COMPONENTS} /// /// This parent that this usage instance belongs to. /// public Token parentToken; /// - /// The usage of this token for platform or module. - /// - public Token.PCD_USAGE usage; - /// - /// Whether this usage instance inherit from library - /// - public boolean isInherit; - /// - /// The pcd type of this token for module. - /// - public Token.PCD_TYPE modulePcdType; - /// /// The name of the module who contains this PCD. /// public String moduleName; /// + /// The GUID of the module who contains this PCD. + /// + public UUID moduleGUID; + /// /// The name of the package whose module contains this PCD. /// public String packageName; /// - /// The component type for this usage instance. + /// The GUID of the package whose module contains this PCD. + /// + public UUID packageGUID; /// - public int componentType; - /// - /// The default value defined in MSA has high prior than defined in SPD. - /// - public Object defaultValueInMSA; + /// The PCD type defined for module + /// + public Token.PCD_TYPE modulePcdType; /// - /// The default value defined in SPD. + /// The arch string of module contains this PCD /// - public Object defaultValueInSPD; + public String arch; /// - /// Help text in MSA + /// The version of module contains this PCD + /// + public String version; /// - public String helpTextInMSA; + /// The module type for this usage instance. /// - /// Help text in SPD + public MODULE_TYPE moduleType; /// - public String helpTextInSPD; + /// The value of the PCD in this usage instance. + /// + public Object datum; /// /// Autogen string for header file. /// @@ -83,367 +84,265 @@ public class UsageInstance { public String cAutogenStr; /** - Constructure function - - @param parentToken Member variable. - @param usage Member variable. - @param pcdType Member variable. - @param componentType Member variable. - @param defaultValueInMSA Member variable. - @param defaultValueInSPD Member variable. - @param helpTextInMSA Member variable. - @param helpTextInSPD Member variable. - @param moduleName Member variable. - @param packageName Member variable. - @param isInherit Member variable. + Constructure function + + @param parentToken Member variable. + @param pcdType Member variable. + @param moduleName Member variable. + @param moduleGUID Member variable. + @param packageName Member variable. + @param packageGUID Member variable. + @param moduleType Member variable. + @param modulePcdType Member variable. + @param arch Member variable. + @param version Member variable. + @param value Member variable. **/ - public UsageInstance( - Token parentToken, - Token.PCD_USAGE usage, - Token.PCD_TYPE pcdType, - int componentType, - Object defaultValueInMSA, - Object defaultValueInSPD, - String helpTextInMSA, - String helpTextInSPD, - String moduleName, - String packageName, - boolean isInherit - ) - { - this.parentToken = parentToken; - this.usage = usage; - this.modulePcdType = pcdType; - this.componentType = componentType; - this.defaultValueInMSA = defaultValueInMSA; - this.defaultValueInSPD = defaultValueInSPD; - this.helpTextInMSA = helpTextInMSA; - this.helpTextInSPD = helpTextInSPD; - this.moduleName = moduleName; - this.packageName = packageName; - this.isInherit = isInherit; + public UsageInstance (Token parentToken, + Token.PCD_TYPE pcdType, + String moduleName, + UUID moduleGUID, + String packageName, + UUID packageGUID, + MODULE_TYPE moduleType, + Token.PCD_TYPE modulePcdType, + String arch, + String version, + Object value) { + this.parentToken = parentToken; + this.moduleName = moduleName; + this.moduleGUID = moduleGUID; + this.packageName = packageName; + this.packageGUID = packageGUID; + this.moduleType = moduleType; + this.modulePcdType = modulePcdType; + this.arch = arch; + this.version = version; + this.datum = value; + this.modulePcdType = pcdType; } /** - Generate autogen string for header file and C code file. - - @throws EntityException Fail to generate. + Get the primary key for usage instance array for every token. + + @param moduleName the name of module + @param moduleGUID the GUID name of module + @param packageName the name of package who contains this module + @param packageGUID the GUID name of package + @param arch the archtecture string + @param version the version of this module + + @return String primary key + */ + public static String getPrimaryKey(String moduleName, + UUID moduleGUID, + String packageName, + UUID packageGUID, + String arch, + String version) { + // + // Because currently transition schema not require write moduleGuid, package Name, Packge GUID in + // section, So currently no expect all paramter must be valid. + return (moduleName + "_" + + ((moduleGUID != null) ? moduleGUID.toString() : "NullModuleGuid") + "_" + + ((packageName != null) ? packageName : "NullPackageName") + "_" + + ((packageGUID != null) ? packageGUID.toString() : "NullPackageGuid") + "_" + + ((arch != null) ? arch : "NullArch") + "_" + + ((version != null) ? version : "NullVersion")); + } + + /** + Get primary key string for this usage instance + + @return String primary key string **/ - public void generateAutoGen() throws EntityException { - Object value = null; - int tokenNumber = 0; + public String getPrimaryKey() { + return UsageInstance.getPrimaryKey(moduleName, moduleGUID, packageName, packageGUID, arch, version); + } - hAutogenStr = ""; - cAutogenStr = ""; + /** + Judget whether current module is PEI driver + + @return boolean + */ + public boolean isPeiPhaseComponent() { + if ((moduleType == MODULE_TYPE.PEI_CORE) || + (moduleType == MODULE_TYPE.PEIM)) { + return true; + } + return false; + } - value = this.parentToken.datum; + /** + Generate autogen string for header file and C code file. + + @throws EntityException Fail to generate. + + @param isBuildUsedLibrary whether the autogen is for library. + */ + public void generateAutoGen(boolean isBuildUsedLibrary) + throws EntityException { - // - // If this pcd token's PCD_TYPE is DYNAMIC_EX, use itself token space name - // otherwices use assgined token space name from tool automatically. - // - if(parentToken.pcdType == Token.PCD_TYPE.DYNAMIC_EX) { - tokenNumber = parentToken.tokenNumber; - } else { - tokenNumber = parentToken.assignedtokenNumber; - } + hAutogenStr = ""; + cAutogenStr = ""; hAutogenStr += String.format("#define _PCD_TOKEN_%s 0x%016x\r\n", - parentToken.cName, tokenNumber); - + parentToken.cName, parentToken.tokenNumber); switch(modulePcdType) { case FEATURE_FLAG: - // - // BUGBUG: The judegement of module PCD type and platform PCD type should not be - // done here, but in wizard tools, But here is just following something - // PcdEmulation driver. - // - if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.FEATURE_FLAG.ordinal()) { - throw new EntityException( - String.format( - "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n", - parentToken.cName, - parentToken.pcdType.name(), - modulePcdType.name() - ) - ); - } - - if(CommonDefinition.isLibraryComponent(componentType)) { - hAutogenStr += String.format( - "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", - parentToken.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + if(isBuildUsedLibrary) { + hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", + parentToken.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } else { - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value.toString() - ); - hAutogenStr += String.format( - "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", - parentToken.cName - ); - cAutogenStr += String.format( - "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", + parentToken.cName); + cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } break; case FIXED_AT_BUILD: - // - // BUGBUG: The judegement of module PCD type and platform PCD type should not be - // done here, but in wizard tools, But here is just following something - // PcdEmulation driver. - // - if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.FIXED_AT_BUILD.ordinal()) { - throw new EntityException( - String.format( - "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n", - parentToken.cName, - parentToken.pcdType.name(), - modulePcdType.name() - ) - ); - } - - if(CommonDefinition.isLibraryComponent(componentType)) { - hAutogenStr += String.format( - "extern const %s _gPcd_FixedAtBuild_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + if(isBuildUsedLibrary) { + hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } else { - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value.toString() - ); - hAutogenStr += String.format( - "extern const %s _gPcd_FixedAtBuild_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - cAutogenStr += String.format( - "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } break; case PATCHABLE_IN_MODULE: - // - // BUGBUG: The judegement of module PCD type and platform PCD type should not be - // done here, but in wizard tools, But here is just following something - // PcdEmulation driver. - // - if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.PATCHABLE_IN_MODULE.ordinal()) { - throw new EntityException( - String.format( - "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n", - parentToken.cName, - parentToken.pcdType.name(), - modulePcdType.name() - ) - ); - } - - if(CommonDefinition.isLibraryComponent(componentType)) { - hAutogenStr += String.format( - "extern %s _gPcd_BinaryPatch_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + if(isBuildUsedLibrary) { + hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } else { - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value - ); - hAutogenStr += String.format( - "extern %s _gPcd_BinaryPatch_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - cAutogenStr += String.format( - "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } break; case DYNAMIC: - // - // BUGBUG: The judegement of module PCD type and platform PCD type should not be - // done here, but in wizard tools, But here is just following something - // PcdEmulation driver. - // - if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.DYNAMIC.ordinal()) { - throw new EntityException( - String.format( - "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n", - parentToken.cName, - parentToken.pcdType.name(), - modulePcdType.name() - ) - ); - } - switch(parentToken.pcdType) { case FEATURE_FLAG: - if(CommonDefinition.isLibraryComponent(componentType)) { - hAutogenStr += String.format( - "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + if(isBuildUsedLibrary) { + hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } else { - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value - ); - hAutogenStr += String.format( - "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", - parentToken.cName - ); - cAutogenStr += String.format( - "const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", + parentToken.cName); + cAutogenStr += String.format("const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } break; case FIXED_AT_BUILD: - if(CommonDefinition.isLibraryComponent(componentType)) { - hAutogenStr += String.format( - "extern const %s _gPcd_FixedAtBuild_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + if(isBuildUsedLibrary) { + hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } else { - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value - ); - hAutogenStr += String.format( - "extern const %s _gPcd_FixedAtBuild_%s\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName - ); - cAutogenStr += String.format( - "const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName); + cAutogenStr += String.format("const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); } break; case PATCHABLE_IN_MODULE: - hAutogenStr += String.format( - "#define _PCD_VALUE_%s %s\r\n", - parentToken.cName, - value - ); - hAutogenStr += String.format( - "extern %s _gPcd_BinaryPatch_%s;\r\n", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); - cAutogenStr += String.format( - "%s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;", - Token.getAutogendatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - parentToken.cName - ); + hAutogenStr += String.format("#define _PCD_VALUE_%s %s\r\n", + parentToken.cName, + datum.toString()); + hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); + cAutogenStr += String.format("%s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;", + Token.getAutogendatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); + hAutogenStr += String.format("#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + parentToken.cName); break; - case DYNAMIC: - hAutogenStr += "\r\n"; - hAutogenStr += String.format( - "#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n", - Token.GetAutogenDefinedatumTypeString(parentToken.datumType), - parentToken.cName, - Token.getAutogenLibrarydatumTypeString(parentToken.datumType), - parentToken.cName - ); + case DYNAMIC: + hAutogenStr += String.format("#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n", + Token.GetAutogenDefinedatumTypeString(parentToken.datumType), + parentToken.cName, + Token.getAutogenLibrarydatumTypeString(parentToken.datumType), + parentToken.cName); break; - default: - ActionMessage.log( - this, - "The PCD_TYPE setted by platform is unknown" - ); + default: + throw new EntityException ("The PCD type is unknown"); } break; case DYNAMIC_EX: diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java index 1e7ebfcbe1..070c2db5d7 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java @@ -26,6 +26,6 @@ public class EntityException extends Exception { @param expStr exception message string. **/ public EntityException(String expStr) { - super("[EntityException]:" + expStr); + super("[PCD EntityException]:" + expStr); } } diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java index 81eb63025b..661260d7bb 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java +++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java @@ -17,6 +17,7 @@ package org.tianocore.build.pcd.ui; import java.awt.*; import java.awt.event.*; +import java.util.Map; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; @@ -82,7 +83,7 @@ public class PCDDatabaseFrame extends JFrame { public JTree initializeTree() { Token[] tokenArray = null; Token token = null; - DefaultMutableTreeNode root = new DefaultMutableTreeNode(dbManager.getLogFileName()); + DefaultMutableTreeNode root = new DefaultMutableTreeNode("PCDTreeRoot"); DefaultMutableTreeNode rootByPCD = new DefaultMutableTreeNode("By PCD"); DefaultMutableTreeNode rootByModule = new DefaultMutableTreeNode("By Module"); DefaultMutableTreeNode tokenNode = null; @@ -92,6 +93,7 @@ public class PCDDatabaseFrame extends JFrame { int index = 0; int usageIndex = 0; int moduleIndex = 0; + Object[] objectArray = null; java.util.List usageArray = null; UsageInstance usageInstance = null; @@ -106,17 +108,14 @@ public class PCDDatabaseFrame extends JFrame { ActionMessage.debug(this, token.cName); tokenNode = new DefaultMutableTreeNode(token.cName); tokenNode.add(new DefaultMutableTreeNode(String.format("TOKEN NUMBER: 0x%08x", token.tokenNumber))); - tokenNode.add(new DefaultMutableTreeNode(String.format("ASSIGNED TOKEN NUMBER: 0x%08x", token.assignedtokenNumber))); tokenNode.add(new DefaultMutableTreeNode("TOKEN SPACE NAME: " + token.tokenSpaceName.toString())); - tokenNode.add(new DefaultMutableTreeNode("ASSIGNED TOKEN SPACE NAME: " + token.assignedtokenSpaceName.toString())); tokenNode.add(new DefaultMutableTreeNode("PCD TYPE: " + Token.getStringOfpcdType(token.pcdType))); tokenNode.add(new DefaultMutableTreeNode("DATUM TYPE: " +Token.getStringOfdatumType(token.datumType))); tokenNode.add(new DefaultMutableTreeNode("DATUM: " + token.datum.toString())); tokenNode.add(new DefaultMutableTreeNode("HIIENABLE: " +(token.hiiEnabled?"true":"false"))); tokenNode.add(new DefaultMutableTreeNode("VARIABLE NAME: " + token.variableName)); - tokenNode.add(new DefaultMutableTreeNode("VARIABLE GUID: " + token.variableGuid.toString())); + //tokenNode.add(new DefaultMutableTreeNode("VARIABLE GUID: " + token.variableGuid.toString())); tokenNode.add(new DefaultMutableTreeNode("SKUENABLE: " +(token.skuEnabled?"true":"false"))); - tokenNode.add(new DefaultMutableTreeNode("SKUDATA ARRAY ENABLE: " +(token.skuDataArrayEnabled?"true":"false"))); tokenNode.add(new DefaultMutableTreeNode(String.format("SKUID: %d", token.skuId))); tokenNode.add(new DefaultMutableTreeNode(String.format("MAX SKU COUNT: %d", token.maxSkuCount))); tokenNode.add(new DefaultMutableTreeNode("VPDENABLE: " +(token.vpdEnabled?"true":"false"))); @@ -124,22 +123,16 @@ public class PCDDatabaseFrame extends JFrame { usageNode = new DefaultMutableTreeNode("PRODUCER"); tokenNode.add(usageNode); - // - // Prepare producer's leaf node - // - - for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) { - usageNode.add(new DefaultMutableTreeNode(token.producers.get(usageIndex).moduleName)); - } // // Prepare consumer's leaf node // usageNode = new DefaultMutableTreeNode("CONSUMER"); tokenNode.add(usageNode); - + objectArray = token.consumers.entrySet().toArray(); for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) { - usageNode.add(new DefaultMutableTreeNode(token.consumers.get(usageIndex).moduleName)); + usageInstance = (UsageInstance) ((Map.Entry)objectArray[usageIndex]).getValue(); + usageNode.add(new DefaultMutableTreeNode(usageInstance.getPrimaryKey())); } rootByPCD.add(tokenNode); @@ -155,14 +148,11 @@ public class PCDDatabaseFrame extends JFrame { } for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) { moduleNode = new DefaultMutableTreeNode(moduleNames.get(moduleIndex)); - usageArray = dbManager.getUsageInstanceArrayByModuleName(moduleNames.get(moduleIndex)); + usageArray = dbManager.getUsageInstanceArrayByKeyString(moduleNames.get(moduleIndex)); for (usageIndex = 0; usageIndex < usageArray.size(); usageIndex ++) { usageInstance = usageArray.get(usageIndex); usageNode = new DefaultMutableTreeNode(usageInstance.parentToken.cName); usageNode.add(new DefaultMutableTreeNode("MODULE PCD TYPE: " + Token.getStringOfpcdType(usageInstance.modulePcdType))); - usageNode.add(new DefaultMutableTreeNode("HELP TEXT: " + usageInstance.helpTextInMSA)); - usageNode.add(new DefaultMutableTreeNode("IS INHERIT: " +(usageInstance.isInherit?"true":"false"))); - usageNode.add(new DefaultMutableTreeNode("USAGE: " + Token.getStringOfUsage(usageInstance.usage))); moduleNode.add(usageNode); } rootByModule.add(moduleNode); -- 2.39.2