]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/Misc.py
BaseTools: Fix the bug to display the single SKUID info
[mirror_edk2.git] / BaseTools / Source / Python / Common / Misc.py
index dbb711e96cefa02ea50d4f981c3d46beda31d0d1..1461d00669c20e54542f954d1bd336fe19a0a495 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Common routines used by all tools\r
 #\r
 ## @file\r
 # Common routines used by all tools\r
 #\r
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -36,7 +36,9 @@ from CommonDataClass.DataClass import *
 from Parsing import GetSplitValueList\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Parsing import GetSplitValueList\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
-\r
+import uuid\r
+from CommonDataClass.Exceptions import BadExpression\r
+import subprocess\r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
 \r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
 \r
@@ -67,8 +69,26 @@ def GetVariableOffset(mapfilepath, efifilepath, varnames):
     if (firstline.startswith("Archive member included ") and\r
         firstline.endswith(" file (symbol)")):\r
         return _parseForGCC(lines, efifilepath, varnames)\r
     if (firstline.startswith("Archive member included ") and\r
         firstline.endswith(" file (symbol)")):\r
         return _parseForGCC(lines, efifilepath, varnames)\r
+    if firstline.startswith("# Path:"):\r
+        return _parseForXcode(lines, efifilepath, varnames)\r
     return _parseGeneral(lines, efifilepath, varnames)\r
 \r
     return _parseGeneral(lines, efifilepath, varnames)\r
 \r
+def _parseForXcode(lines, efifilepath, varnames):\r
+    status = 0\r
+    ret = []\r
+    for index, line in enumerate(lines):\r
+        line = line.strip()\r
+        if status == 0 and line == "# Symbols:":\r
+            status = 1\r
+            continue\r
+        if status == 1 and len(line) != 0:\r
+            for varname in varnames:\r
+                if varname in line:\r
+                    m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname, line)\r
+                    if m != None:\r
+                        ret.append((varname, m.group(1)))\r
+    return ret\r
+\r
 def _parseForGCC(lines, efifilepath, varnames):\r
     """ Parse map file generated by GCC linker """\r
     status = 0\r
 def _parseForGCC(lines, efifilepath, varnames):\r
     """ Parse map file generated by GCC linker """\r
     status = 0\r
@@ -1453,6 +1473,149 @@ def AnalyzePcdExpression(Setting):
 \r
     return FieldList\r
 \r
 \r
     return FieldList\r
 \r
