BaseTools/Build: Add SDL support

1.BaseTool add ATTRIBUTE (+/-RT, RO) support in PCD declaration in DSC file
2.BaseTool collect valid PCD value in DEC file and generate data base for runtime sanity check
3.BaseTool support SetPcd error.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Bob Feng" <bob.c.feng@intel.com>
Reviewed-by: "Chen, Hesheng" <hesheng.chen@intel.com>
Reviewed-by: "Liu, Yingke D" <yingke.d.liu@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17158 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Bob Feng 2015-04-10 06:59:47 +00:00 committed by bobfeng
parent b7668ccee9
commit 82a6a9605c
14 changed files with 1299 additions and 30 deletions

View File

@ -1,7 +1,7 @@
## @file ## @file
# Generate AutoGen.h, AutoGen.c and *.depex files # Generate AutoGen.h, AutoGen.c and *.depex files
# #
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -1813,6 +1813,9 @@ class PlatformAutoGen(AutoGen):
if not IsValid: if not IsValid:
EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile, EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName)) ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
ToPcd.validateranges = FromPcd.validateranges
ToPcd.validlists = FromPcd.validlists
ToPcd.expressions = FromPcd.expressions
if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]: if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \ EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \

View File

@ -1,7 +1,7 @@
## @file ## @file
# Routines for generating AutoGen.h and AutoGen.c # Routines for generating AutoGen.h and AutoGen.c
# #
# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -786,6 +786,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + Pcd.TokenCName
PcdExCNameList = [] PcdExCNameList = []
if Pcd.Type in gDynamicExPcd: if Pcd.Type in gDynamicExPcd:
@ -805,21 +806,27 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(Value) LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName)) AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(Value) LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
elif Pcd.Type in gDynamicPcd: elif Pcd.Type in gDynamicPcd:
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
else: else:
AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(Value) LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
else: else:
PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
Const = 'const' Const = 'const'
@ -963,8 +970,10 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName)) AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtrS(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName))
else: else:
AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName)) AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
AutoGenH.Append('#define %s(Value) ((%s = (Value)), RETURN_SUCCESS) \n' % (SetModeStatusName, PcdVariableName))
else: else:
AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName) AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
@ -1018,6 +1027,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType] DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName
Type = '' Type = ''
Array = '' Array = ''
@ -1046,28 +1056,35 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(Value) LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName)) AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
if Pcd.DatumType == 'VOID*': if Pcd.DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(Value) LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else: else:
AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber)) AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber))
if PcdItemType in gDynamicPcd: if PcdItemType in gDynamicPcd:
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
if DatumType == 'VOID*': if DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
else: else:
AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName)) AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(Value) LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE: if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) ) AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName)) AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName)) AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
AutoGenH.Append('#define %s(Value) ((%s = (Value)), RETURN_SUCCESS)\n' % (SetModeStatusName, PcdVariableName))
if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG: if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))

View File

