From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.120; helo=mga04.intel.com; envelope-from=bob.c.feng@intel.com; receiver=edk2-devel@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D73B82097F579 for ; Wed, 7 Nov 2018 01:18:50 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Nov 2018 01:18:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,475,1534834800"; d="scan'208";a="98299139" Received: from shwdepsi1121.ccr.corp.intel.com ([10.239.158.47]) by orsmga003.jf.intel.com with ESMTP; 07 Nov 2018 01:18:47 -0800 From: BobCF To: edk2-devel@lists.01.org Cc: "bob.c.feng@intel.com" , Liming Gao Date: Wed, 7 Nov 2018 17:18:34 +0800 Message-Id: <20181107091834.21004-1-bob.c.feng@intel.com> X-Mailer: git-send-email 2.19.1.windows.1 MIME-Version: 1.0 Subject: [PATCH] BaseTools: Enable Pcd Array support. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Nov 2018 09:18:51 -0000 Content-Transfer-Encoding: 8bit From: "bob.c.feng@intel.com" https://bugzilla.tianocore.org/show_bug.cgi?id=1292 This patch is going to enable Array data type for PCD. 1. Support Pcd ARRAY as Structure PCD type including basic datatype array and structure array. For example: gStructuredPcdPkgTokenSpaceGuid.PcdTest|{0x0}|TEST[10]|0x00010080 gStructuredPcdPkgTokenSpaceGuid.PcdTest2|{0x0}|UINT8[10]|0x00010081 2. Support C CODE style value initialization in DEC/DSC. For example: gStructuredPcdPkgTokenSpaceGuid.PcdTest|{CODE({ {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, {0, {0, 0, 0, 0, 0, 0, 0}}, })} Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Bob Feng Cc: Liming Gao --- BaseTools/Source/Python/Common/Expression.py | 396 +++++++++--------- BaseTools/Source/Python/Common/Misc.py | 2 + .../Python/Workspace/BuildClassObject.py | 85 +++- .../Source/Python/Workspace/DecBuildData.py | 29 +- .../Source/Python/Workspace/DscBuildData.py | 384 +++++++++++------ .../Source/Python/Workspace/MetaFileParser.py | 86 +++- 6 files changed, 644 insertions(+), 338 deletions(-) diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py index a21ab5daa7..f6e245be70 100644 --- a/BaseTools/Source/Python/Common/Expression.py +++ b/BaseTools/Source/Python/Common/Expression.py @@ -820,221 +820,219 @@ class ValueExpressionEx(ValueExpression): def __call__(self, RealValue=False, Depth=0): PcdValue = self.PcdValue - try: - PcdValue = ValueExpression.__call__(self, RealValue, Depth) - if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or PcdValue.startswith("L'")): - PcdValue, Size = ParseFieldValue(PcdValue) - PcdValueList = [] - for I in range(Size): - PcdValueList.append('0x%02X'%(PcdValue & 0xff)) - PcdValue = PcdValue >> 8 - PcdValue = '{' + ','.join(PcdValueList) + '}' - elif self.PcdType in TAB_PCD_NUMERIC_TYPES and (PcdValue.startswith("'") or \ - PcdValue.startswith('"') or PcdValue.startswith("L'") or PcdValue.startswith('L"') or PcdValue.startswith('{')): - raise BadExpression - except WrnExpression as Value: - PcdValue = Value.result - except BadExpression as Value: - if self.PcdType in TAB_PCD_NUMERIC_TYPES: - PcdValue = PcdValue.strip() - if PcdValue.startswith('{') and PcdValue.endswith('}'): - PcdValue = SplitPcdValueString(PcdValue[1:-1]) - if ERR_STRING_CMP.split(':')[0] in Value.message: - raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value)) - if isinstance(PcdValue, type([])): - TmpValue = 0 - Size = 0 - ValueType = '' - for Item in PcdValue: - Item = Item.strip() - if Item.startswith(TAB_UINT8): - ItemSize = 1 - ValueType = TAB_UINT8 - elif Item.startswith(TAB_UINT16): - ItemSize = 2 - ValueType = TAB_UINT16 - elif Item.startswith(TAB_UINT32): - ItemSize = 4 - ValueType = TAB_UINT32 - elif Item.startswith(TAB_UINT64): - ItemSize = 8 - ValueType = TAB_UINT64 - elif Item[0] in {'"', "'", 'L'}: - ItemSize = 0 - ValueType = TAB_VOID - else: - ItemSize = 0 - ValueType = TAB_UINT8 - Item = ValueExpressionEx(Item, ValueType, self._Symb)(True) - - if ItemSize == 0: - try: - tmpValue = int(Item, 0) - if tmpValue > 255: - raise BadExpression("Byte array number %s should less than 0xFF." % Item) - except BadExpression as Value: - raise BadExpression(Value) - except ValueError: - pass - ItemValue, ItemSize = ParseFieldValue(Item) - else: - ItemValue = ParseFieldValue(Item)[0] - - if isinstance(ItemValue, type('')): - ItemValue = int(ItemValue, 0) - - TmpValue = (ItemValue << (Size * 8)) | TmpValue - Size = Size + ItemSize - else: - try: - TmpValue, Size = ParseFieldValue(PcdValue) - except BadExpression as Value: - raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value)) - if isinstance(TmpValue, type('')): - try: - TmpValue = int(TmpValue) - except: - raise BadExpression(Value) - else: - PcdValue = '0x%0{}X'.format(Size) % (TmpValue) - if TmpValue < 0: - raise BadExpression('Type %s PCD Value is negative' % self.PcdType) - if self.PcdType == TAB_UINT8 and Size > 1: - raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType) - if self.PcdType == TAB_UINT16 and Size > 2: - raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType) - if self.PcdType == TAB_UINT32 and Size > 4: - raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType) - if self.PcdType == TAB_UINT64 and Size > 8: - raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType) - else: - try: - TmpValue = int(PcdValue) - TmpList = [] - if TmpValue.bit_length() == 0: - PcdValue = '{0x00}' - else: - for I in range((TmpValue.bit_length() + 7) / 8): - TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff)) - PcdValue = '{' + ', '.join(TmpList) + '}' - except: - if PcdValue.strip().startswith('{'): - PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1]) - LabelDict = {} - NewPcdValueList = [] - LabelOffset = 0 - for Item in PcdValueList: - # compute byte offset of every LABEL - LabelList = _ReLabel.findall(Item) - Item = _ReLabel.sub('', Item) + if "{CODE(" not in PcdValue: + try: + PcdValue = ValueExpression.__call__(self, RealValue, Depth) + if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or PcdValue.startswith("L'")): + PcdValue, Size = ParseFieldValue(PcdValue) + PcdValueList = [] + for I in range(Size): + PcdValueList.append('0x%02X'%(PcdValue & 0xff)) + PcdValue = PcdValue >> 8 + PcdValue = '{' + ','.join(PcdValueList) + '}' + elif self.PcdType in TAB_PCD_NUMERIC_TYPES and (PcdValue.startswith("'") or \ + PcdValue.startswith('"') or PcdValue.startswith("L'") or PcdValue.startswith('L"') or PcdValue.startswith('{')): + raise BadExpression + except WrnExpression as Value: + PcdValue = Value.result + except BadExpression as Value: + if self.PcdType in TAB_PCD_NUMERIC_TYPES: + PcdValue = PcdValue.strip() + if PcdValue.startswith('{') and PcdValue.endswith('}'): + PcdValue = SplitPcdValueString(PcdValue[1:-1]) + if isinstance(PcdValue, type([])): + TmpValue = 0 + Size = 0 + ValueType = '' + for Item in PcdValue: Item = Item.strip() - if LabelList: - for Label in LabelList: - if not IsValidCName(Label): - raise BadExpression('%s is not a valid c variable name' % Label) - if Label not in LabelDict: - LabelDict[Label] = str(LabelOffset) if Item.startswith(TAB_UINT8): - LabelOffset = LabelOffset + 1 + ItemSize = 1 + ValueType = TAB_UINT8 elif Item.startswith(TAB_UINT16): - LabelOffset = LabelOffset + 2 + ItemSize = 2 + ValueType = TAB_UINT16 elif Item.startswith(TAB_UINT32): - LabelOffset = LabelOffset + 4 + ItemSize = 4 + ValueType = TAB_UINT32 elif Item.startswith(TAB_UINT64): - LabelOffset = LabelOffset + 8 + ItemSize = 8 + ValueType = TAB_UINT64 + elif Item[0] in {'"', "'", 'L'}: + ItemSize = 0 + ValueType = TAB_VOID else: + ItemSize = 0 + ValueType = TAB_UINT8 + Item = ValueExpressionEx(Item, ValueType, self._Symb)(True) + if ItemSize == 0: try: - ItemValue, ItemSize = ParseFieldValue(Item) - LabelOffset = LabelOffset + ItemSize - except: - LabelOffset = LabelOffset + 1 - - for Item in PcdValueList: - # for LABEL parse - Item = Item.strip() - try: - Item = _ReLabel.sub('', Item) - except: - pass - try: - OffsetList = _ReOffset.findall(Item) - except: - pass - # replace each offset, except errors - for Offset in OffsetList: - try: - Item = Item.replace('OFFSET_OF({})'.format(Offset), LabelDict[Offset]) - except: - raise BadExpression('%s not defined' % Offset) - - NewPcdValueList.append(Item) - - AllPcdValueList = [] - for Item in NewPcdValueList: - Size = 0 - ValueStr = '' - TokenSpaceGuidName = '' - if Item.startswith(TAB_GUID) and Item.endswith(')'): - try: - TokenSpaceGuidName = re.search('GUID\((\w+)\)', Item).group(1) - except: + tmpValue = int(Item, 0) + if tmpValue > 255: + raise BadExpression("Byte array number %s should less than 0xFF." % Item) + except BadExpression as Value: + raise BadExpression(Value) + except ValueError: pass - if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb: - Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')' - elif TokenSpaceGuidName: - raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName) - Item, Size = ParseFieldValue(Item) - for Index in range(0, Size): - ValueStr = '0x%02X' % (int(Item) & 255) - Item >>= 8 - AllPcdValueList.append(ValueStr) - continue - elif Item.startswith('DEVICE_PATH') and Item.endswith(')'): - Item, Size = ParseFieldValue(Item) - AllPcdValueList.append(Item[1:-1]) - continue + ItemValue, ItemSize = ParseFieldValue(Item) else: - ValueType = "" + ItemValue = ParseFieldValue(Item)[0] + + if isinstance(ItemValue, type('')): + ItemValue = int(ItemValue, 0) + + TmpValue = (ItemValue << (Size * 8)) | TmpValue + Size = Size + ItemSize + else: + try: + TmpValue, Size = ParseFieldValue(PcdValue) + except BadExpression as Value: + raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value)) + if isinstance(TmpValue, type('')): + try: + TmpValue = int(TmpValue) + except: + raise BadExpression(Value) + else: + PcdValue = '0x%0{}X'.format(Size) % (TmpValue) + if TmpValue < 0: + raise BadExpression('Type %s PCD Value is negative' % self.PcdType) + if self.PcdType == TAB_UINT8 and Size > 1: + raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType) + if self.PcdType == TAB_UINT16 and Size > 2: + raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType) + if self.PcdType == TAB_UINT32 and Size > 4: + raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType) + if self.PcdType == TAB_UINT64 and Size > 8: + raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType) + else: + try: + TmpValue = int(PcdValue) + TmpList = [] + if TmpValue.bit_length() == 0: + PcdValue = '{0x00}' + else: + for I in range((TmpValue.bit_length() + 7) / 8): + TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff)) + PcdValue = '{' + ', '.join(TmpList) + '}' + except: + if PcdValue.strip().startswith('{'): + PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1]) + LabelDict = {} + NewPcdValueList = [] + LabelOffset = 0 + for Item in PcdValueList: + # compute byte offset of every LABEL + LabelList = _ReLabel.findall(Item) + Item = _ReLabel.sub('', Item) + Item = Item.strip() + if LabelList: + for Label in LabelList: + if not IsValidCName(Label): + raise BadExpression('%s is not a valid c variable name' % Label) + if Label not in LabelDict: + LabelDict[Label] = str(LabelOffset) if Item.startswith(TAB_UINT8): - ItemSize = 1 - ValueType = TAB_UINT8 + LabelOffset = LabelOffset + 1 elif Item.startswith(TAB_UINT16): - ItemSize = 2 - ValueType = TAB_UINT16 + LabelOffset = LabelOffset + 2 elif Item.startswith(TAB_UINT32): - ItemSize = 4 - ValueType = TAB_UINT32 + LabelOffset = LabelOffset + 4 elif Item.startswith(TAB_UINT64): - ItemSize = 8 - ValueType = TAB_UINT64 - else: - ItemSize = 0 - if ValueType: - TmpValue = ValueExpressionEx(Item, ValueType, self._Symb)(True) + LabelOffset = LabelOffset + 8 else: - TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True) - Item = '0x%x' % TmpValue if not isinstance(TmpValue, type('')) else TmpValue - if ItemSize == 0: - ItemValue, ItemSize = ParseFieldValue(Item) - if Item[0] not in {'"', 'L', '{'} and ItemSize > 1: - raise BadExpression("Byte array number %s should less than 0xFF." % Item) + try: + ItemValue, ItemSize = ParseFieldValue(Item) + LabelOffset = LabelOffset + ItemSize + except: + LabelOffset = LabelOffset + 1 + + for Item in PcdValueList: + # for LABEL parse + Item = Item.strip() + try: + Item = _ReLabel.sub('', Item) + except: + pass + try: + OffsetList = _ReOffset.findall(Item) + except: + pass + # replace each offset, except errors + for Offset in OffsetList: + try: + Item = Item.replace('OFFSET_OF({})'.format(Offset), LabelDict[Offset]) + except: + raise BadExpression('%s not defined' % Offset) + + NewPcdValueList.append(Item) + + AllPcdValueList = [] + for Item in NewPcdValueList: + Size = 0 + ValueStr = '' + TokenSpaceGuidName = '' + if Item.startswith(TAB_GUID) and Item.endswith(')'): + try: + TokenSpaceGuidName = re.search('GUID\((\w+)\)', Item).group(1) + except: + pass + if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb: + Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')' + elif TokenSpaceGuidName: + raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName) + Item, Size = ParseFieldValue(Item) + for Index in range(0, Size): + ValueStr = '0x%02X' % (int(Item) & 255) + Item >>= 8 + AllPcdValueList.append(ValueStr) + continue + elif Item.startswith('DEVICE_PATH') and Item.endswith(')'): + Item, Size = ParseFieldValue(Item) + AllPcdValueList.append(Item[1:-1]) + continue else: - ItemValue = ParseFieldValue(Item)[0] - for I in range(0, ItemSize): - ValueStr = '0x%02X' % (int(ItemValue) & 255) - ItemValue >>= 8 - AllPcdValueList.append(ValueStr) - Size += ItemSize - - if Size > 0: - PcdValue = '{' + ','.join(AllPcdValueList) + '}' - else: - raise BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value)) + ValueType = "" + if Item.startswith(TAB_UINT8): + ItemSize = 1 + ValueType = TAB_UINT8 + elif Item.startswith(TAB_UINT16): + ItemSize = 2 + ValueType = TAB_UINT16 + elif Item.startswith(TAB_UINT32): + ItemSize = 4 + ValueType = TAB_UINT32 + elif Item.startswith(TAB_UINT64): + ItemSize = 8 + ValueType = TAB_UINT64 + else: + ItemSize = 0 + if ValueType: + TmpValue = ValueExpressionEx(Item, ValueType, self._Symb)(True) + else: + TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True) + Item = '0x%x' % TmpValue if not isinstance(TmpValue, type('')) else TmpValue + if ItemSize == 0: + ItemValue, ItemSize = ParseFieldValue(Item) + if Item[0] not in {'"', 'L', '{'} and ItemSize > 1: + raise BadExpression("Byte array number %s should less than 0xFF." % Item) + else: + ItemValue = ParseFieldValue(Item)[0] + for I in range(0, ItemSize): + ValueStr = '0x%02X' % (int(ItemValue) & 255) + ItemValue >>= 8 + AllPcdValueList.append(ValueStr) + Size += ItemSize + + if Size > 0: + PcdValue = '{' + ','.join(AllPcdValueList) + '}' + else: + raise BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value)) - if PcdValue == 'True': - PcdValue = '1' - if PcdValue == 'False': - PcdValue = '0' + if PcdValue == 'True': + PcdValue = '1' + if PcdValue == 'False': + PcdValue = '0' if RealValue: return PcdValue diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index 3b8efb2e71..e23772c297 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -1297,6 +1297,8 @@ def ParseDevPathValue (Value): return '{' + out + '}', Size def ParseFieldValue (Value): + if "{CODE(" in Value: + return Value, len(Value.split(",")) if isinstance(Value, type(0)): return Value, (Value.bit_length() + 7) / 8 if not isinstance(Value, type('')): diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py index 95edc376fe..15bb822910 100644 --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -50,7 +50,7 @@ class PcdClassObject(object): self.TokenSpaceGuidCName = Guid self.TokenSpaceGuidValue = GuidValue self.Type = Type - self.DatumType = DatumType + self._DatumType = DatumType self.DefaultValue = Value self.TokenValue = Token self.MaxDatumSize = MaxDatumSize @@ -72,6 +72,63 @@ class PcdClassObject(object): self.PcdValueFromFdf = "" self.CustomAttribute = {} self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag + self._Capacity = None + + @property + def Capacity(self): + self._Capacity = [] + dimension = ArrayIndex.findall(self._DatumType) + for item in dimension: + maxsize = item.lstrip("[").rstrip("]").strip() + if not maxsize: + maxsize = "-1" + self._Capacity.append(maxsize) + if hasattr(self, "SkuOverrideValues"): + for sku in self.SkuOverrideValues: + for defaultstore in self.SkuOverrideValues[sku]: + fields = self.SkuOverrideValues[sku][defaultstore] + for demesionattr in fields: + deme = ArrayIndex.findall(demesionattr) + for i in range(len(deme)-1): + if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]): + print "error" + if hasattr(self,"DefaultValues"): + for demesionattr in self.DefaultValues: + deme = ArrayIndex.findall(demesionattr) + for i in range(len(deme)-1): + if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]): + print "error" + self._Capacity = [str(int(d) + 1) for d in self._Capacity] + return self._Capacity + @property + def DatumType(self): + return self._DatumType + + @DatumType.setter + def DatumType(self,DataType): + self._DatumType = DataType + self._Capacity = None + + @property + def BaseDatumType(self): + if self.IsArray(): + return self._DatumType[:self._DatumType.index("[")] + else: + return self._DatumType + def IsArray(self): + return True if len(self.Capacity) else False + + def IsAggregateDatumType(self): + if self.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: + return False + if self.IsArray() or StructPattern.match(self.DatumType): + return True + return False + + def IsSimpleTypeArray(self): + if self.IsArray() and self.BaseDatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, "BOOLEAN"]: + return True + return False @staticmethod def GetPcdMaxSizeWorker(PcdString, MaxSize): @@ -183,23 +240,27 @@ class StructurePcd(PcdClassObject): def __repr__(self): return self.TypeName - def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0): - if FieldName in self.DefaultValues: - del self.DefaultValues[FieldName] - self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo] - return self.DefaultValues[FieldName] + def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0,DimensionAttr ="-1"): + if DimensionAttr not in self.DefaultValues: + self.DefaultValues[DimensionAttr] = collections.OrderedDict() + if FieldName in self.DefaultValues[DimensionAttr]: + del self.DefaultValues[DimensionAttr][FieldName] + self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo] + return self.DefaultValues[DimensionAttr][FieldName] def SetDecDefaultValue(self, DefaultValue): self.DefaultValueFromDec = DefaultValue - def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0): + def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'): if SkuName not in self.SkuOverrideValues: self.SkuOverrideValues[SkuName] = OrderedDict() if DefaultStoreName not in self.SkuOverrideValues[SkuName]: self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict() - if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName]: - del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] - self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] = [Value.strip(), FileName, LineNo] - return self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] + if DimensionAttr not in self.SkuOverrideValues[SkuName][DefaultStoreName]: + self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr] = collections.OrderedDict() + if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]: + del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName][DimensionAttr] + self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo] + return self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] def SetPcdMode (self, PcdMode): self.PcdMode = PcdMode @@ -209,7 +270,7 @@ class StructurePcd(PcdClassObject): self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue self.Type = PcdObject.Type if PcdObject.Type else self.Type - self.DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType + self._DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType self.DefaultValue = PcdObject.DefaultValue if PcdObject.DefaultValue else self.DefaultValue self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py index 31ee13eca9..cc00409fee 100644 --- a/BaseTools/Source/Python/Workspace/DecBuildData.py +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py @@ -361,6 +361,21 @@ class DecBuildData(PackageBuildClassObject): self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) return self._Pcds + def ParsePcdName(self,TokenCName): + TokenCName = TokenCName.strip() + if TokenCName.startswith("["): + if "." in TokenCName: + Demesionattr = TokenCName[:TokenCName.index(".")] + Fields = TokenCName[TokenCName.index(".")+1:] + else: + Demesionattr = TokenCName + Fields = "" + else: + Demesionattr = "" + Fields = TokenCName + + return Demesionattr,Fields + def ProcessStructurePcd(self, StructurePcdRawDataSet): s_pcd_set = OrderedDict() for s_pcd, LineNo in StructurePcdRawDataSet: @@ -373,6 +388,8 @@ class DecBuildData(PackageBuildClassObject): dep_pkgs = [] struct_pcd = StructurePcd() for item, LineNo in s_pcd_set[pcdname]: + if not item.TokenCName: + continue if "" in item.TokenCName: struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue) elif "" in item.TokenCName: @@ -385,7 +402,8 @@ class DecBuildData(PackageBuildClassObject): struct_pcd.PkgPath = self.MetaFile.File struct_pcd.SetDecDefaultValue(item.DefaultValue) else: - struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue, self.MetaFile.File, LineNo) + DemesionAttr, Fields = self.ParsePcdName(item.TokenCName) + struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr) struct_pcd.PackageDecs = dep_pkgs str_pcd_set.append(struct_pcd) @@ -446,15 +464,12 @@ class DecBuildData(PackageBuildClassObject): StructurePcds = self.ProcessStructurePcd(StrPcdSet) for pcd in StructurePcds: Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd - StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$') for pcd in Pcds.values(): if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: - if StructPattern.match(pcd.DatumType) is None: + if not pcd.IsAggregateDatumType(): EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1]) - for struct_pcd in Pcds.values(): - if isinstance(struct_pcd, StructurePcd) and not struct_pcd.StructuredPcdIncludeFile: - EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName, DefinitionPosition[struct_pcd][0], DefinitionPosition[struct_pcd][1] )) - + elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile: + EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] )) return Pcds @property diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 11aa63fb26..66d1881aac 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -42,6 +42,7 @@ import subprocess from Common.Misc import SaveFileOnChange from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject from collections import OrderedDict, defaultdict +from .BuildClassObject import ArrayIndex PcdValueInitName = 'PcdValueInit' @@ -912,25 +913,26 @@ class DscBuildData(PlatformBuildClassObject): ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting)) if ValueList[Index]: DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType - try: - ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True) - except BadExpression as Value: - EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo, - ExtraData="PCD [%s.%s] Value \"%s\" " % ( - TokenSpaceGuid, PcdCName, ValueList[Index])) - except EvaluationException as Excpt: - if hasattr(Excpt, 'Pcd'): - if Excpt.Pcd in GlobalData.gPlatformOtherPcds: - EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as" - " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section" - " of the DSC file" % Excpt.Pcd, - File=self.MetaFile, Line=LineNo) + if "{CODE(" not in ValueList[Index]: + try: + ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True) + except BadExpression as Value: + EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo, + ExtraData="PCD [%s.%s] Value \"%s\" " % ( + TokenSpaceGuid, PcdCName, ValueList[Index])) + except EvaluationException as Excpt: + if hasattr(Excpt, 'Pcd'): + if Excpt.Pcd in GlobalData.gPlatformOtherPcds: + EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as" + " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section" + " of the DSC file" % Excpt.Pcd, + File=self.MetaFile, Line=LineNo) + else: + EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd, + File=self.MetaFile, Line=LineNo) else: - EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd, + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt), File=self.MetaFile, Line=LineNo) - else: - EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt), - File=self.MetaFile, Line=LineNo) if ValueList[Index]: Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index]) @@ -1395,6 +1397,26 @@ class DscBuildData(PlatformBuildClassObject): self.Pcds[Name, Guid].DefaultValue = Value return AllPcds + def ParsePcdNameStruct(self,NamePart1,NamePart2): + TokenSpaceCName = PcdCName = DimensionAttr = Field = "" + if "." in NamePart1: + TokenSpaceCName, TempPcdCName = NamePart1.split(".") + if "[" in TempPcdCName: + PcdCName = TempPcdCName[:TempPcdCName.index("[")] + DimensionAttr = TempPcdCName[TempPcdCName.index("["):] + else: + PcdCName = TempPcdCName + Field = NamePart2 + else: + TokenSpaceCName = NamePart1 + if "[" in NamePart2: + PcdCName = NamePart2[:NamePart2.index("[")] + DimensionAttr = NamePart2[NamePart2.index("["):] + else: + PcdCName = NamePart2 + + return TokenSpaceCName,PcdCName,DimensionAttr,Field + def UpdateStructuredPcds(self, TypeList, AllPcds): DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT], @@ -1424,9 +1446,19 @@ class DscBuildData(PlatformBuildClassObject): SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName if SkuName not in SkuIds: continue + TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName) + pcd_in_dec = self._DecPcds.get((PCName,TCName), None) + if pcd_in_dec is None: + EdkLogger.error('build', PARSER_ERROR, + "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch), + File=self.MetaFile, Line = Dummy5) + if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName): + if not isinstance (pcd_in_dec, StructurePcd): + EdkLogger.error('build', PARSER_ERROR, + "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch), + File=self.MetaFile, Line = Dummy5) - if SkuName in SkuIds and "." in TokenSpaceGuid: - S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]]) + S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]]) # handle pcd value override StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet) @@ -1434,27 +1466,19 @@ class DscBuildData(PlatformBuildClassObject): for str_pcd in StrPcdSet: str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None) str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None) - if not isinstance (str_pcd_dec, StructurePcd): - EdkLogger.error('build', PARSER_ERROR, - "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch), - File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5]) - if str_pcd_dec: - str_pcd_obj_str = StructurePcd() - str_pcd_obj_str.copy(str_pcd_dec) - if str_pcd_obj: - str_pcd_obj_str.copy(str_pcd_obj) - if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: - str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList} - else: - str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList} - for str_pcd_data in StrPcdSet[str_pcd]: - if str_pcd_data[3] in SkuIds: - str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), TAB_DEFAULT if str_pcd_data[3] == TAB_COMMON else str_pcd_data[3], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[5]) - S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str - else: - EdkLogger.error('build', PARSER_ERROR, - "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch), - File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5]) + str_pcd_obj_str = StructurePcd() + str_pcd_obj_str.copy(str_pcd_dec) + if str_pcd_obj: + str_pcd_obj_str.copy(str_pcd_obj) + if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList} + else: + str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList} + for str_pcd_data in StrPcdSet[str_pcd]: + if str_pcd_data[4] in SkuIds: + str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2]) + S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str + # Add the Structure PCD that only defined in DEC, don't have override in DSC file for Pcd in self.DecPcds: if isinstance(self._DecPcds[Pcd], StructurePcd): @@ -1590,9 +1614,10 @@ class DscBuildData(PlatformBuildClassObject): if SkuName not in AvailableSkuIdSet: EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, File=self.MetaFile, Line=Dummy5) - if "." not in TokenSpaceGuid: - PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) - PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting + if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON): + if "." not in TokenSpaceGuid and "[" not in PcdCName: + PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) + PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet: Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName] @@ -1688,7 +1713,20 @@ class DscBuildData(PlatformBuildClassObject): def GenerateSizeFunction(self, Pcd): CApp = "// Default Value in Dec \n" CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) - for FieldList in [Pcd.DefaultValues]: + if Pcd.IsArray(): + if (len(Pcd.Capacity) == 1 and Pcd.Capacity[0] != '0') or (len(Pcd.Capacity) >1 and reduce(lambda x,y:int(x)*int(y), Pcd.Capacity)) > 0: + CApp += " *Size = (sizeof (%s) * (%s) > *Size) ? sizeof (%s) * (%s): *Size; \n" % (Pcd.BaseDatumType, "*".join(Pcd.Capacity),Pcd.BaseDatumType, "*".join(Pcd.Capacity)) + if "{CODE(" in Pcd.DefaultValueFromDec: + CApp += " *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName) + for skuname in Pcd.SkuInfoList: + skuobj = Pcd.SkuInfoList[skuname] + if skuobj.VariableName: + for defaultstore in skuobj.DefaultStoreDict: + CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore) + else: + CApp += " *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT) + for index in Pcd.DefaultValues: + FieldList = Pcd.DefaultValues[index] if not FieldList: continue for FieldName in FieldList: @@ -1718,31 +1756,32 @@ class DscBuildData(PlatformBuildClassObject): continue for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]: CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) - for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]: - if not FieldList: - continue - for FieldName in FieldList: - FieldName = "." + FieldName - IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) - if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): - try: - Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True) - except BadExpression: - EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % - (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) - Value, ValueSize = ParseFieldValue(Value) - CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); - else: - NewFieldName = '' - FieldName_ori = FieldName.strip('.') - while '[' in FieldName: - NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' - ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) - FieldName = FieldName.split(']', 1)[1] - FieldName = NewFieldName + FieldName - while '[' in FieldName: - FieldName = FieldName.rsplit('[', 1)[0] - CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) + for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]: + for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]: + if not FieldList: + continue + for FieldName in FieldList: + FieldName = "." + FieldName + IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) + if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): + try: + Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName: + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) if Pcd.PcdFieldValueFromFdf: CApp = CApp + "// From fdf \n" for FieldName in Pcd.PcdFieldValueFromFdf: @@ -1791,19 +1830,64 @@ class DscBuildData(PlatformBuildClassObject): while '[' in FieldName: FieldName = FieldName.rsplit('[', 1)[0] CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0]) - CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize()) + if Pcd.GetPcdMaxSize(): + CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize()) CApp = CApp + "}\n" return CApp @staticmethod def GenerateSizeStatments(Pcd): - CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType) + if Pcd.IsArray(): + r_datatype = [Pcd.BaseDatumType] + for dem in Pcd.Capacity: + if dem == '0': + r_datatype.append("[1]") + else: + r_datatype.append("[" + dem + "]") + CApp = ' Size = sizeof(%s);\n' % ("".join(r_datatype)) + else: + CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType) CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) return CApp + def GetIndicator(self,index,FieldName,Pcd): + def cleanupindex(indexstr): + return indexstr.strip("[").strip("]").strip() + index_elements = ArrayIndex.findall(index) + pcd_capacity = Pcd.Capacity + if index: + indicator = "(Pcd" + if len(pcd_capacity)>2: + for i in xrange(0,len(index_elements)): + index_ele = index_elements[i] + index_num = index_ele.strip("[").strip("]").strip() + if i == len(index_elements) -2: + indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i])) + break + else: + indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1])) + elif len(pcd_capacity) == 2: + indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip()) + elif len(pcd_capacity) == 1: + index_ele = index_elements[0] + index_num = index_ele.strip("[").strip("]").strip() + indicator += " + %s)" % (index_num) + else: + indicator = "Pcd" + if FieldName: + indicator += "->" + FieldName + return indicator + + def GetStarNum(self,Pcd): + if not Pcd.IsArray(): + return 1 + elif Pcd.IsSimpleTypeArray(): + return len(Pcd.Capacity) + else: + return len(Pcd.Capacity) + 1 def GenerateDefaultValueAssignFunction(self, Pcd): CApp = "// Default value in Dec \n" - CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType) + CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType) CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' CHAR8 *Value;\n' DefaultValueFromDec = Pcd.DefaultValueFromDec @@ -1822,9 +1906,13 @@ class DscBuildData(PlatformBuildClassObject): # # Use memcpy() to copy value into field # - CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) - CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) - for FieldList in [Pcd.DefaultValues]: + if "{CODE(" in Pcd.DefaultValueFromDec: + CApp = CApp + ' memcpy (Pcd, %s_%s_INIT_Value, sizeof(%s_%s_INIT_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + else: + CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + for index in Pcd.DefaultValues: + FieldList = Pcd.DefaultValues[index] if not FieldList: continue for FieldName in FieldList: @@ -1840,8 +1928,10 @@ class DscBuildData(PlatformBuildClassObject): Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) except Exception: EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2])) + + indicator = self.GetIndicator(index, FieldName,Pcd) if isinstance(Value, str): - CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) elif IsArray: # # Use memcpy() to copy value into field @@ -1850,14 +1940,16 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) + CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize) + else: if '[' in FieldName and ']' in FieldName: Index = int(FieldName.split('[')[1].split(']')[0]) CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName) if ValueSize > 4: - CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) else: - CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + "}\n" return CApp @@ -1868,7 +1960,7 @@ class DscBuildData(PlatformBuildClassObject): def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName): CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName) - CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType) + CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType) CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' CHAR8 *Value;\n' @@ -1881,40 +1973,60 @@ class DscBuildData(PlatformBuildClassObject): pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName) else: pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT) - for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]: - if not FieldList: - continue - if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = IsFieldValueAnArray(FieldList) - if IsArray: + + if pcddefaultvalue: + FieldList = pcddefaultvalue + IsArray = IsFieldValueAnArray(FieldList) + if IsArray: + if "{CODE(" not in FieldList: try: FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True) except BadExpression: EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList)) - Value, ValueSize = ParseFieldValue (FieldList) + Value, ValueSize = ParseFieldValue (FieldList) - if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT): - if isinstance(Value, str): + if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT): + if isinstance(Value, str): + if "{CODE(" in Value: + CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) + else: CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) - elif IsArray: - # - # Use memcpy() to copy value into field - # + elif IsArray: + # + # Use memcpy() to copy value into field + # + if Pcd.IsArray(): + CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) + else: CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) - else: - if isinstance(Value, str): + else: + if isinstance(Value, str): + if "{CODE(" in Value: + CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) + else: CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)) - elif IsArray: - # - # Use memcpy() to copy value into field - # + elif IsArray: + # + # Use memcpy() to copy value into field + # + if Pcd.IsArray(): + CApp = CApp + ' memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName) + else: CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)) CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + + inheritvalue = inherit_OverrideValues.get(DefaultStoreName) + if not inheritvalue: + inheritvalue = [] + for index in inheritvalue: + FieldList = inheritvalue[index] + if not FieldList: continue if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )): for FieldName in FieldList: + indicator = self.GetIndicator(index, FieldName,Pcd) IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: @@ -1932,18 +2044,19 @@ class DscBuildData(PlatformBuildClassObject): # # Use memcpy() to copy value into field # - CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) + CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize) else: if '[' in FieldName and ']' in FieldName: Index = int(FieldName.split('[')[1].split(']')[0]) CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName) if ValueSize > 4: - CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) else: - CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + "}\n" return CApp @@ -1954,7 +2067,7 @@ class DscBuildData(PlatformBuildClassObject): def GenerateCommandLineValue(self, Pcd): CApp = "// Value in CommandLine\n" - CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType) + CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType) CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' CHAR8 *Value;\n' @@ -2001,7 +2114,7 @@ class DscBuildData(PlatformBuildClassObject): # # Use memcpy() to copy value into field # - CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) @@ -2022,7 +2135,7 @@ class DscBuildData(PlatformBuildClassObject): return CApp def GenerateFdfValue(self,Pcd): CApp = "// Value in Fdf\n" - CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType) + CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType) CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' CHAR8 *Value;\n' @@ -2069,7 +2182,7 @@ class DscBuildData(PlatformBuildClassObject): # # Use memcpy() to copy value into field # - CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) @@ -2090,7 +2203,7 @@ class DscBuildData(PlatformBuildClassObject): return CApp def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp): - OverrideValues = {DefaultStore:""} + OverrideValues = {DefaultStore:{}} if Pcd.SkuOverrideValues: OverrideValues = Pcd.SkuOverrideValues[SkuName] if not OverrideValues: @@ -2106,16 +2219,14 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' CHAR8 *Value;\n' CApp = CApp + ' UINT32 OriginalSize;\n' CApp = CApp + ' VOID *OriginalPcd;\n' - CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo) + + CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo) + CApp = CApp + '\n' - if SkuName in Pcd.SkuInfoList: - DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue) - else: - DefaultValue = Pcd.DefaultValue - PcdDefaultValue = StringToArray(DefaultValue.strip()) + PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip()) - InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue) + InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType, PcdDefaultValue) # # Get current PCD value and size @@ -2138,7 +2249,7 @@ class DscBuildData(PlatformBuildClassObject): # Always keep that larger one as the current size # CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n' - CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType) + CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,) CApp = CApp + ' memset (Pcd, 0, Size);\n' # @@ -2167,7 +2278,7 @@ class DscBuildData(PlatformBuildClassObject): # # Set new PCD value and size # - CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) # # Free PCD @@ -2176,6 +2287,39 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + '}\n' CApp = CApp + '\n' return InitByteValue, CApp + + def GenerateArrayAssignment(self, Pcd): + CApp = "" + if not Pcd: + return CApp + if not Pcd.IsArray(): + return CApp + Demesion = "" + for d in Pcd.Capacity: + if d == "0": + Demesion += "[]" + else: + Demesion += "["+d+"]" + + Value = Pcd.DefaultValueFromDec + if "{CODE(" in Pcd.DefaultValueFromDec: + realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] # "{CODE(").rstrip(")}" + CApp += "static %s %s_%s_INIT_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue) + + for skuname in Pcd.SkuInfoList: + skuinfo = Pcd.SkuInfoList[skuname] + if skuinfo.VariableName: + for defaultstore in skuinfo.DefaultStoreDict: + Value = skuinfo[defaultstore] + if "{CODE(" in Value: + realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}" + CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Demesion,realvalue) + else: + Value = skuinfo.DefaultValue + if "{CODE(" in Value: + realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}" + CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue) + return CApp def SkuOverrideValuesEmpty(self,OverrideValues): if not OverrideValues: return True @@ -2215,6 +2359,8 @@ class DscBuildData(PlatformBuildClassObject): IncludeFiles.add(IncludeFile) CApp = CApp + '#include <%s>\n' % (IncludeFile) CApp = CApp + '\n' + for Pcd in StructuredPcds.values(): + CApp = CApp + self.GenerateArrayAssignment(Pcd) for PcdName in StructuredPcds: Pcd = StructuredPcds[PcdName] CApp = CApp + self.GenerateSizeFunction(Pcd) @@ -2395,6 +2541,8 @@ class DscBuildData(PlatformBuildClassObject): FileLine = FileInfo [1].split (')')[0] else: FileInfo = Message.strip().split(':') + if len(FileInfo) < 2: + continue FileName = FileInfo [0] FileLine = FileInfo [1] if FileLine.isdigit(): @@ -2478,7 +2626,7 @@ class DscBuildData(PlatformBuildClassObject): if SkuName not in AvailableSkuIdSet: EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, File=self.MetaFile, Line=Dummy5) - if "." not in TokenSpaceGuid: + if "." not in TokenSpaceGuid and "[" not in PcdCName: PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting @@ -2651,7 +2799,7 @@ class DscBuildData(PlatformBuildClassObject): if DefaultStore not in DefaultStoresDefine: EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore, File=self.MetaFile, Line=Dummy5) - if "." not in TokenSpaceGuid: + if "." not in TokenSpaceGuid and "[" not in PcdCName: PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting @@ -2814,7 +2962,7 @@ class DscBuildData(PlatformBuildClassObject): if SkuName not in AvailableSkuIdSet: EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, File=self.MetaFile, Line=Dummy5) - if "." not in TokenSpaceGuid: + if "." not in TokenSpaceGuid and "[" not in PcdCName: PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 804a4aa5cb..6fde9e54f5 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -40,6 +40,7 @@ from .MetaFileCommentParser import CheckInfComment ## RegEx for finding file versions hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}') decVersionPattern = re.compile(r'\d+\.\d+') +CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}") ## A decorator used to parse macro definition def ParseMacro(Parser): @@ -913,6 +914,10 @@ class DscParser(MetaFileParser): # self._IdMapping = {-1:-1} + self._PcdCodeValue = "" + self._PcdDataTypeCODE = False + self._CurrentPcdName = "" + ## Parser starter def Start(self): Content = '' @@ -922,6 +927,9 @@ class DscParser(MetaFileParser): EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) OwnerId = {} + + Content = self.ProcessMultipleLineCODEValue(Content) + for Index in range(0, len(Content)): Line = CleanString(Content[Index]) # skip empty line @@ -1133,6 +1141,41 @@ class DscParser(MetaFileParser): def _LibraryInstanceParser(self): self._ValueList[0] = self._CurrentLine + def ProcessMultipleLineCODEValue(self,Content): + CODEBegin = False + CODELine = "" + continuelinecount = 0 + newContent = [] + for Index in range(0, len(Content)): + Line = Content[Index] + if CODEBegin: + CODELine = CODELine + Line + continuelinecount +=1 + if ")}" in Line: + newContent.append(CODELine) + for _ in range(continuelinecount): + newContent.append("") + CODEBegin = False + CODELine = "" + continuelinecount = 0 + else: + if not Line: + newContent.append(Line) + continue + if "{CODE(" not in Line: + newContent.append(Line) + continue + elif CODEPattern.findall(Line): + newContent.append(Line) + continue + else: + CODEBegin = True + CODELine = Line + + return newContent + + def _DecodeCODEData(self): + pass ## PCD sections parser # # [PcdsFixedAtBuild] @@ -1149,7 +1192,28 @@ class DscParser(MetaFileParser): # @ParseMacro def _PcdParser(self): + if self._PcdDataTypeCODE: + self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine + if self._CurrentLine.endswith(")}"): + self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue)) + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._ValueList = None + return TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._CurrentPcdName = TokenList[0] + if TokenList[1].strip().startswith("{CODE"): + self._PcdDataTypeCODE = True + self._PcdCodeValue = TokenList[1].strip() + + if self._PcdDataTypeCODE: + if self._CurrentLine.endswith(")}"): + self._PcdDataTypeCODE = False + self._PcdCodeValue = "" + else: + self._ValueList = None + return self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT) if len(PcdNameTockens) == 2: @@ -1907,6 +1971,17 @@ class DecParser(MetaFileParser): if self._ValueList[0] not in self._GuidDict: self._GuidDict[self._ValueList[0]] = self._ValueList[1] + def ParsePcdName(self,namelist): + if "[" in namelist[1]: + pcdname = namelist[1][:namelist[1].index("[")] + arrayindex = namelist[1][namelist[1].index("["):] + namelist[1] = pcdname + if len(namelist) == 2: + namelist.append(arrayindex) + else: + namelist[2] = ".".join((arrayindex,namelist[2])) + return namelist + ## PCD sections parser # # [PcdsFixedAtBuild] @@ -1945,9 +2020,16 @@ class DecParser(MetaFileParser): return else: PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT) - PcdNames = PcdTockens[0].split(TAB_SPLIT) + PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT)) if len(PcdNames) == 2: - self._CurrentStructurePcdName = "" + if PcdNames[1].strip().endswith("]"): + PcdName = PcdNames[1][:PcdNames[1].index('[')] + Index = PcdNames[1][PcdNames[1].index('['):] + self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName)) + self._ValueList[1] = Index + self._ValueList[2] = PcdTockens[1] + else: + self._CurrentStructurePcdName = "" else: if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]): EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])), -- 2.19.1.windows.1