+def ParseDevPathValue (Value):\r
+    DevPathList = [ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl","BMC","AcpiPath","Acpi","PciRoot",\r
+                    "PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","AcpiAdr","Msg","Ata","Scsi",\r
+                    "Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","VenVt100","VenVt100Plus",\r
+                    "VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","DebugPort","MAC","IPv4","IPv6","Uart",\r
+                    "UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter","UsbMassStorage","UsbHub",\r
+                    "UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless","UsbDeviceFirmwareUpdate",\r
+                    "UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vlan","Uri","Bluetooth","Wi-Fi",\r
+                    "MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","RamDisk","VirtualDisk","VirtualCD",\r
+                    "PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ]\r
+    if '\\' in Value:\r
+        Value.replace('\\', '/').replace(' ', '')\r
+    for Item in Value.split('/'):\r
+        Key = Item.strip().split('(')[0]\r
+        if Key not in DevPathList:\r
+            pass\r
+\r
+    Cmd = 'DevicePath ' + '"' + Value + '"'\r
+    try:\r
+        p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+        out, err = p.communicate()\r
+    except Exception, X:\r
+        raise BadExpression("DevicePath: %s" % (str(X)) )\r
+    finally:\r
+        subprocess._cleanup()\r
+        p.stdout.close()\r
+        p.stderr.close()\r
+    if err:\r
+        raise BadExpression("DevicePath: %s" % str(err))\r
+    Size = len(out.split())\r
+    out = ','.join(out.split())\r
+    return '{' + out + '}', Size\r
+\r
+def ParseFieldValue (Value):\r
+    if type(Value) == type(0):\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if type(Value) <> type(''):\r
+        raise BadExpression('Type %s is %s' %(Value, type(Value)))\r
+    Value = Value.strip()\r
+    if Value.startswith('UINT8') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 1:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 1\r
+    if Value.startswith('UINT16') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 2:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 2\r
+    if Value.startswith('UINT32') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 4:\r
+            raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))\r
+        return Value, 4\r
+    if Value.startswith('UINT64') and Value.endswith(')'):\r
+        Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+        if Size > 8:\r
+            raise BadExpression('Value (%s) Size larger than %d' % (Value, Size))\r
+        return Value, 8\r
+    if Value.startswith('GUID') and Value.endswith(')'):\r
+        Value = Value.split('(', 1)[1][:-1].strip()\r
+        if Value[0] == '{' and Value[-1] == '}':\r
+            TmpValue = GuidStructureStringToGuidString(Value)\r
+            if len(TmpValue) == 0:\r
+                raise BadExpression("Invalid GUID value string %s" % Value)\r
+            Value = TmpValue\r
+        if Value[0] == '"' and Value[-1] == '"':\r
+            Value = Value[1:-1]\r
+        try:\r
+            Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"\r
+        except ValueError, Message:\r
+            raise BadExpression('%s' % Message)\r
+        Value, Size = ParseFieldValue(Value)\r
+        return Value, 16\r
+    if Value.startswith('L"') and Value.endswith('"'):\r
+        # Unicode String\r
+        List = list(Value[2:-1])\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 16) | ord(Char)\r
+        return Value, (len(List) + 1) * 2\r
+    if Value.startswith('"') and Value.endswith('"'):\r
+        # ASCII String\r
+        List = list(Value[1:-1])\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 8) | ord(Char)\r
+        return Value, len(List) + 1\r
+    if Value.startswith("L'") and Value.endswith("'"):\r
+        # Unicode Character Constant\r
+        List = list(Value[2:-1])\r
+        if len(List) == 0:\r
+            raise BadExpression('Length %s is %s' % (Value, len(List)))\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 16) | ord(Char)\r
+        return Value, len(List) * 2\r
+    if Value.startswith("'") and Value.endswith("'"):\r
+        # Character constant\r
+        List = list(Value[1:-1])\r
+        if len(List) == 0:\r
+            raise BadExpression('Length %s is %s' % (Value, len(List)))\r
+        List.reverse()\r
+        Value = 0\r
+        for Char in List:\r
+            Value = (Value << 8) | ord(Char)\r
+        return Value, len(List)\r
+    if Value.startswith('{') and Value.endswith('}'):\r
+        # Byte array\r
+        Value = Value[1:-1]\r
+        List = [Item.strip() for Item in Value.split(',')]\r
+        List.reverse()\r
+        Value = 0\r
+        RetSize = 0\r
+        for Item in List:\r
+            ItemValue, Size = ParseFieldValue(Item)\r
+            RetSize += Size\r
+            for I in range(Size):\r
+                Value = (Value << 8) | ((ItemValue >> 8 * I) & 0xff)\r
+        return Value, RetSize\r
+    if Value.startswith('DEVICE_PATH(') and Value.endswith(')'):\r
+        Value = Value.replace("DEVICE_PATH(", '').rstrip(')')\r
+        Value = Value.strip().strip('"')\r
+        return ParseDevPathValue(Value)\r
+    if Value.lower().startswith('0x'):\r
+        Value = int(Value, 16)\r
+        if Value == 0:\r
+            return 0, 1\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if Value[0].isdigit():\r
+        Value = int(Value, 10)\r
+        if Value == 0:\r
+            return 0, 1\r
+        return Value, (Value.bit_length() + 7) / 8\r
+    if Value.lower() == 'true':\r
+        return 1, 1\r
+    if Value.lower() == 'false':\r
+        return 0, 1\r
+    return Value, 1\r
+\r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
@@ -1486,19 +1649,25 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
         Value = FieldList[0]\r
         Size = ''\r
         if len(FieldList) > 1:\r
         Value = FieldList[0]\r
         Size = ''\r
         if len(FieldList) > 1:\r