@ -1,7 +1,7 @@
## @file ## @file
# Routines for generating Pcd Database # Routines for generating Pcd Database
# #
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -14,8 +14,12 @@ from StringIO import StringIO
from Common.Misc import * from Common.Misc import *
from Common.String import StringToArray from Common.String import StringToArray
from struct import pack from struct import pack
from ValidCheckingInfoObject import VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER
from ValidCheckingInfoObject import VAR_CHECK_PCD_VARIABLE_TAB
from ValidCheckingInfoObject import VAR_VALID_OBJECT_FACTORY
from Common.VariableAttributes import VariableAttributes
DATABASE_VERSION = 4 DATABASE_VERSION = 5
gPcdDatabaseAutoGenC = TemplateString(""" gPcdDatabaseAutoGenC = TemplateString("""
// //
@ -444,7 +448,7 @@ class DbVariableTableItemList (DbComItemList):
RawDataList = [] RawDataList = []
DbComItemList.__init__(self, ItemSize, DataList, RawDataList) DbComItemList.__init__(self, ItemSize, DataList, RawDataList)
def PackData(self): def PackData(self):
PackStr = "=LLHH" PackStr = "=LLHHLHH"
Buffer = '' Buffer = ''
for DataList in self.RawDataList: for DataList in self.RawDataList:
for Data in DataList: for Data in DataList:
@ -452,7 +456,10 @@ class DbVariableTableItemList (DbComItemList):
GetIntegerValue(Data[0]), GetIntegerValue(Data[0]),
GetIntegerValue(Data[1]), GetIntegerValue(Data[1]),
GetIntegerValue(Data[2]), GetIntegerValue(Data[2]),
GetIntegerValue(Data[3])) GetIntegerValue(Data[3]),
GetIntegerValue(Data[4]),
GetIntegerValue(Data[5]),
GetIntegerValue(0))
return Buffer return Buffer
class DbStringHeadTableItemList(DbItemList): class DbStringHeadTableItemList(DbItemList):
@ -712,7 +719,7 @@ def BuildExDataBase(Dict):
# DbItemList to DbStringHeadTableItemList # DbItemList to DbStringHeadTableItemList
DbStringHeadValue = DbStringHeadTableItemList(4, RawDataList = StringHeadValue) DbStringHeadValue = DbStringHeadTableItemList(4, RawDataList = StringHeadValue)
VariableTable = Dict['VARIABLE_DB_VALUE'] VariableTable = Dict['VARIABLE_DB_VALUE']
DbVariableTable = DbVariableTableItemList(12, RawDataList = VariableTable) DbVariableTable = DbVariableTableItemList(20, RawDataList = VariableTable)
NumberOfSkuEnabledPcd = GetIntegerValue(Dict['SKU_HEAD_SIZE']) NumberOfSkuEnabledPcd = GetIntegerValue(Dict['SKU_HEAD_SIZE'])
Dict['SKUHEAD_TABLE_VALUE'] = [(0,0) for i in xrange(NumberOfSkuEnabledPcd)] Dict['SKUHEAD_TABLE_VALUE'] = [(0,0) for i in xrange(NumberOfSkuEnabledPcd)]
SkuTable = Dict['SKUHEAD_TABLE_VALUE'] # Generated later SkuTable = Dict['SKUHEAD_TABLE_VALUE'] # Generated later
@ -852,7 +859,7 @@ def BuildExDataBase(Dict):
for VariableEntries in VariableTable: for VariableEntries in VariableTable:
skuindex = 0 skuindex = 0
for VariableEntryPerSku in VariableEntries: for VariableEntryPerSku in VariableEntries:
(VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable) = VariableEntryPerSku[:] (VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable, VariableAttribute) = VariableEntryPerSku[:]
DbIndex = 0 DbIndex = 0
DbOffset = FixedHeaderLen DbOffset = FixedHeaderLen
for DbIndex in xrange(len(DbTotal)): for DbIndex in xrange(len(DbTotal)):
@ -867,8 +874,8 @@ def BuildExDataBase(Dict):
skuindex += 1 skuindex += 1
if DbIndex >= InitTableNum: if DbIndex >= InitTableNum:
assert(False) assert(False)
VarAttr, VarProp = VariableAttributes.GetVarAttributes(VariableAttribute)
VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset) VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset, VarAttr, VarProp)
# calculate various table offset now # calculate various table offset now
DbTotalLength = FixedHeaderLen DbTotalLength = FixedHeaderLen
@ -1113,6 +1120,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
NumberOfSizeItems = 0 NumberOfSizeItems = 0
NumberOfSkuEnabledPcd = 0 NumberOfSkuEnabledPcd = 0
GuidList = [] GuidList = []
VarCheckTab = VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER()
i = 0 i = 0
ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber) ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)
for Pcd in ReorderedDynPcdList: for Pcd in ReorderedDynPcdList:
@ -1182,6 +1190,29 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
SkuIdIndex += 1 SkuIdIndex += 1
if len(Sku.VariableName) > 0: if len(Sku.VariableName) > 0:
VariableGuidStructure = Sku.VariableGuidValue
VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
if Platform.Platform.VarCheckFlag:
var_check_obj = VAR_CHECK_PCD_VARIABLE_TAB(VariableGuidStructure, StringToArray(Sku.VariableName))
try:
var_check_obj.push_back(VAR_VALID_OBJECT_FACTORY.Get_valid_object(Pcd, Sku.VariableOffset))
VarAttr, _ = VariableAttributes.GetVarAttributes(Sku.VariableAttribute)
var_check_obj.SetAttributes(VarAttr)
var_check_obj.UpdateSize()
VarCheckTab.push_back(var_check_obj)
except Exception:
ValidInfo = ''
if Pcd.validateranges:
ValidInfo = Pcd.validateranges[0]
if Pcd.validlists:
ValidInfo = Pcd.validlists[0]
if ValidInfo:
EdkLogger.error("build", PCD_VALIDATION_INFO_ERROR,
"The PCD '%s.%s' Validation information defined in DEC file has incorrect format." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
ExtraData = "[%s]" % str(ValidInfo))
else:
EdkLogger.error("build", PCD_VALIDATION_INFO_ERROR,
"The PCD '%s.%s' Validation information defined in DEC file has incorrect format." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
Pcd.TokenTypeList += ['PCD_TYPE_HII'] Pcd.TokenTypeList += ['PCD_TYPE_HII']
Pcd.InitString = 'INIT' Pcd.InitString = 'INIT'
# Store all variable names of one HII PCD under different SKU to stringTable # Store all variable names of one HII PCD under different SKU to stringTable
@ -1215,8 +1246,6 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
VariableHeadStringIndex = VariableHeadList[SkuIdIndex - 2] VariableHeadStringIndex = VariableHeadList[SkuIdIndex - 2]
# store VariableGuid to GuidTable and get the VariableHeadGuidIndex # store VariableGuid to GuidTable and get the VariableHeadGuidIndex
VariableGuidStructure = Sku.VariableGuidValue
VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
if VariableGuid not in GuidList: if VariableGuid not in GuidList:
GuidList += [VariableGuid] GuidList += [VariableGuid]
@ -1268,7 +1297,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
# the Pcd default value was filled before # the Pcd default value was filled before
VariableOffset = len(Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]) - 1 VariableOffset = len(Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]) - 1
VariableRefTable = Dict['VARDEF_DB_VALUE_' + Pcd.DatumType] VariableRefTable = Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]
VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable]) VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable, Sku.VariableAttribute])
elif Sku.VpdOffset != '': elif Sku.VpdOffset != '':
Pcd.TokenTypeList += ['PCD_TYPE_VPD'] Pcd.TokenTypeList += ['PCD_TYPE_VPD']
@ -1600,6 +1629,9 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict)) AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))
if Platform.Platform.VarCheckFlag:
dest = os.path.join(Platform.BuildDir, 'FV')
VarCheckTab.dump(dest, Phase)
Buffer = BuildExDataBase(Dict) Buffer = BuildExDataBase(Dict)
return AutoGenH, AutoGenC, Buffer return AutoGenH, AutoGenC, Buffer

View File

