]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
Add many datum and datum size checking in PCD building tools, These checking work...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / entity / Token.java
index 5931b8bceb5d15f09f091cef1178cc076241c3a6..f5765e1d408fa1e9b7ef2ffc8452235bed26f34d 100644 (file)
@@ -15,11 +15,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/  \r
 package org.tianocore.build.pcd.entity;\r
 \r
+import java.math.BigInteger;\r
 import java.util.ArrayList;\r
+import java.util.HashMap;\r
 import java.util.List;\r
+import java.util.Map;\r
 import java.util.UUID;\r
 \r
 import org.tianocore.build.pcd.action.ActionMessage;\r
+import org.tianocore.build.pcd.exception.EntityException;\r
 \r
 /** This class is to descript a PCD token object. The information of a token mainly \r
     comes from MSA, SPD and setting produced by platform developer. \r
@@ -67,28 +71,16 @@ public class Token {
     public int              tokenNumber;\r
 \r
     ///\r
-    /// The token space name assigned by platform. For Non-DynamicEx driver this value is same.\r
-    /// assignedtokenSpaceName is defined in FPD.\r
-    ///\r
-    public UUID             assignedtokenSpaceName;\r
-\r
-    ///\r
-    /// The token number assigned by platform. The number indiect the offset of this token in platform\r
-    /// token space.\r
-    /// AssgiendtokenNumber is defined in FPD.\r
-    ///\r
-    public int              assignedtokenNumber;\r
-\r
-    ///\r
-    /// pcdType is the PCD item type defined by platform developer.\r
-    ///\r
-    public PCD_TYPE         pcdType;\r
+    /// All supported PCD type, this value can be retrieved from SPD\r
+    /// Currently, only record all PCD type for this token in FPD file.\r
+    /// \r
+    public List<PCD_TYPE>   supportedPcdType;\r
 \r
     ///\r
-    /// PCDtype is set by platform developer. It is final PCD type of this token.\r
-    /// SupportedPcdType is defined in SPD.\r
-    ///\r
-    public PCD_TYPE[]       supportedpcdType;\r
+    /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD\r
+    /// is true.\r
+    /// \r
+    public boolean          isDynamicPCD;\r
 \r
     ///\r
     /// datumSize is to descript the fix size or max size for this token. \r
@@ -98,144 +90,73 @@ public class Token {
 \r
     ///\r
     /// datum type is to descript what type can be expressed by a PCD token.\r
-    /// datumType is defined in SPD.\r
+    /// For same PCD used in different module, the datum type should be unique.\r
+    /// So it belong memeber to Token class.\r
     ///\r
     public DATUM_TYPE       datumType;\r
 \r
-    ///\r
-    /// Isplatform is to descript whether this token is defined in platform level.\r
-    /// If token is belong to platform level. The value can be different for every\r
-    /// module. All are determined by platform developer.\r
-    ///\r
-    public boolean          isPlatform;\r
-\r
-    ///\r
-    /// hiiEnabled is to indicate whether the token support Hii functionality.\r
-    /// hiiEnabled is defined in FPD.\r
-    ///\r
-    public boolean          hiiEnabled;\r
-\r
-    ///\r
-    /// variableName is valid only when this token support Hii functionality. variableName\r
-    /// indicates the value of token is associated with what variable.\r
-    /// variableName is defined in FPD.\r
-    ///\r
-    public String           variableName;\r
-\r
-    ///\r
-    /// variableGuid is the GUID this token associated with.\r
-    /// variableGuid is defined in FPD.\r
-    ///\r
-    public UUID             variableGuid;\r
-\r
-    ///\r
-    /// Variable offset indicate the associated variable's offset in NV storage.\r
-    /// variableOffset is defined in FPD.\r
-    ///\r
-    public int              variableOffset;\r
-\r
-    ///\r
-    /// skuEnabled is to indicate whether the token support Sku functionality.\r
-    /// skuEnabled is defined in FPD.\r
-    ///\r
-    public boolean          skuEnabled;\r
-\r
-    ///\r
-    /// skuDataArrayEnabled is to indicate wheter use the skuData array or default value.\r
-    ///\r
-    public boolean          skuDataArrayEnabled;\r
-\r
     ///\r
     /// skuData contains all value for SkuNumber of token.\r
-    /// skuData is defined in FPD.\r
+    /// This field is for Dynamic or DynamicEx type PCD, \r
     ///\r
     public List<SkuInstance> skuData;\r
 \r
-    ///\r
-    /// maxSkuCount indicate the max count of sku data.\r
-    /// maxSkuCount is defined in FPD.\r
-    ///\r
-    public int              maxSkuCount;\r
-\r
-    ///\r
-    /// SkuId is the id of current selected SKU.\r
-    /// SkuId is defined in FPD.\r
-    ///\r
-    public int              skuId;\r
-\r
-    ///\r
-    /// datum is the value set by platform developer.\r
-    /// datum is defined in FPD.\r
-    ///\r
-    public Object           datum;\r
-\r
-    ///\r
-    /// Default value of this token.\r
-    /// This default value is defined in SPD level.\r
-    ///\r
-    public Object           defaultValue;\r
-\r
-    ///\r
-    /// BUGBUG: fix comment\r
-    /// vpdEnabled is defined in FPD.\r
-    ///\r
-    public boolean          vpdEnabled;\r
-\r
-    ///\r
-    /// BUGBUG: fix comment\r
-    /// vpdOffset is defined in FPD.\r
-    ///\r
-    public long             vpdOffset;\r
-\r
-    ///\r
-    /// producers array record all module private information who produce this PCD token.\r
-    ///\r
-    public List<UsageInstance>  producers;\r
-\r
     ///\r
     /// consumers array record all module private information who consume this PCD token.\r
     ///\r
-    public List<UsageInstance>  consumers;\r
+    public Map<String, UsageInstance>  consumers;\r
 \r
-    /**\r
-      Constructure function.\r
-     \r
-      Initialize the value of token.\r
-     \r
-      @param cName                   The cName of this token\r
-      @param tokenSpaceName          The tokenSpaceName of this token, it is a GUID.\r
-      @param assignedtokenSpaceName  The assignedtokenSpaceName of this token, it is a GUID.\r
-      \r
-    **/ \r
-    public Token(String cName, UUID tokenSpaceName, UUID assignedtokenSpaceName) {\r
+    public Token(String cName, UUID tokenSpaceName) {\r
         UUID    nullUUID = new UUID(0, 0);\r
 \r
         this.cName                  = cName;\r
-        this.tokenSpaceName         =(tokenSpaceName == null) ? nullUUID : tokenSpaceName;\r
-        this.assignedtokenSpaceName =(assignedtokenSpaceName == null) ? nullUUID : assignedtokenSpaceName;\r
+        this.tokenSpaceName         = (tokenSpaceName == null) ? nullUUID : tokenSpaceName;\r
         this.tokenNumber            = 0;\r
-        this.assignedtokenNumber    = 0;\r
-        this.pcdType                = PCD_TYPE.UNKNOWN;\r
-        this.supportedpcdType       = null;\r
-        this.isPlatform             = false;\r
         this.datumType              = DATUM_TYPE.UNKNOWN;\r
         this.datumSize              = -1;\r
-        this.defaultValue           = null;\r
-        this.datum                  = null;\r
-        this.hiiEnabled             = false;\r
-        this.variableGuid           = null;\r
-        this.variableName           = "";\r
-        this.variableOffset         = -1;\r
-        this.skuEnabled             = false;\r
-        this.skuDataArrayEnabled    = false;\r
-        this.skuId                  = -1;\r
-        this.maxSkuCount            = -1;\r
         this.skuData                = new ArrayList<SkuInstance>();\r
-        this.vpdEnabled             = false;\r
-        this.vpdOffset              = -1;\r
 \r
-        this.producers              = new ArrayList<UsageInstance>();\r
-        this.consumers              = new ArrayList<UsageInstance>();\r
+        this.consumers              = new HashMap<String, UsageInstance>();\r
+        this.supportedPcdType       = new ArrayList<PCD_TYPE>();\r
+    }\r
+\r
+    /**\r
+      updateSupportPcdType\r
+      \r
+      SupportPcdType should be gotten from SPD file actually, but now it just\r
+      record all PCD type for this token in FPD file.\r
+      \r
+      @param pcdType    new PCD type found in FPD file for this token.\r
+    **/\r
+    public void updateSupportPcdType(PCD_TYPE pcdType) {\r
+        int     index = 0;\r
+        boolean found = false;\r
+        for (index = 0; index < this.supportedPcdType.size(); index ++) {\r
+            if (this.supportedPcdType.get(index) == pcdType) {\r
+                found = true;\r
+                break;\r
+            }\r
+        }\r
+        if (!found) {\r
+            this.supportedPcdType.add(pcdType);\r
+        }\r
+    }\r
+\r
+    /**\r
+       Judge whether pcdType is belong to dynamic type. Dynamic type includes\r
+       DYNAMIC and DYNAMIC_EX.\r
+       \r
+       @param pcdType\r
+       \r
+       @return boolean\r
+     */\r
+    public static boolean isDynamic(PCD_TYPE pcdType) {\r
+        if ((pcdType == PCD_TYPE.DYNAMIC   ) ||\r
+            (pcdType == PCD_TYPE.DYNAMIC_EX)) {\r
+            return true;\r
+        }\r
+\r
+        return false;\r
     }\r
 \r
     /**\r
@@ -247,19 +168,35 @@ public class Token {
       \r
       @return  primary key for this token in token database.\r
     **/\r
-    public static String getPrimaryKeyString(String cName, UUID tokenSpaceName, \r
-                                             UUID platformtokenSpaceName) {\r
+    public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) {\r
         UUID  nullUUID = new UUID(0, 0);\r
 \r
-        if (platformtokenSpaceName == nullUUID) {\r
-            return cName + "_" + tokenSpaceName.toString().replace('-', '_');\r
+        if (tokenSpaceName == null) {\r
+            return cName + "_" + nullUUID.toString().replace('-', '_');\r
         } else {\r
-            return cName + "_" + platformtokenSpaceName.toString().replace('-', '_');\r
+            return cName + "_" + tokenSpaceName.toString().replace('-', '_');\r
+        }\r
+    }\r
+\r
+    /**\r
+       If skudata list contains more than one data, then Sku mechanism is enable.\r
+       \r
+       @return boolean\r
+     */\r
+    public boolean isSkuEnable() {\r
+        if (this.skuData.size() > 1) {\r
+            return true;\r
         }\r
+        return false;\r
     }\r
 \r
+    /**\r
+       Get the token primary key in token database.\r
+       \r
+       @return String\r
+     */\r
     public String getPrimaryKeyString () {\r
-        return cName + "_" + tokenSpaceName.toString().replace('-', '_');\r
+        return Token.getPrimaryKeyString(cName, tokenSpaceName);\r
     }\r
 \r
     /**\r
@@ -302,99 +239,52 @@ public class Token {
       @retval TRUE  - Success to add usage instance.\r
       @retval FALSE - Fail to add usage instance\r
     **/\r
-    public boolean addUsageInstance(UsageInstance usageInstance) {\r
-        if (usageInstance.usage == PCD_USAGE.UNKNOWN) {\r
-            return false;\r
+    public boolean addUsageInstance(UsageInstance usageInstance) \r
+        throws EntityException {\r
+        String exceptionStr;\r
+\r
+        if (isUsageInstanceExist(usageInstance.moduleName,\r
+                                 usageInstance.moduleGUID,\r
+                                 usageInstance.packageName,\r
+                                 usageInstance.packageGUID,\r
+                                 usageInstance.arch,\r
+                                 usageInstance.version)) {\r
+            exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+\r
+                                         "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",\r
+                                         usageInstance.parentToken.cName,\r
+                                         usageInstance.moduleName);\r
+            throw new EntityException(exceptionStr);\r
         }\r
 \r
-        if ((usageInstance.usage == PCD_USAGE.ALWAYS_PRODUCED) ||\r
-            (usageInstance.usage == PCD_USAGE.SOMETIMES_PRODUCED)) {\r
-            producers.add(usageInstance);\r
-        } else {\r
-            consumers.add(usageInstance);\r
-        }\r
+        consumers.put(usageInstance.getPrimaryKey(), usageInstance);\r
         return true;\r
     }\r
 \r
     /**\r
-      Judge whether exist an usage instance for this token\r
-      \r
-      @param moduleName   Use xmlFilePath as keyword to search the usage instance\r
-      \r
-      @retval PCD_USAGE - if UsageInstance exists.\r
-      @retval UNKNOWN   - if UsageInstance does not exist, return UNKONW.\r
-    **/\r
-    public PCD_USAGE isUsageInstanceExist(String moduleName) {\r
-        int           index;\r
-        UsageInstance usageInstance;\r
-\r
-        if (moduleName == null) {\r
-            ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!");\r
-            return PCD_USAGE.UNKNOWN;\r
-        }\r
-\r
-        if (moduleName.length() == 0) {\r
-            return PCD_USAGE.UNKNOWN;\r
-        }\r
-\r
-        //\r
-        // Searching the usage instance in module's producer and consumer according to \r
-        // module's name.\r
-        //\r
-        for (index = 0; index < producers.size(); index ++) {\r
-            usageInstance =(UsageInstance)producers.get(index);\r
-            if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {\r
-                return usageInstance.usage;\r
-            }\r
-        }\r
-\r
-        for (index = 0; index < consumers.size(); index ++) {\r
-            usageInstance =(UsageInstance)consumers.get(index);\r
-            if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {\r
-                return usageInstance.usage;\r
-            }\r
-        }\r
-        return PCD_USAGE.UNKNOWN;\r
-    }\r
-\r
-    /**\r
-      Get usage instance according to a MSA file name\r
-      \r
-      @param moduleName   The file path string of MSA file.\r
-\r
-      @return usage instance object.\r
-    **/\r
-    public UsageInstance getUsageInstance(String moduleName) {\r
-        int           usageIndex;\r
-        UsageInstance usageInstance;\r
-\r
-        if (moduleName == null) {\r
-            ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!");\r
-            return null;\r
-        }\r
-\r
-        if (moduleName.length() == 0) {\r
-            return null;\r
-        }\r
-\r
-        if (producers.size() != 0) {\r
-            for (usageIndex = 0; usageIndex < producers.size(); usageIndex ++) {\r
-                usageInstance =(UsageInstance)producers.get(usageIndex);\r
-                if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {\r
-                    return usageInstance;\r
-                }\r
-            }\r
-        }\r
-\r
-        if (consumers.size() != 0) {\r
-            for (usageIndex = 0; usageIndex < consumers.size(); usageIndex ++) {\r
-                usageInstance =(UsageInstance)consumers.get(usageIndex);\r
-                if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {\r
-                    return usageInstance;\r
-                }\r
-            }\r
-        }\r
-        return null;\r
+       Judge whether exist an usage instance for this token\r
+       \r
+       @param moduleName    the name of module\r
+       @param moduleGuid    the GUID name of modules\r
+       @param packageName   the name of package contains this module\r
+       @param packageGuid   the GUID name of package contains this module\r
+       @param arch          the architecture string\r
+       @param version       the version string\r
+       \r
+       @return boolean      whether exist an usage instance for this token.\r
+     */\r
+    public boolean isUsageInstanceExist(String moduleName,\r
+                                        UUID   moduleGuid,\r
+                                        String packageName,\r
+                                        UUID   packageGuid,\r
+                                        String arch,\r
+                                        String version) {\r
+        String keyStr = UsageInstance.getPrimaryKey(moduleName, \r
+                                                    moduleGuid, \r
+                                                    packageName, \r
+                                                    packageGuid, \r
+                                                    arch, \r
+                                                    version);\r
+        return (consumers.get(keyStr) != null);\r
     }\r
 \r
     /**\r
@@ -639,33 +529,100 @@ public class Token {
         return uuid;\r
     }\r
 \r
+    public DynamicTokenValue getDefaultSku() {\r
+        DynamicTokenValue dynamicData;\r
+        int               index;\r
+        for (index = 0; index < this.skuData.size(); index ++) {\r
+            if (skuData.get(index).id == 0) {\r
+                return skuData.get(index).value;\r
+            }\r
+        }\r
+\r
+        return null;\r
+    }\r
     //\r
     // BugBug: We need change this algorithm accordingly when schema is updated\r
     //          to support no default value.\r
     //\r
     public boolean hasDefaultValue () {\r
-\r
-        if (hiiEnabled) {\r
-            return true;\r
+        int               value         = 0;\r
+        boolean           isInteger     = true;\r
+        DynamicTokenValue dynamicValue  = null;\r
+\r
+        if (this.isDynamicPCD) {\r
+            dynamicValue = getDefaultSku();\r
+            switch (dynamicValue.type) {\r
+            case HII_TYPE:\r
+                return !isValidNullValue(dynamicValue.hiiDefaultValue);\r
+            case VPD_TYPE:\r
+                return false;\r
+            case DEFAULT_TYPE:\r
+                return !isValidNullValue(dynamicValue.value);\r
+            }\r
         }\r
 \r
-        if (vpdEnabled) {\r
-            return true;\r
-        }\r
+        return false;\r
+    }\r
 \r
-        if (datum.toString().compareTo("NoDefault") == 0) {\r
-            return false;\r
-        }\r
+    public boolean isValidNullValue(String judgedValue) {\r
+        int         intValue;\r
+        BigInteger  bigIntValue;\r
 \r
-        return true;\r
+        switch (datumType) {\r
+        case UINT8:\r
+        case UINT16:\r
+        case UINT32:\r
+            intValue = Integer.decode(judgedValue);\r
+            if (intValue == 0) {\r
+                return true;\r
+            }\r
+            break;\r
+        case UINT64:\r
+            if (judgedValue.length() > 2){\r
+                if ((judgedValue.charAt(0) == '0') && \r
+                    ((judgedValue.charAt(1) == 'x') ||\r
+                     (judgedValue.charAt(1) == 'X'))) {\r
+                    bigIntValue = new BigInteger(judgedValue.substring(2, judgedValue.length()),  16);\r
+                    if (bigIntValue.bitCount() == 0) {\r
+                        return true;\r
+                    }\r
+                } else {\r
+                    bigIntValue = new BigInteger(judgedValue);\r
+                    if (bigIntValue.bitCount() == 0) {\r
+                        return true;\r
+                    }\r
+                }\r
+            } else  {\r
+                bigIntValue = new BigInteger(judgedValue);\r
+                if (bigIntValue.bitCount() == 0) {\r
+                    return true;\r
+                }\r
+            }\r
+            break;\r
+        case BOOLEAN:\r
+            if (judgedValue.equalsIgnoreCase("false")) {\r
+                return true;\r
+            }\r
+            break;\r
+        case POINTER:\r
+            if (judgedValue.equalsIgnoreCase("")        ||\r
+                judgedValue.equalsIgnoreCase("\"\"")   ||\r
+                judgedValue.equalsIgnoreCase("L\"\"")   ||\r
+                (judgedValue.length() == 0)             ||\r
+                judgedValue.equalsIgnoreCase("{}")) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
     }\r
 \r
     public boolean isStringType () {\r
-        String str = datum.toString();\r
+        String str = getDefaultSku().value;\r
 \r
-        if (datumType == Token.DATUM_TYPE.POINTER &&\r
-            str.startsWith("L\"") && \r
-            str.endsWith("\"")) {\r
+        //\r
+        // BUGBUG: need scott confirmation.\r
+        // \r
+        if (datumType == Token.DATUM_TYPE.POINTER) {\r
             return true;\r
         }\r
 \r
@@ -673,7 +630,7 @@ public class Token {
     }\r
 \r
     public String getStringTypeString () {                       \r
-        return datum.toString().substring(2, datum.toString().length() - 1);\r
+        return getDefaultSku().value.substring(2, getDefaultSku().value.length() - 1);\r
     }\r
 }\r
 \r