-            Type = FieldList[1]\r
-            # Fix the PCD type when no DataType input\r
-            if Type == 'VOID*':\r
-                DataType = 'VOID*'\r
-            else:\r
+            if FieldList[1].upper().startswith("0X") or FieldList[1].isdigit():\r
                 Size = FieldList[1]\r
                 Size = FieldList[1]\r
+            else:\r
+                DataType = FieldList[1]\r
+\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
-        else:\r
+        if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
             IsValid = (len(FieldList) <= 1)\r
-        return [Value, '', Size], IsValid, 0\r
+        else:\r
+            IsValid = (len(FieldList) <= 3)\r
+#         Value, Size = ParseFieldValue(Value)\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
+        return [str(Value), '', str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
         Size = Type = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
         Size = Type = ''\r
@@ -1516,11 +1685,18 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
                     Size = str(len(Value.split(",")))\r
                 else:\r
                     Size = str(len(Value) -2 + 1 )\r
                     Size = str(len(Value.split(",")))\r
                 else:\r
                     Size = str(len(Value) -2 + 1 )\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
-        else:\r
+        if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
             IsValid = (len(FieldList) <= 1)\r
-        return [Value, Type, Size], IsValid, 0\r
+        else:\r
+            IsValid = (len(FieldList) <= 3)\r
+\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
+        return [Value, Type, str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
         Value = Size = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
         Value = Size = ''\r
@@ -1532,11 +1708,17 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
                 Size = FieldList[1]\r
             if len(FieldList) > 2:\r
                 Value = FieldList[2]\r
                 Size = FieldList[1]\r
             if len(FieldList) > 2:\r
                 Value = FieldList[2]\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
+        if DataType == "":\r
+            IsValid = (len(FieldList) <= 1)\r
         else:\r
         else:\r
-            IsValid = (len(FieldList) <= 2)\r
-        return [VpdOffset, Size, Value], IsValid, 2\r
+            IsValid = (len(FieldList) <= 3)\r
+        if Size:\r
+            try:\r
+                int(Size,16) if Size.upper().startswith("0X") else int(Size)\r
+            except:\r
+                IsValid = False\r
+                Size = -1\r
+        return [VpdOffset, str(Size), Value], IsValid, 2\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
         Guid = Offset = Value = Attribute = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
         Guid = Offset = Value = Attribute = ''\r
@@ -1635,10 +1817,10 @@ def CheckPcdDatum(Type, Value):
     if Type == "VOID*":\r
         ValueRe = re.compile(r'\s*L?\".*\"\s*$')\r
         if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"'))\r
     if Type == "VOID*":\r
         ValueRe = re.compile(r'\s*L?\".*\"\s*$')\r
         if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"'))\r
-                or (Value.startswith('{') and Value.endswith('}'))\r
+                or (Value.startswith('{') and Value.endswith('}')) or (Value.startswith("L'") or Value.startswith("'") and Value.endswith("'"))\r
                ):\r
             return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\\r
                ):\r
             return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\\r
-                          ", or \"...\" for string, or L\"...\" for unicode string" % (Value, Type)\r
+                          ", \"...\" or \'...\' for string, L\"...\" or L\'...\' for unicode string" % (Value, Type)\r
         elif ValueRe.match(Value):\r
             # Check the chars in UnicodeString or CString is printable\r
             if Value.startswith("L"):\r
         elif ValueRe.match(Value):\r
             # Check the chars in UnicodeString or CString is printable\r
             if Value.startswith("L"):\r
@@ -1664,7 +1846,7 @@ def CheckPcdDatum(Type, Value):
             return False, "Invalid value [%s] of type [%s];"\\r
                           " must be a hexadecimal, decimal or octal in C language format." % (Value, Type)\r
     else:\r
             return False, "Invalid value [%s] of type [%s];"\\r
                           " must be a hexadecimal, decimal or octal in C language format." % (Value, Type)\r
     else:\r