@ -0,0 +1,351 @@
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
# This file is used to collect the Variable checking information
#
# #
# Import Modules
#
import os
from Common.RangeExpression import RangeExpression
from Common.Misc import *
from StringIO import StringIO
from struct import pack
class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):
def __init__(self):
self.var_check_info = []
def push_back(self, var_check_tab):
for tab in self.var_check_info:
if tab.equal(var_check_tab):
tab.merge(var_check_tab)
break
else:
self.var_check_info.append(var_check_tab)
def dump(self, dest, Phase):
FormatMap = {}
FormatMap[1] = "=B"
FormatMap[2] = "=H"
FormatMap[4] = "=L"
FormatMap[8] = "=Q"
if not os.path.isabs(dest):
return
if not os.path.exists(dest):
os.mkdir(dest)
BinFileName = "PcdVarCheck.bin"
BinFilePath = os.path.join(dest, BinFileName)
Buffer = ''
index = 0
for var_check_tab in self.var_check_info:
index += 1
realLength = 0
realLength += 32
Name = var_check_tab.Name[1:-1]
NameChars = Name.split(",")
realLength += len(NameChars)
if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
realLength += (4 - (realLength % 4))
itemIndex = 0
for item in var_check_tab.validtab:
itemIndex += 1
realLength += 5
for v_data in item.data:
if type(v_data) == type(1):
realLength += item.StorageWidth
else:
realLength += item.StorageWidth
realLength += item.StorageWidth
if (index == len(self.var_check_info)) :
if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
realLength += (4 - (realLength % 4))
else:
if realLength % 4:
realLength += (4 - (realLength % 4))
var_check_tab.Length = realLength
realLength = 0
index = 0
for var_check_tab in self.var_check_info:
index += 1
b = pack("=H", var_check_tab.Revision)
Buffer += b
realLength += 2
b = pack("=H", var_check_tab.HeaderLength)
Buffer += b
realLength += 2
b = pack("=L", var_check_tab.Length)
Buffer += b
realLength += 4
b = pack("=B", var_check_tab.Type)
Buffer += b
realLength += 1
for i in range(0, 3):
b = pack("=B", var_check_tab.Reserved)
Buffer += b
realLength += 1
b = pack("=L", var_check_tab.Attributes)
Buffer += b
realLength += 4
Guid = var_check_tab.Guid
b = pack('=LHHBBBBBBBB',
Guid[0],
Guid[1],
Guid[2],
Guid[3],
Guid[4],
Guid[5],
Guid[6],
Guid[7],
Guid[8],
Guid[9],
Guid[10],
)
Buffer += b
realLength += 16
Name = var_check_tab.Name[1:-1]
NameChars = Name.split(",")
for NameChar in NameChars:
NameCharNum = int(NameChar, 16)
b = pack("=B", NameCharNum)
Buffer += b
realLength += 1
if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
for i in range(4 - (realLength % 4)):
b = pack("=B", var_check_tab.pad)
Buffer += b
realLength += 1
itemIndex = 0
for item in var_check_tab.validtab:
itemIndex += 1
b = pack("=B", item.Type)
Buffer += b
realLength += 1
b = pack("=B", item.Length)
Buffer += b
realLength += 1
b = pack("=H", int(item.VarOffset, 16))
Buffer += b
realLength += 2
b = pack("=B", item.StorageWidth)
Buffer += b
realLength += 1
for v_data in item.data:
if type(v_data) == type(1):
b = pack(FormatMap[item.StorageWidth], v_data)
Buffer += b
realLength += item.StorageWidth
else:
b = pack(FormatMap[item.StorageWidth], v_data[0])
Buffer += b
realLength += item.StorageWidth
b = pack(FormatMap[item.StorageWidth], v_data[1])
Buffer += b
realLength += item.StorageWidth
if (index == len(self.var_check_info)) :
if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
for i in range(4 - (realLength % 4)):
b = pack("=B", var_check_tab.pad)
Buffer += b
realLength += 1
else:
if realLength % 4:
for i in range(4 - (realLength % 4)):
b = pack("=B", var_check_tab.pad)
Buffer += b
realLength += 1
DbFile = StringIO()
if Phase == 'DXE' and os.path.exists(BinFilePath):
BinFile = open(BinFilePath, "rb")
BinBuffer = BinFile.read()
BinFile.close()
BinBufferSize = len(BinBuffer)
if (BinBufferSize % 4):
for i in range(4 - (BinBufferSize % 4)):
b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad)
BinBuffer += b
Buffer = BinBuffer + Buffer
DbFile.write(Buffer)
SaveFileOnChange(BinFilePath, DbFile.getvalue(), True)
class VAR_CHECK_PCD_VARIABLE_TAB(object):
pad = 0xDA
def __init__(self, TokenSpaceGuid, PcdCName):
self.Revision = 0x0001
self.HeaderLength = 0
self.Length = 0 # Length include this header
self.Type = 0
self.Reserved = 0
self.Attributes = 0x00000000
self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]")
self.Name = PcdCName
self.validtab = []
def UpdateSize(self):
self.HeaderLength = 32 + len(self.Name.split(","))
self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen()
def GetValidTabLen(self):
validtablen = 0
for item in self.validtab:
validtablen += item.Length
return validtablen
def SetAttributes(self, attributes):
self.Attributes = attributes
def push_back(self, valid_obj):
if valid_obj is not None:
self.validtab.append(valid_obj)
def equal(self, varchecktab):
if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name:
return True
else:
return False
def merge(self, varchecktab):
for validobj in varchecktab.validtab:
if validobj in self.validtab:
continue
self.validtab.append(validobj)
self.UpdateSize()
class VAR_CHECK_PCD_VALID_OBJ(object):
def __init__(self, VarOffset, data, PcdDataType):
self.Type = 1
self.Length = 0 # Length include this header
self.VarOffset = VarOffset
self.StorageWidth = 0
self.PcdDataType = PcdDataType.strip()
self.rawdata = data
self.data = set()
self.ValidData = True
self.updateStorageWidth()
def updateStorageWidth(self):
if self.PcdDataType == "UINT8" or self.PcdDataType == "BOOLEAN":
self.StorageWidth = 1
elif self.PcdDataType == "UINT16":
self.StorageWidth = 2
elif self.PcdDataType == "UINT32":
self.StorageWidth = 4
elif self.PcdDataType == "UINT64":
self.StorageWidth = 8
else:
self.StorageWidth = 0
self.ValidData = False
def __eq__(self, validObj):
if self.VarOffset == validObj.VarOffset:
return True
else:
return False
class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ):
def __init__(self, VarOffset, validlist, PcdDataType):
super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType)
self.Type = 1
self.update_data()
self.update_size()
def update_data(self):
valid_num_list = []
data_list = []
for item in self.rawdata:
valid_num_list.extend(item.split(','))
for valid_num in valid_num_list:
valid_num = valid_num.strip()
if valid_num.startswith('0x') or valid_num.startswith('0X'):
data_list.append(int(valid_num, 16))
else:
data_list.append(int(valid_num))
self.data = set(data_list)
def update_size(self):
self.Length = 5 + len(self.data) * self.StorageWidth
class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ):
def __init__(self, VarOffset, validrange, PcdDataType):
super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType)
self.Type = 2
self.update_data()
self.update_size()
def update_data(self):
RangeExpr = ""
data_list = []
i = 0
for item in self.rawdata:
if i == 0:
RangeExpr = "( " + item + " )"
else:
RangeExpr = RangeExpr + "OR ( " + item + " )"
range_result = RangeExpression(RangeExpr, self.PcdDataType)(True)
for rangelist in range_result:
for obj in rangelist.pop():
data_list.append((obj.start, obj.end))
self.data = set(data_list)
def update_size(self):
self.Length = 5 + len(self.data) * 2 * self.StorageWidth
class VAR_VALID_OBJECT_FACTORY(object):
def __init__(self):
pass
@staticmethod
def Get_valid_object(PcdClass, VarOffset):
if PcdClass.validateranges:
return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType)
if PcdClass.validlists:
return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType)
else:
return None
if __name__ == "__main__":
class TestObj(object):
def __init__(self, number1):
self.number_1 = number1
def __eq__(self, testobj):
if self.number_1 == testobj.number_1:
return True
else:
return False
test1 = TestObj(1)
test2 = TestObj(2)
testarr = [test1, test2]
print TestObj(2) in testarr
print TestObj(2) == test2

View File

@ -1,7 +1,7 @@
## @file ## @file
# Standardized Error Hanlding infrastructures. # Standardized Error Hanlding infrastructures.
# #
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -81,6 +81,9 @@ EOT_ERROR = 0xF005
DDC_ERROR = 0xF009 DDC_ERROR = 0xF009
WARNING_AS_ERROR = 0xF006 WARNING_AS_ERROR = 0xF006
MIGRATION_ERROR = 0xF010 MIGRATION_ERROR = 0xF010
PCD_VALIDATION_INFO_ERROR = 0xF011
PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012
PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013
ABORT_ERROR = 0xFFFE ABORT_ERROR = 0xFFFE
UNKNOWN_ERROR = 0xFFFF UNKNOWN_ERROR = 0xFFFF

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define common static strings used by INF/DEC/DSC files # This file is used to define common static strings used by INF/DEC/DSC files
# #
# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR> # Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
@ -398,6 +398,7 @@ TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS' TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER' TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION' TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION'
TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION = 'PCD_VAR_CHECK_GENERATION'
TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION' TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER' TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME' TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'

View File

@ -1508,15 +1508,17 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
return [VpdOffset, Size, Value], IsValid, 2 return [VpdOffset, Size, Value], IsValid, 2
elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII): elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):
HiiString = FieldList[0] HiiString = FieldList[0]
Guid = Offset = Value = '' Guid = Offset = Value = Attribute = ''
if len(FieldList) > 1: if len(FieldList) > 1:
Guid = FieldList[1] Guid = FieldList[1]
if len(FieldList) > 2: if len(FieldList) > 2:
Offset = FieldList[2] Offset = FieldList[2]
if len(FieldList) > 3: if len(FieldList) > 3:
Value = FieldList[3] Value = FieldList[3]
IsValid = (3 <= len(FieldList) <= 4) if len(FieldList) > 4:
return [HiiString, Guid, Offset, Value], IsValid, 3 Attribute = FieldList[4]
IsValid = (3 <= len(FieldList) <= 5)
return [HiiString, Guid, Offset, Value, Attribute], IsValid, 3
return [], False, 0 return [], False, 0
## AnalyzePcdData ## AnalyzePcdData

View File

@ -0,0 +1,737 @@
# # @file
# This file is used to parse and evaluate range expression in Pcd declaration.
#
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
# # Import Modules
#
from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression
from CommonDataClass.Exceptions import WrnExpression
import uuid
ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'
ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'
ERR_MATCH = 'No matching right parenthesis.'
ERR_STRING_TOKEN = 'Bad string token: [%s].'
ERR_MACRO_TOKEN = 'Bad macro token: [%s].'
ERR_EMPTY_TOKEN = 'Empty token is not allowed.'
ERR_PCD_RESOLVE = 'PCD token cannot be resolved: [%s].'
ERR_VALID_TOKEN = 'No more valid token found from rest of string: [%s].'
ERR_EXPR_TYPE = 'Different types found in expression.'
ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]'
ERR_REL_NOT_IN = 'Expect "IN" after "not" operator.'
WRN_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'
WRN_EQCMP_STR_OTHERS = '== Comparison between Operand of string type and Boolean/Number Type always return False.'
WRN_NECMP_STR_OTHERS = '!= Comparison between Operand of string type and Boolean/Number Type always return True.'
ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Number Type is not allowed: [%s].'
ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'
ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'
ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'
ERR_EMPTY_EXPR = 'Empty expression is not allowed.'
ERR_IN_OPERAND = 'Macro after IN operator can only be: $(FAMILY), $(ARCH), $(TOOL_CHAIN_TAG) and $(TARGET).'
def MaxOfType(DataType):
if DataType == 'UINT8':
return int('0xFF', 16)
if DataType == 'UINT16':
return int('0xFFFF', 16)
if DataType == 'UINT32':
return int('0xFFFFFFFF', 16)
if DataType == 'UINT64':
return int('0xFFFFFFFFFFFFFFFF', 16)
class RangeObject(object):
def __init__(self, start, end, empty = False):
if int(start) < int(end):
self.start = int(start)
self.end = int(end)
else:
self.start = int(end)
self.end = int(start)
self.empty = empty
class RangeContainer(object):
def __init__(self):
self.rangelist = []
def push(self, RangeObject):
self.rangelist.append(RangeObject)
self.rangelist = sorted(self.rangelist, key = lambda rangeobj : rangeobj.start)
self.merge()
def pop(self):
for item in self.rangelist:
yield item
def __clean__(self):
newrangelist = []
for rangeobj in self.rangelist:
if rangeobj.empty == True:
continue
else:
newrangelist.append(rangeobj)
self.rangelist = newrangelist
def merge(self):
self.__clean__()
for i in range(0, len(self.rangelist) - 1):
if self.rangelist[i + 1].start > self.rangelist[i].end:
continue
else:
self.rangelist[i + 1].start = self.rangelist[i].start
self.rangelist[i + 1].end = self.rangelist[i + 1].end > self.rangelist[i].end and self.rangelist[i + 1].end or self.rangelist[i].end
self.rangelist[i].empty = True
self.__clean__()
def dump(self):
print "----------------------"
rangelist = ""
for object in self.rangelist:
rangelist = rangelist + "[%d , %d]" % (object.start, object.end)
print rangelist
class XOROperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "XOR ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(0, int(Operand) - 1))
rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))
SymbolTable[rangeId] = rangeContainer
return rangeId
class LEOperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "LE ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId1 = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(0, int(Operand)))
SymbolTable[rangeId1] = rangeContainer
return rangeId1
class LTOperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "LT ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId1 = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(0, int(Operand) - 1))
SymbolTable[rangeId1] = rangeContainer
return rangeId1
class GEOperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "GE ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId1 = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(int(Operand), MaxOfType(DataType)))
SymbolTable[rangeId1] = rangeContainer
return rangeId1
class GTOperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "GT ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId1 = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(int(Operand) + 1, MaxOfType(DataType)))
SymbolTable[rangeId1] = rangeContainer
return rangeId1
class EQOperatorObject(object):
def __init__(self):
pass
def Calculate(self, Operand, DataType, SymbolTable):
if type(Operand) == type('') and not Operand.isalnum():
Expr = "EQ ..."
raise BadExpression(ERR_SNYTAX % Expr)
rangeId1 = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(int(Operand) , int(Operand)))
SymbolTable[rangeId1] = rangeContainer
return rangeId1
def GetOperatorObject(Operator):
if Operator == '>':
return GTOperatorObject()
elif Operator == '>=':
return GEOperatorObject()
elif Operator == '<':
return LTOperatorObject()
elif Operator == '<=':
return LEOperatorObject()
elif Operator == '==':
return EQOperatorObject()
elif Operator == '^':
return XOROperatorObject()
else:
raise BadExpression("Bad Operator")
class RangeExpression(object):
# Logical operator mapping
LogicalOperators = {
'&&' : 'and', '||' : 'or',
'!' : 'not', 'AND': 'and',
'OR' : 'or' , 'NOT': 'not',
'XOR': '^' , 'xor': '^',
'EQ' : '==' , 'NE' : '!=',
'GT' : '>' , 'LT' : '<',
'GE' : '>=' , 'LE' : '<=',
'IN' : 'in'
}
NonLetterOpLst = ['+', '-', '&', '|', '^', '!', '=', '>', '<']
PcdPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*$')
HexPattern = re.compile(r'0[xX][0-9a-fA-F]+')
RegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')
ExRegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
SymbolPattern = re.compile("("
"\$\([A-Z][A-Z0-9_]*\)|\$\(\w+\.\w+\)|\w+\.\w+|"
"&&|\|\||!(?!=)|"
"(?<=\W)AND(?=\W)|(?<=\W)OR(?=\W)|(?<=\W)NOT(?=\W)|(?<=\W)XOR(?=\W)|"
"(?<=\W)EQ(?=\W)|(?<=\W)NE(?=\W)|(?<=\W)GT(?=\W)|(?<=\W)LT(?=\W)|(?<=\W)GE(?=\W)|(?<=\W)LE(?=\W)"
")")
RangePattern = re.compile(r'[0-9]+ - [0-9]+')
def preProcessRangeExpr(self, expr):
# convert hex to int
# convert interval to object index. ex. 1 - 10 to a GUID
expr = expr.strip()
NumberDict = {}
for HexNumber in self.HexPattern.findall(expr):
Number = str(int(HexNumber, 16))
NumberDict[HexNumber] = Number
for HexNum in NumberDict:
expr = expr.replace(HexNum, NumberDict[HexNum])
rangedict = {}
for validrange in self.RangePattern.findall(expr):
start, end = validrange.split(" - ")
start = start.strip()
end = end.strip()
rangeid = str(uuid.uuid1())
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(start, end))
self.operanddict[str(rangeid)] = rangeContainer
rangedict[validrange] = str(rangeid)
for validrange in rangedict:
expr = expr.replace(validrange, rangedict[validrange])
self._Expr = expr
return expr
def EvalRange(self, Operator, Oprand):
operatorobj = GetOperatorObject(Operator)
return operatorobj.Calculate(Oprand, self.PcdDataType, self.operanddict)
def Rangeintersection(self, Oprand1, Oprand2):
rangeContainer1 = self.operanddict[Oprand1]
rangeContainer2 = self.operanddict[Oprand2]
rangeContainer = RangeContainer()
for range1 in rangeContainer1.pop():
for range2 in rangeContainer2.pop():
if range1.start >= range2.start:
start = range1.start
end = range1.end
range1.start = range2.start
range1.end = range2.end
range2.start = start
range2.end = end
if range1.empty:
rangeid = str(uuid.uuid1())
rangeContainer.push(RangeObject(0, 0, True))
if range1.end < range2.start:
rangeid = str(uuid.uuid1())
rangeContainer.push(RangeObject(0, 0, True))
elif range1.end == range2.start:
rangeid = str(uuid.uuid1())
rangeContainer.push(RangeObject(range1.end, range1.end))
elif range1.end <= range2.end and range1.end > range2.start:
rangeid = str(uuid.uuid1())
rangeContainer.push(RangeObject(range2.start, range1.end))
elif range1.end >= range2.end:
rangeid = str(uuid.uuid1())
rangeContainer.push(RangeObject(range2.start, range2.end))
self.operanddict[rangeid] = rangeContainer
# rangeContainer.dump()
return rangeid
def Rangecollections(self, Oprand1, Oprand2):
rangeContainer1 = self.operanddict[Oprand1]
rangeContainer2 = self.operanddict[Oprand2]
rangeContainer = RangeContainer()
for rangeobj in rangeContainer2.pop():
rangeContainer.push(rangeobj)
for rangeobj in rangeContainer1.pop():
rangeContainer.push(rangeobj)
rangeid = str(uuid.uuid1())
self.operanddict[rangeid] = rangeContainer
# rangeContainer.dump()
return rangeid
def NegtiveRange(self, Oprand1):
rangeContainer1 = self.operanddict[Oprand1]
rangeids = []
for rangeobj in rangeContainer1.pop():
rangeContainer = RangeContainer()
rangeid = str(uuid.uuid1())
if rangeobj.empty:
rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))
else:
if rangeobj.start > 0:
rangeContainer.push(RangeObject(0, rangeobj.start - 1))
if rangeobj.end < MaxOfType(self.PcdDataType):
rangeContainer.push(RangeObject(rangeobj.end + 1, MaxOfType(self.PcdDataType)))
self.operanddict[rangeid] = rangeContainer
rangeids.append(rangeid)
if len(rangeids) == 0:
rangeContainer = RangeContainer()
rangeContainer.push(RangeObject(0, MaxOfType(self.PcdDataType)))
rangeid = str(uuid.uuid1())
self.operanddict[rangeid] = rangeContainer
return rangeid
if len(rangeids) == 1:
return rangeids[0]
re = self.Rangeintersection(rangeids[0], rangeids[1])
for i in range(2, len(rangeids)):
re = self.Rangeintersection(re, rangeids[i])
rangeid2 = str(uuid.uuid1())
self.operanddict[rangeid2] = self.operanddict[re]
return rangeid2
def Eval(self, Operator, Oprand1, Oprand2 = None):
if Operator in ["!", "NOT", "not"]:
if not self.RegGuidPattern.match(Oprand1.strip()):
raise BadExpression(ERR_STRING_EXPR % Operator)
return self.NegtiveRange(Oprand1)
else:
if Operator in ["==", ">=", "<=", ">", "<", '^']:
return self.EvalRange(Operator, Oprand1)
elif Operator == 'and' :
if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):
raise BadExpression(ERR_STRING_EXPR % Operator)
return self.Rangeintersection(Oprand1, Oprand2)
elif Operator == 'or':
if not self.ExRegGuidPattern.match(Oprand1.strip()) or not self.ExRegGuidPattern.match(Oprand2.strip()):
raise BadExpression(ERR_STRING_EXPR % Operator)
return self.Rangecollections(Oprand1, Oprand2)
else:
raise BadExpression(ERR_STRING_EXPR % Operator)
def __init__(self, Expression, PcdDataType, SymbolTable = {}):
self._NoProcess = False
if type(Expression) != type(''):
self._Expr = Expression
self._NoProcess = True
return
self._Expr = Expression.strip()
if not self._Expr.strip():
raise BadExpression(ERR_EMPTY_EXPR)
#
# The symbol table including PCD and macro mapping
#
self._Symb = SymbolTable
self._Symb.update(self.LogicalOperators)
self._Idx = 0
self._Len = len(self._Expr)
self._Token = ''
self._WarnExcept = None
# Literal token without any conversion
self._LiteralToken = ''
# store the operand object
self.operanddict = {}
# The Pcd max value depends on PcdDataType
self.PcdDataType = PcdDataType
# Public entry for this class
# @param RealValue: False: only evaluate if the expression is true or false, used for conditional expression
# True : return the evaluated str(value), used for PCD value
#
# @return: True or False if RealValue is False
# Evaluated value of string format if RealValue is True
#
def __call__(self, RealValue = False, Depth = 0):
if self._NoProcess:
return self._Expr
self._Depth = Depth
self._Expr = self._Expr.strip()
self.preProcessRangeExpr(self._Expr)
# check if the expression does not need to evaluate
if RealValue and Depth == 0:
self._Token = self._Expr
if self.ExRegGuidPattern.match(self._Expr):
return [self.operanddict[self._Expr] ]
self._Idx = 0
self._Token = ''
Val = self._OrExpr()
RealVal = Val
RangeIdList = RealVal.split("or")
RangeList = []
for rangeid in RangeIdList:
RangeList.append(self.operanddict[rangeid.strip()])
return RangeList
# Template function to parse binary operators which have same precedence
# Expr [Operator Expr]*
def _ExprFuncTemplate(self, EvalFunc, OpLst):
Val = EvalFunc()
while self._IsOperator(OpLst):
Op = self._Token
try:
Val = self.Eval(Op, Val, EvalFunc())
except WrnExpression, Warn:
self._WarnExcept = Warn
Val = Warn.result
return Val
# A [|| B]*
def _OrExpr(self):
return self._ExprFuncTemplate(self._AndExpr, ["OR", "or"])
# A [&& B]*
def _AndExpr(self):
return self._ExprFuncTemplate(self._NeExpr, ["AND", "and"])
def _NeExpr(self):
Val = self._RelExpr()
while self._IsOperator([ "!=", "NOT", "not"]):
Op = self._Token
if Op in ["!", "NOT", "not"]:
if not self._IsOperator(["IN", "in"]):
raise BadExpression(ERR_REL_NOT_IN)
Op += ' ' + self._Token
try:
Val = self.Eval(Op, Val, self._RelExpr())
except WrnExpression, Warn:
self._WarnExcept = Warn
Val = Warn.result
return Val
# [!]*A
def _RelExpr(self):
if self._IsOperator(["NOT" , "LE", "GE", "LT", "GT", "EQ", "XOR"]):
Token = self._Token
Val = self._NeExpr()
try:
return self.Eval(Token, Val)
except WrnExpression, Warn:
self._WarnExcept = Warn
return Warn.result
return self._IdenExpr()
# Parse identifier or encapsulated expression
def _IdenExpr(self):
Tk = self._GetToken()
if Tk == '(':
Val = self._OrExpr()
try:
# _GetToken may also raise BadExpression
if self._GetToken() != ')':
raise BadExpression(ERR_MATCH)
except BadExpression:
raise BadExpression(ERR_MATCH)
return Val
return Tk
# Skip whitespace or tab
def __SkipWS(self):
for Char in self._Expr[self._Idx:]:
if Char not in ' \t':
break
self._Idx += 1
# Try to convert string to number
def __IsNumberToken(self):
Radix = 10
if self._Token.lower()[0:2] == '0x' and len(self._Token) > 2:
Radix = 16
try:
self._Token = int(self._Token, Radix)
return True
except ValueError:
return False
except TypeError:
return False
# Parse array: {...}
def __GetArray(self):
Token = '{'
self._Idx += 1
self.__GetNList(True)
Token += self._LiteralToken
if self._Idx >= self._Len or self._Expr[self._Idx] != '}':
raise BadExpression(ERR_ARRAY_TOKEN % Token)
Token += '}'
# All whitespace and tabs in array are already stripped.
IsArray = IsGuid = False
if len(Token.split(',')) == 11 and len(Token.split(',{')) == 2 \
and len(Token.split('},')) == 1:
HexLen = [11, 6, 6, 5, 4, 4, 4, 4, 4, 4, 6]
HexList = Token.split(',')
if HexList[3].startswith('{') and \
not [Index for Index, Hex in enumerate(HexList) if len(Hex) > HexLen[Index]]:
IsGuid = True
if Token.lstrip('{').rstrip('}').find('{') == -1:
if not [Hex for Hex in Token.lstrip('{').rstrip('}').split(',') if len(Hex) > 4]:
IsArray = True
if not IsArray and not IsGuid:
raise BadExpression(ERR_ARRAY_TOKEN % Token)
self._Idx += 1
self._Token = self._LiteralToken = Token
return self._Token
# Parse string, the format must be: "..."
def __GetString(self):
Idx = self._Idx
# Skip left quote
self._Idx += 1
# Replace escape \\\", \"
Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace('\\\"', '\\\'')
for Ch in Expr:
self._Idx += 1
if Ch == '"':
break
self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]
if not self._Token.endswith('"'):
raise BadExpression(ERR_STRING_TOKEN % self._Token)
self._Token = self._Token[1:-1]
return self._Token
# Get token that is comprised by alphanumeric, underscore or dot(used by PCD)
# @param IsAlphaOp: Indicate if parsing general token or script operator(EQ, NE...)
def __GetIdToken(self, IsAlphaOp = False):
IdToken = ''
for Ch in self._Expr[self._Idx:]:
if not self.__IsIdChar(Ch):
break
self._Idx += 1
IdToken += Ch
self._Token = self._LiteralToken = IdToken
if not IsAlphaOp:
self.__ResolveToken()
return self._Token
# Try to resolve token
def __ResolveToken(self):
if not self._Token:
raise BadExpression(ERR_EMPTY_TOKEN)
# PCD token
if self.PcdPattern.match(self._Token):
if self._Token not in self._Symb:
Ex = BadExpression(ERR_PCD_RESOLVE % self._Token)
Ex.Pcd = self._Token
raise Ex
self._Token = RangeExpression(self._Symb[self._Token], self._Symb)(True, self._Depth + 1)
if type(self._Token) != type(''):
self._LiteralToken = hex(self._Token)
return
if self._Token.startswith('"'):
self._Token = self._Token[1:-1]
elif self._Token in ["FALSE", "false", "False"]:
self._Token = False
elif self._Token in ["TRUE", "true", "True"]:
self._Token = True
else:
self.__IsNumberToken()
def __GetNList(self, InArray = False):
self._GetSingleToken()
if not self.__IsHexLiteral():
if InArray:
raise BadExpression(ERR_ARRAY_ELE % self._Token)
return self._Token
self.__SkipWS()
Expr = self._Expr[self._Idx:]
if not Expr.startswith(','):
return self._Token
NList = self._LiteralToken
while Expr.startswith(','):
NList += ','
self._Idx += 1
self.__SkipWS()
self._GetSingleToken()
if not self.__IsHexLiteral():
raise BadExpression(ERR_ARRAY_ELE % self._Token)
NList += self._LiteralToken
self.__SkipWS()
Expr = self._Expr[self._Idx:]
self._Token = self._LiteralToken = NList
return self._Token
def __IsHexLiteral(self):
if self._LiteralToken.startswith('{') and \
self._LiteralToken.endswith('}'):
return True
if self.HexPattern.match(self._LiteralToken):
Token = self._LiteralToken[2:]
Token = Token.lstrip('0')
if not Token:
self._LiteralToken = '0x0'
else:
self._LiteralToken = '0x' + Token.lower()
return True
return False
def _GetToken(self):
return self.__GetNList()
@staticmethod
def __IsIdChar(Ch):
return Ch in '._/:' or Ch.isalnum()
# Parse operand
def _GetSingleToken(self):
self.__SkipWS()
Expr = self._Expr[self._Idx:]
if Expr.startswith('L"'):
# Skip L
self._Idx += 1
UStr = self.__GetString()
self._Token = 'L"' + UStr + '"'
return self._Token
self._Token = ''
if Expr:
Ch = Expr[0]
Match = self.RegGuidPattern.match(Expr)
if Match and not Expr[Match.end():Match.end() + 1].isalnum() \
and Expr[Match.end():Match.end() + 1] != '_':
self._Idx += Match.end()
self._Token = Expr[0:Match.end()]
return self._Token
elif self.__IsIdChar(Ch):
return self.__GetIdToken()
elif Ch == '(' or Ch == ')':
self._Idx += 1
self._Token = Ch
return self._Token
raise BadExpression(ERR_VALID_TOKEN % Expr)
# Parse operator
def _GetOperator(self):
self.__SkipWS()
LegalOpLst = ['&&', '||', '!=', '==', '>=', '<='] + self.NonLetterOpLst
self._Token = ''
Expr = self._Expr[self._Idx:]
# Reach end of expression
if not Expr:
return ''
# Script operator: LT, GT, LE, GE, EQ, NE, and, or, xor, not
if Expr[0].isalpha():
return self.__GetIdToken(True)
# Start to get regular operator: +, -, <, > ...
if Expr[0] not in self.NonLetterOpLst:
return ''
OpToken = ''
for Ch in Expr:
if Ch in self.NonLetterOpLst:
if '!' == Ch and OpToken:
break
self._Idx += 1
OpToken += Ch
else:
break
if OpToken not in LegalOpLst:
raise BadExpression(ERR_OPERATOR_UNSUPPORT % OpToken)
self._Token = OpToken
return OpToken
# Check if current token matches the operators given from OpList
def _IsOperator(self, OpList):
Idx = self._Idx
self._GetOperator()
if self._Token in OpList:
if self._Token in self.LogicalOperators:
self._Token = self.LogicalOperators[self._Token]
return True
self._Idx = Idx
return False
# UTRangeList()