-        return False, "Invalid type [%s]; must be one of VOID*, BOOLEAN, UINT8, UINT16, UINT32, UINT64." % (Type)\r
+        return True, "StructurePcd"\r
 \r
     return True, ""\r
 \r
 \r
     return True, ""\r
 \r
@@ -1979,61 +2161,167 @@ class PeImageClass():
             Value = (Value << 8) | int(ByteList[index])\r
         return Value\r
 \r
             Value = (Value << 8) | int(ByteList[index])\r
         return Value\r
 \r
+class DefaultStore():\r
+    def __init__(self,DefaultStores ):\r
 \r
 \r
+        self.DefaultStores = DefaultStores\r
+    def DefaultStoreID(self,DefaultStoreName):\r
+        for key,value in self.DefaultStores.items():\r
+            if value == DefaultStoreName:\r
+                return key\r
+        return None\r
+    def GetDefaultDefault(self):\r
+        if not self.DefaultStores or "0" in self.DefaultStores:\r
+            return "0",TAB_DEFAULT_STORES_DEFAULT\r
+        else:\r
+            minvalue = min([int(value_str) for value_str in self.DefaultStores.keys()])\r
+            return (str(minvalue), self.DefaultStores[str(minvalue)])\r
+    def GetMin(self,DefaultSIdList):\r
+        if not DefaultSIdList:\r
+            return "STANDARD"\r
+        storeidset = {storeid for storeid, storename in self.DefaultStores.values() if storename in DefaultSIdList}\r
+        if not storeidset:\r
+            return ""\r
+        minid = min(storeidset )\r
+        for sid,name in self.DefaultStores.values():\r
+            if sid == minid:\r
+                return name\r
 class SkuClass():\r
     \r
     DEFAULT = 0\r
     SINGLE = 1\r
     MULTIPLE =2\r
     \r
 class SkuClass():\r
     \r
     DEFAULT = 0\r
     SINGLE = 1\r
     MULTIPLE =2\r
     \r
-    def __init__(self,SkuIdentifier='', SkuIds={}):\r
+    def __init__(self,SkuIdentifier='', SkuIds=None):\r
+        if SkuIds is None:\r
+            SkuIds = {}\r
+\r
+        for SkuName in SkuIds:\r
+            SkuId = SkuIds[SkuName][0]\r
+            skuid_num = int(SkuId,16) if SkuId.upper().startswith("0X") else int(SkuId)\r
+            if skuid_num > 0xFFFFFFFFFFFFFFFF:\r
+                EdkLogger.error("build", PARAMETER_INVALID,\r
+                            ExtraData = "SKU-ID [%s] value %s exceeds the max value of UINT64"\r
+                                      % (SkuName, SkuId))\r
         \r
         self.AvailableSkuIds = sdict()\r
         self.SkuIdSet = []\r
         self.SkuIdNumberSet = []\r
         \r
         self.AvailableSkuIds = sdict()\r
         self.SkuIdSet = []\r
         self.SkuIdNumberSet = []\r
+        self.SkuData = SkuIds\r
+        self.__SkuInherit = {}\r
+        self.__SkuIdentifier = SkuIdentifier\r
         if SkuIdentifier == '' or SkuIdentifier is None:\r
             self.SkuIdSet = ['DEFAULT']\r
             self.SkuIdNumberSet = ['0U']\r
         elif SkuIdentifier == 'ALL':\r
             self.SkuIdSet = SkuIds.keys()\r
         if SkuIdentifier == '' or SkuIdentifier is None:\r
             self.SkuIdSet = ['DEFAULT']\r
             self.SkuIdNumberSet = ['0U']\r
         elif SkuIdentifier == 'ALL':\r
             self.SkuIdSet = SkuIds.keys()\r
-            self.SkuIdNumberSet = [num.strip() + 'U' for num in SkuIds.values()]\r
+            self.SkuIdNumberSet = [num[0].strip() + 'U' for num in SkuIds.values()]\r
         else:\r
             r = SkuIdentifier.split('|') \r
         else:\r
             r = SkuIdentifier.split('|') \r
-            self.SkuIdSet=[r[k].strip() for k in range(len(r))]      \r
+            self.SkuIdSet=[(r[k].strip()).upper() for k in range(len(r))]\r
             k = None\r
             try: \r
             k = None\r
             try: \r
-                self.SkuIdNumberSet = [SkuIds[k].strip() + 'U' for k in self.SkuIdSet]   \r
+                self.SkuIdNumberSet = [SkuIds[k][0].strip() + 'U' for k in self.SkuIdSet]\r
             except Exception:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData = "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (k, " | ".join(SkuIds.keys())))\r
             except Exception:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData = "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (k, " | ".join(SkuIds.keys())))\r
-        if len(self.SkuIdSet) == 2 and 'DEFAULT' in self.SkuIdSet and SkuIdentifier != 'ALL':\r
-            self.SkuIdSet.remove('DEFAULT')\r
-            self.SkuIdNumberSet.remove('0U')\r
         for each in self.SkuIdSet:\r
             if each in SkuIds:\r
         for each in self.SkuIdSet:\r
             if each in SkuIds:\r
-                self.AvailableSkuIds[each] = SkuIds[each]\r
+                self.AvailableSkuIds[each] = SkuIds[each][0]\r
             else:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (each, " | ".join(SkuIds.keys())))\r
             else:\r
                 EdkLogger.error("build", PARAMETER_INVALID,\r
                             ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"\r
                                       % (each, " | ".join(SkuIds.keys())))\r
+        if self.SkuUsageType != self.SINGLE:\r
+            self.AvailableSkuIds.update({'DEFAULT':0, 'COMMON':0})\r
+        if self.SkuIdSet:\r
+            GlobalData.gSkuids = (self.SkuIdSet)\r
+            if 'COMMON' in GlobalData.gSkuids:\r
+                GlobalData.gSkuids.remove('COMMON')\r
+            if self.SkuUsageType == self.SINGLE:\r
+                if len(GlobalData.gSkuids) != 1:\r
+                    if 'DEFAULT' in GlobalData.gSkuids:\r
+                        GlobalData.gSkuids.remove('DEFAULT')\r
+            if GlobalData.gSkuids:\r
+                GlobalData.gSkuids.sort()\r
+\r
+    def GetNextSkuId(self, skuname):\r
+        if not self.__SkuInherit:\r
+            self.__SkuInherit = {}\r
+            for item in self.SkuData.values():\r
+                self.__SkuInherit[item[1]]=item[2] if item[2] else "DEFAULT"\r
+        return self.__SkuInherit.get(skuname,"DEFAULT")\r
+\r
+    def GetSkuChain(self,sku):\r
+        if sku == "DEFAULT":\r
+            return ["DEFAULT"]\r
+        skulist = [sku]\r
+        nextsku = sku\r
+        while 1:\r
+            nextsku = self.GetNextSkuId(nextsku)\r
+            skulist.append(nextsku)\r
+            if nextsku == "DEFAULT":\r
+                break\r
+        skulist.reverse()\r
+        return skulist\r
+    def SkuOverrideOrder(self):\r
+        skuorderset = []\r
+        for skuname in self.SkuIdSet:\r
+            skuorderset.append(self.GetSkuChain(skuname))\r
         \r
         \r
+        skuorder = []\r
+        for index in range(max([len(item) for item in skuorderset])):\r
+            for subset in skuorderset:\r
+                if index > len(subset)-1:\r
+                    continue\r
+                if subset[index] in skuorder:\r
+                    continue\r
+                skuorder.append(subset[index])\r
+\r
+        return skuorder\r
+\r
     def __SkuUsageType(self): \r
         \r
     def __SkuUsageType(self): \r
         \r
+        if self.__SkuIdentifier.upper() == "ALL":\r
+            return SkuClass.MULTIPLE\r
+\r
         if len(self.SkuIdSet) == 1:\r
             if self.SkuIdSet[0] == 'DEFAULT':\r
                 return SkuClass.DEFAULT\r
             else:\r
                 return SkuClass.SINGLE\r
         if len(self.SkuIdSet) == 1:\r
             if self.SkuIdSet[0] == 'DEFAULT':\r
                 return SkuClass.DEFAULT\r
             else:\r
                 return SkuClass.SINGLE\r