View File

@ -0,0 +1,57 @@
# # @file
#
# This file is used to handle the variable attributes and property information
#
#
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
class VariableAttributes(object):
EFI_VARIABLE_NON_VOLATILE = 0x00000001
EFI_VARIABLE_BOOTSERVICE_ACCESS = 0x00000002
EFI_VARIABLE_RUNTIME_ACCESS = 0x00000004
VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY = 0x00000001
VarAttributesMap = {
"NV":EFI_VARIABLE_NON_VOLATILE,
"BS":EFI_VARIABLE_BOOTSERVICE_ACCESS,
"RT":EFI_VARIABLE_RUNTIME_ACCESS,
"RO":VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
}
def __init__(self):
pass
@staticmethod
def GetVarAttributes(var_attr_str):
VarAttr = 0x00000000
VarProp = 0x00000000
attr_list = var_attr_str.split(",")
for attr in attr_list:
attr = attr.strip()
if attr == 'RO':
VarProp = VariableAttributes.VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
else:
VarAttr = VarAttr | VariableAttributes.VarAttributesMap.get(attr, 0x00000000)
return VarAttr, VarProp
@staticmethod
def ValidateVarAttributes(var_attr_str):
if not var_attr_str:
return True, ""
attr_list = var_attr_str.split(",")
attr_temp = []
for attr in attr_list:
attr = attr.strip()
attr_temp.append(attr)
if attr not in VariableAttributes.VarAttributesMap:
return False, "The variable attribute %s is not support to be specified in dsc file. Supported variable attribute are ['BS','NV','RT','RO'] "
if 'RT' in attr_temp and 'BS' not in attr_temp:
return False, "the RT attribute need the BS attribute to be present"
return True, ""

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define common items of class object # This file is used to define common items of class object
# #
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -270,7 +270,7 @@ class PpiClass(GuidProtocolPpiCommonClass):
# #
class SkuInfoClass(object): class SkuInfoClass(object):
def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '',
HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = ''): HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = '', VariableAttribute = ''):
self.SkuIdName = SkuIdName self.SkuIdName = SkuIdName
self.SkuId = SkuId self.SkuId = SkuId
@ -282,6 +282,7 @@ class SkuInfoClass(object):
self.VariableGuidValue = VariableGuidValue self.VariableGuidValue = VariableGuidValue
self.VariableOffset = VariableOffset self.VariableOffset = VariableOffset
self.HiiDefaultValue = HiiDefaultValue self.HiiDefaultValue = HiiDefaultValue
self.VariableAttribute = VariableAttribute
# #
# Used by Vpd # Used by Vpd

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to define each component of the build database # This file is used to define each component of the build database
# #
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -44,7 +44,7 @@ from Common.BuildToolError import *
# @var Phase: To store value for Phase, default is "DXE" # @var Phase: To store value for Phase, default is "DXE"
# #
class PcdClassObject(object): class PcdClassObject(object):
def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False, GuidValue = None): def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False, GuidValue = None, validateranges = [], validlists = [], expressions = []):
self.TokenCName = Name self.TokenCName = Name
self.TokenSpaceGuidCName = Guid self.TokenSpaceGuidCName = Guid
self.TokenSpaceGuidValue = GuidValue self.TokenSpaceGuidValue = GuidValue
@ -59,6 +59,9 @@ class PcdClassObject(object):
self.IsOverrided = IsOverrided self.IsOverrided = IsOverrided
self.IsFromBinaryInf = False self.IsFromBinaryInf = False
self.IsFromDsc = False self.IsFromDsc = False
self.validateranges = validateranges
self.validlists = validlists
self.expressions = expressions
## Convert the class to a string ## Convert the class to a string
# #