+        elif len(self.SkuIdSet) == 2:\r
+            if 'DEFAULT' in self.SkuIdSet:\r
+                return SkuClass.SINGLE\r
+            else:\r
+                return SkuClass.MULTIPLE\r
         else:\r
             return SkuClass.MULTIPLE\r
         else:\r
             return SkuClass.MULTIPLE\r
+    def DumpSkuIdArrary(self):\r
 \r
 \r
+        ArrayStrList = []\r
+        if self.SkuUsageType == SkuClass.SINGLE:\r
+            ArrayStr = "{0x0}"\r
+        else:\r
+            for skuname in self.AvailableSkuIds:\r
+                if skuname == "COMMON":\r
+                    continue\r
+                while skuname != "DEFAULT":\r
+                    ArrayStrList.append(hex(int(self.AvailableSkuIds[skuname])))\r
+                    skuname = self.GetNextSkuId(skuname)\r
+                ArrayStrList.append("0x0")\r
+            ArrayStr = "{" + ",".join(ArrayStrList) +  "}"\r
+        return ArrayStr\r
     def __GetAvailableSkuIds(self):\r
         return self.AvailableSkuIds\r
     \r
     def __GetSystemSkuID(self):\r
         if self.__SkuUsageType() == SkuClass.SINGLE:\r
     def __GetAvailableSkuIds(self):\r
         return self.AvailableSkuIds\r
     \r
     def __GetSystemSkuID(self):\r
         if self.__SkuUsageType() == SkuClass.SINGLE:\r
-            return self.SkuIdSet[0]\r
+            if len(self.SkuIdSet) == 1:\r
+                return self.SkuIdSet[0]\r
+            else:\r
+                return self.SkuIdSet[0] if self.SkuIdSet[0] != 'DEFAULT' else self.SkuIdSet[1]\r
         else:\r
             return 'DEFAULT'\r
     def __GetAvailableSkuIdNumber(self):\r
         else:\r
             return 'DEFAULT'\r
     def __GetAvailableSkuIdNumber(self):\r
@@ -2063,11 +2351,11 @@ def PackRegistryFormatGuid(Guid):
                 )\r
 \r
 def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
                 )\r
 \r
 def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
-    if PcdDatumType == 'VOID*':\r
-        if Value.startswith('L'):\r
+    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:\r
+        if Value.startswith('L') or Value.startswith('"'):\r
             if not Value[1]:\r
                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
             if not Value[1]:\r
                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
-            Value = Value[0] + '"' + Value[1:] + '"'\r
+            Value = Value\r
         elif Value.startswith('H'):\r
             if not Value[1]:\r
                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
         elif Value.startswith('H'):\r
             if not Value[1]:\r
                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')\r
@@ -2087,6 +2375,29 @@ def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Val
         elif Value == 'FALSE' or Value == '0':\r
             Value = '0'\r
     return  Value\r
         elif Value == 'FALSE' or Value == '0':\r
             Value = '0'\r
     return  Value\r
+##  Get the integer value from string like "14U" or integer like 2\r
+#\r
+#   @param      Input   The object that may be either a integer value or a string\r
+#\r
+#   @retval     Value    The integer value that the input represents\r
+#\r
+def GetIntegerValue(Input):\r
+    if type(Input) in (int, long):\r
+        return Input\r
+    String = Input\r
+    if String.endswith("U"):\r
+        String = String[:-1]\r
+    if String.endswith("ULL"):\r
+        String = String[:-3]\r
+    if String.endswith("LL"):\r
+        String = String[:-2]\r
+\r
+    if String.startswith("0x") or String.startswith("0X"):\r
+        return int(String, 16)\r
+    elif String == '':\r
+        return 0\r
+    else:\r
+        return int(String)\r
 \r
 ##\r
 #\r
 \r
 ##\r
 #\r