View File

@ -376,7 +376,8 @@ class MetaFileParser(object):
File=self.MetaFile, File=self.MetaFile,
Line=self._LineIndex + 1 Line=self._LineIndex + 1
) )
def GetValidExpression(self, TokenSpaceGuid, PcdCName):
return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)
def _GetMacros(self): def _GetMacros(self):
Macros = {} Macros = {}
Macros.update(self._FileLocalMacros) Macros.update(self._FileLocalMacros)
@ -814,6 +815,7 @@ class DscParser(MetaFileParser):
"PLATFORM_VERSION", "PLATFORM_VERSION",
"SKUID_IDENTIFIER", "SKUID_IDENTIFIER",
"PCD_INFO_GENERATION", "PCD_INFO_GENERATION",
"PCD_VAR_CHECK_GENERATION",
"SUPPORTED_ARCHITECTURES", "SUPPORTED_ARCHITECTURES",
"BUILD_TARGETS", "BUILD_TARGETS",
"OUTPUT_DIRECTORY", "OUTPUT_DIRECTORY",

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to create/update/query/erase a meta file table # This file is used to create/update/query/erase a meta file table
# #
# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -225,6 +225,26 @@ class PackageTable(MetaFileTable):
SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
return self.Exec(SqlCommand) return self.Exec(SqlCommand)
def GetValidExpression(self, TokenSpaceGuid, PcdCName):
SqlCommand = "select Value1 from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName)
self.Cur.execute(SqlCommand)
validateranges = []
validlists = []
expressions = []
for row in self.Cur:
comment = row[0]
comment = comment.strip("#")
comment = comment.strip()
if comment.startswith("@ValidRange"):
comment = comment.replace("@ValidRange", "", 1)
validateranges.append(comment.split("|")[1].strip())
if comment.startswith("@ValidList"):
comment = comment.replace("@ValidList", "", 1)
validlists.append(comment.split("|")[1].strip())
if comment.startswith("@Expression"):
comment = comment.replace("@Expression", "", 1)
expressions.append(comment.split("|")[1].strip())
return set(validateranges), set(validlists), set(expressions)
## Python class representation of table storing platform data ## Python class representation of table storing platform data
class PlatformTable(MetaFileTable): class PlatformTable(MetaFileTable):
_COLUMN_ = ''' _COLUMN_ = '''

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to create a database used by build tool # This file is used to create a database used by build tool
# #
# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -38,7 +38,7 @@ from Common.Misc import AnalyzeDscPcd
from Common.Misc import ProcessDuplicatedInf from Common.Misc import ProcessDuplicatedInf
import re import re
from Common.Parsing import IsValidWord from Common.Parsing import IsValidWord
from Common.VariableAttributes import VariableAttributes
import Common.GlobalData as GlobalData import Common.GlobalData as GlobalData
## Platform build information from DSC file ## Platform build information from DSC file
@ -133,6 +133,7 @@ class DscBuildData(PlatformBuildClassObject):
self._SkuName = None self._SkuName = None
self._SkuIdentifier = None self._SkuIdentifier = None
self._PcdInfoFlag = None self._PcdInfoFlag = None
self._VarCheckFlag = None
self._FlashDefinition = None self._FlashDefinition = None
self._BuildNumber = None self._BuildNumber = None
self._MakefileName = None self._MakefileName = None
@ -233,6 +234,8 @@ class DscBuildData(PlatformBuildClassObject):
self._SkuIdentifier = Record[2] self._SkuIdentifier = Record[2]
elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION: elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
self._PcdInfoFlag = Record[2] self._PcdInfoFlag = Record[2]
elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
self._VarCheckFlag = Record[2]
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS: elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
try: try:
self._LoadFixAddress = int (Record[2], 0) self._LoadFixAddress = int (Record[2], 0)
@ -352,6 +355,13 @@ class DscBuildData(PlatformBuildClassObject):
return True return True
else: else:
return False return False
def _GetVarCheckFlag(self):
if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':
return False
elif self._VarCheckFlag.upper() == 'TRUE':
return True
else:
return False
def _GetSkuIdentifier(self): def _GetSkuIdentifier(self):
if self._SkuName: if self._SkuName:
@ -898,6 +908,17 @@ class DscBuildData(PlatformBuildClassObject):
return Pcds return Pcds
def CompareVarAttr(self, Attr1, Attr2):
if not Attr1 or not Attr2: # for empty string
return True
Attr1s = [attr.strip() for attr in Attr1.split(",")]
Attr1Set = set(Attr1s)
Attr2s = [attr.strip() for attr in Attr2.split(",")]
Attr2Set = set(Attr2s)
if Attr2Set == Attr1Set:
return True
else:
return False
## Retrieve dynamic HII PCD settings ## Retrieve dynamic HII PCD settings
# #
# @param Type PCD type # @param Type PCD type
@ -907,6 +928,7 @@ class DscBuildData(PlatformBuildClassObject):
def _GetDynamicHiiPcd(self, Type): def _GetDynamicHiiPcd(self, Type):
SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds) SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
VariableAttrs = {}
Pcds = sdict() Pcds = sdict()
# #
@ -931,8 +953,12 @@ class DscBuildData(PlatformBuildClassObject):
Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None: if Setting == None:
continue continue
VariableName, VariableGuid, VariableOffset, DefaultValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
if not rt:
EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
ExtraData = "[%s]" % VarAttribute)
ExceedMax = False ExceedMax = False
FormatCorrect = True FormatCorrect = True
if VariableOffset.isdigit(): if VariableOffset.isdigit():
@ -955,8 +981,14 @@ class DscBuildData(PlatformBuildClassObject):
if ExceedMax: if ExceedMax:
EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName))) EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))
if (VariableName, VariableGuid) not in VariableAttrs:
VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
else:
if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue) SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)
pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
if (PcdCName,TokenSpaceGuid) in Pcds.keys(): if (PcdCName,TokenSpaceGuid) in Pcds.keys():
pcdObject = Pcds[PcdCName,TokenSpaceGuid] pcdObject = Pcds[PcdCName,TokenSpaceGuid]
pcdObject.SkuInfoList[SkuName] = SkuInfo pcdObject.SkuInfoList[SkuName] = SkuInfo
@ -971,7 +1003,10 @@ class DscBuildData(PlatformBuildClassObject):
'', '',
{SkuName : SkuInfo}, {SkuName : SkuInfo},
False, False,
None None,
pcdDecObject.validateranges,
pcdDecObject.validlists,
pcdDecObject.expressions
) )
@ -1143,6 +1178,7 @@ class DscBuildData(PlatformBuildClassObject):
SkuName = property(_GetSkuName, _SetSkuName) SkuName = property(_GetSkuName, _SetSkuName)
SkuIdentifier = property(_GetSkuIdentifier) SkuIdentifier = property(_GetSkuIdentifier)
PcdInfoFlag = property(_GetPcdInfoFlag) PcdInfoFlag = property(_GetPcdInfoFlag)
VarCheckFlag = property(_GetVarCheckFlag)
FlashDefinition = property(_GetFdfFile) FlashDefinition = property(_GetFdfFile)
BuildNumber = property(_GetBuildNumber) BuildNumber = property(_GetBuildNumber)
MakefileName = property(_GetMakefileName) MakefileName = property(_GetMakefileName)
@ -1462,6 +1498,7 @@ class DecBuildData(PackageBuildClassObject):
DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting) DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject( Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(
PcdCName, PcdCName,
TokenSpaceGuid, TokenSpaceGuid,
@ -1472,7 +1509,10 @@ class DecBuildData(PackageBuildClassObject):
'', '',
{}, {},
False, False,
None None,
list(validateranges),
list(validlists),
list(expressions)
) )
return Pcds return Pcds