mirror of https://github.com/acidanthera/audk.git
BaseTools: Collect DynamicHii PCD values and assign it to VPD PCD Value
https://bugzilla.tianocore.org/show_bug.cgi?id=661 Collect all DynamicHii and DynamicExHii PCD value into PCD PcdNvStoreDefaultValueBuffer, then firmware can access this PCD value to get the variable default setting. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Feng Bob C <bob.c.feng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
parent
ae7b6df816
commit
34952f493c
|
@ -44,6 +44,7 @@ from Common.MultipleWorkspace import MultipleWorkspace as mws
|
|||
import InfSectionParser
|
||||
import datetime
|
||||
import hashlib
|
||||
from GenVar import Variable,var_info
|
||||
|
||||
## Regular expression for splitting Dependency Expression string into tokens
|
||||
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
|
||||
|
@ -1352,6 +1353,26 @@ class PlatformAutoGen(AutoGen):
|
|||
if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]:
|
||||
LibAuto.ConstPcd[key] = Pcd.DefaultValue
|
||||
|
||||
def CollectVariables(self, DynamicPcdSet):
|
||||
VariableInfo = Variable()
|
||||
Index = 0
|
||||
for Pcd in DynamicPcdSet:
|
||||
if not hasattr(Pcd,"DefaultStoreName"):
|
||||
Pcd.DefaultStoreName = ['0']
|
||||
for StorageName in Pcd.DefaultStoreName:
|
||||
pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
|
||||
for SkuName in Pcd.SkuInfoList:
|
||||
Sku = Pcd.SkuInfoList[SkuName]
|
||||
SkuId = Sku.SkuId
|
||||
if SkuId == None or SkuId == '':
|
||||
continue
|
||||
if len(Sku.VariableName) > 0:
|
||||
VariableGuidStructure = Sku.VariableGuidValue
|
||||
VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure)
|
||||
if Pcd.Phase == "DXE":
|
||||
VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuId, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Pcd.DefaultValue,Sku.HiiDefaultValue,Pcd.DatumType))
|
||||
Index += 1
|
||||
return VariableInfo
|
||||
## Collect dynamic PCDs
|
||||
#
|
||||
# Gather dynamic PCDs list from each module and their settings from platform
|
||||
|
@ -1582,6 +1603,17 @@ class PlatformAutoGen(AutoGen):
|
|||
if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
|
||||
VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
|
||||
|
||||
#Collect DynamicHii PCD values and assign it to DynamicExVpd PCD gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer
|
||||
PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid"))
|
||||
if PcdNvStoreDfBuffer:
|
||||
var_info = self.CollectVariables(self._DynamicPcdList)
|
||||
default_skuobj = PcdNvStoreDfBuffer.SkuInfoList.get("DEFAULT")
|
||||
default_skuobj.DefaultValue = var_info.dump()
|
||||
if default_skuobj:
|
||||
PcdNvStoreDfBuffer.SkuInfoList.clear()
|
||||
PcdNvStoreDfBuffer.SkuInfoList['DEFAULT'] = default_skuobj
|
||||
PcdNvStoreDfBuffer.MaxDatumSize = len(default_skuobj.DefaultValue.split(","))
|
||||
|
||||
PlatformPcds = self._PlatformPcds.keys()
|
||||
PlatformPcds.sort()
|
||||
#
|
||||
|
|
|
@ -628,31 +628,6 @@ def GetMatchedIndex(Key1, List1, Key2, List2):
|
|||
return -1
|
||||
|
||||
|
||||
## Get the integer value from string like "14U" or integer like 2
|
||||
#
|
||||
# @param Input The object that may be either a integer value or a string
|
||||
#
|
||||
# @retval Value The integer value that the input represents
|
||||
#
|
||||
def GetIntegerValue(Input):
|
||||
if type(Input) in (int, long):
|
||||
return Input
|
||||
String = Input
|
||||
if String.endswith("U"):
|
||||
String = String[:-1]
|
||||
if String.endswith("ULL"):
|
||||
String = String[:-3]
|
||||
if String.endswith("LL"):
|
||||
String = String[:-2]
|
||||
|
||||
if String.startswith("0x") or String.startswith("0X"):
|
||||
return int(String, 16)
|
||||
elif String == '':
|
||||
return 0
|
||||
else:
|
||||
return int(String)
|
||||
|
||||
|
||||
## convert StringArray like {0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00}
|
||||
# to List like [0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00]
|
||||
#
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
# Copyright (c) 2017, 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
|
||||
#
|
||||
from struct import pack,unpack
|
||||
import collections
|
||||
import copy
|
||||
from Common.VariableAttributes import VariableAttributes
|
||||
from Common.Misc import *
|
||||
import collections
|
||||
|
||||
var_info = collections.namedtuple("uefi_var", "pcdindex,pcdname,defaultstoragename,skuname,var_name, var_guid, var_attribute,pcd_default_value, default_value, data_type")
|
||||
NvStorageHeaderSize = 28
|
||||
VariableHeaderSize = 32
|
||||
|
||||
def StringArrayToList(StringArray):
|
||||
StringArray = StringArray[1:-1]
|
||||
StringArray = '[' + StringArray + ']'
|
||||
return eval(StringArray)
|
||||
|
||||
def PackGUID(Guid):
|
||||
GuidBuffer = pack('=LHHBBBBBBBB',
|
||||
int(Guid[0], 16),
|
||||
int(Guid[1], 16),
|
||||
int(Guid[2], 16),
|
||||
int(Guid[3][-4:-2], 16),
|
||||
int(Guid[3][-2:], 16),
|
||||
int(Guid[4][-12:-10], 16),
|
||||
int(Guid[4][-10:-8], 16),
|
||||
int(Guid[4][-8:-6], 16),
|
||||
int(Guid[4][-6:-4], 16),
|
||||
int(Guid[4][-4:-2], 16),
|
||||
int(Guid[4][-2:], 16)
|
||||
)
|
||||
return GuidBuffer
|
||||
|
||||
class Variable(object):
|
||||
def __init__(self,):
|
||||
self.VarInfo = []
|
||||
|
||||
def append_variable(self,uefi_var):
|
||||
self.VarInfo.append(uefi_var)
|
||||
|
||||
def process_variable_data(self):
|
||||
|
||||
var_data = dict()
|
||||
|
||||
indexedvarinfo = collections.OrderedDict()
|
||||
for item in self.VarInfo:
|
||||
if item.pcdindex not in indexedvarinfo:
|
||||
indexedvarinfo[item.pcdindex] = dict()
|
||||
indexedvarinfo[item.pcdindex][(int(item.skuname),int(item.defaultstoragename))] = item
|
||||
|
||||
for index in indexedvarinfo:
|
||||
sku_var_info = indexedvarinfo[index]
|
||||
|
||||
default_data_buffer = ""
|
||||
others_data_buffer = ""
|
||||
tail = None
|
||||
default_sku_default = indexedvarinfo.get(index).get((0,0))
|
||||
|
||||
if default_sku_default.data_type not in ["UINT8","UINT16","UINT32","UINT64","BOOLEAN"]:
|
||||
var_max_len = max([len(var_item.default_value.split(",")) for var_item in sku_var_info.values()])
|
||||
if len(default_sku_default.default_value.split(",")) < var_max_len:
|
||||
tail = ",".join([ "0x00" for i in range(var_max_len-len(default_sku_default.default_value.split(",")))])
|
||||
|
||||
default_data_buffer = self.PACK_VARIABLES_DATA(default_sku_default.default_value,default_sku_default.data_type,tail)
|
||||
|
||||
default_data_array = ()
|
||||
for item in default_data_buffer:
|
||||
default_data_array += unpack("B",item)
|
||||
|
||||
if (0,0) not in var_data:
|
||||
var_data[(0,0)] = collections.OrderedDict()
|
||||
var_data[(0,0)][index] = (default_data_buffer,sku_var_info[(0,0)])
|
||||
|
||||
for (skuid,defaultstoragename) in indexedvarinfo.get(index):
|
||||
tail = None
|
||||
if (skuid,defaultstoragename) == (0,0):
|
||||
continue
|
||||
other_sku_other = indexedvarinfo.get(index).get((skuid,defaultstoragename))
|
||||
|
||||
if default_sku_default.data_type not in ["UINT8","UINT16","UINT32","UINT64","BOOLEAN"]:
|
||||
if len(other_sku_other.default_value.split(",")) < var_max_len:
|
||||
tail = ",".join([ "0x00" for i in range(var_max_len-len(other_sku_other.default_value.split(",")))])
|
||||
|
||||
others_data_buffer = self.PACK_VARIABLES_DATA(other_sku_other.default_value,other_sku_other.data_type,tail)
|
||||
|
||||
others_data_array = ()
|
||||
for item in others_data_buffer:
|
||||
others_data_array += unpack("B",item)
|
||||
|
||||
data_delta = self.calculate_delta(default_data_array, others_data_array)
|
||||
|
||||
if (skuid,defaultstoragename) not in var_data:
|
||||
var_data[(skuid,defaultstoragename)] = collections.OrderedDict()
|
||||
var_data[(skuid,defaultstoragename)][index] = (data_delta,sku_var_info[(skuid,defaultstoragename)])
|
||||
return var_data
|
||||
|
||||
def new_process_varinfo(self):
|
||||
|
||||
var_data = self.process_variable_data()
|
||||
|
||||
pcds_default_data = var_data.get((0,0))
|
||||
NvStoreDataBuffer = ""
|
||||
var_data_offset = collections.OrderedDict()
|
||||
offset = NvStorageHeaderSize
|
||||
for default_data,default_info in pcds_default_data.values():
|
||||
var_name_buffer = self.PACK_VARIABLE_NAME(default_info.var_name)
|
||||
|
||||
vendorguid = default_info.var_guid.split('-')
|
||||
|
||||
if default_info.var_attribute:
|
||||
var_attr_value,_ = VariableAttributes.GetVarAttributes(default_info.var_attribute)
|
||||
else:
|
||||
var_attr_value = 0x07
|
||||
|
||||
print "default var_name_buffer"
|
||||
print self.format_data(var_name_buffer)
|
||||
print "default var_buffer"
|
||||
print self.format_data(default_data)
|
||||
|
||||
DataBuffer = self.AlignData(var_name_buffer + default_data)
|
||||
|
||||
data_size = len(DataBuffer)
|
||||
offset += VariableHeaderSize + len(default_info.var_name.split(","))
|
||||
var_data_offset[default_info.pcdindex] = offset
|
||||
offset += data_size - len(default_info.var_name.split(","))
|
||||
|
||||
var_header_buffer = self.PACK_VARIABLE_HEADER(var_attr_value, len(default_info.var_name.split(",")), data_size, vendorguid)
|
||||
NvStoreDataBuffer += (var_header_buffer + DataBuffer)
|
||||
|
||||
variable_storage_header_buffer = self.PACK_VARIABLE_STORE_HEADER(len(NvStoreDataBuffer) + 28)
|
||||
|
||||
nv_default_part = self.AlignData(self.PACK_DEFAULT_DATA(0, 0, self.unpack_data(variable_storage_header_buffer+NvStoreDataBuffer)))
|
||||
|
||||
print "default whole data \n",self.format_data(nv_default_part)
|
||||
|
||||
data_delta_structure_buffer = ""
|
||||
for skuid,defaultid in var_data:
|
||||
if (skuid,defaultid) == (0,0):
|
||||
continue
|
||||
pcds_sku_data = var_data.get((skuid,defaultid))
|
||||
delta_data_set = []
|
||||
for pcdindex in pcds_sku_data:
|
||||
offset = var_data_offset[pcdindex]
|
||||
delta_data,_ = pcds_sku_data[pcdindex]
|
||||
delta_data = [(item[0] + offset, item[1]) for item in delta_data]
|
||||
delta_data_set.extend(delta_data)
|
||||
|
||||
data_delta_structure_buffer += self.AlignData(self.PACK_DELTA_DATA(defaultid,skuid,delta_data_set))
|
||||
print "delta data"
|
||||
print delta_data_set
|
||||
print self.format_data(self.AlignData(self.PACK_DELTA_DATA(defaultid,skuid,delta_data_set)))
|
||||
|
||||
return self.format_data(nv_default_part + data_delta_structure_buffer)
|
||||
|
||||
|
||||
def format_data(self,data):
|
||||
|
||||
return [hex(item) for item in self.unpack_data(data)]
|
||||
|
||||
def unpack_data(self,data):
|
||||
final_data = ()
|
||||
for item in data:
|
||||
final_data += unpack("B",item)
|
||||
return final_data
|
||||
|
||||
def calculate_delta(self, default, theother):
|
||||
print "default data \n", default
|
||||
print "other data \n",theother
|
||||
if len(default) - len(theother) != 0:
|
||||
EdkLogger.error("build", FORMAT_INVALID, 'The variable data length is not the same for the same PCD.')
|
||||
data_delta = []
|
||||
for i in range(len(default)):
|
||||
if default[i] != theother[i]:
|
||||
data_delta.append((i,theother[i]))
|
||||
return data_delta
|
||||
|
||||
def dump(self):
|
||||
|
||||
default_var_bin = self.new_process_varinfo()
|
||||
value_str = "{"
|
||||
default_var_bin_strip = [ data.strip("""'""") for data in default_var_bin]
|
||||
value_str += ",".join(default_var_bin_strip)
|
||||
value_str += "}"
|
||||
return value_str
|
||||
|
||||
def PACK_VARIABLE_STORE_HEADER(self,size):
|
||||
#Signature: gEfiVariableGuid
|
||||
Guid = "{ 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}"
|
||||
Guid = GuidStructureStringToGuidString(Guid)
|
||||
GuidBuffer = PackGUID(Guid.split('-'))
|
||||
|
||||
SizeBuffer = pack('=L',size)
|
||||
FormatBuffer = pack('=B',0x5A)
|
||||
StateBuffer = pack('=B',0xFE)
|
||||
reservedBuffer = pack('=H',0)
|
||||
reservedBuffer += pack('=L',0)
|
||||
|
||||
return GuidBuffer + SizeBuffer + FormatBuffer + StateBuffer + reservedBuffer
|
||||
|
||||
|
||||
def PACK_VARIABLE_HEADER(self,attribute,namesize,datasize,vendorguid):
|
||||
|
||||
Buffer = pack('=H',0x55AA) # pack StartID
|
||||
Buffer += pack('=B',0x3F) # pack State
|
||||
Buffer += pack('=B',0) # pack reserved
|
||||
|
||||
Buffer += pack('=L',attribute)
|
||||
Buffer += pack('=L',namesize)
|
||||
Buffer += pack('=L',datasize)
|
||||
|
||||
Buffer += PackGUID(vendorguid)
|
||||
|
||||
return Buffer
|
||||
|
||||
def PACK_VARIABLES_DATA(self, var_value,data_type, tail = None):
|
||||
Buffer = ""
|
||||
data_len = 0
|
||||
if data_type == "VOID*":
|
||||
for value_char in var_value.strip("{").strip("}").split(","):
|
||||
Buffer += pack("=B",int(value_char,16))
|
||||
data_len += len(var_value.split(","))
|
||||
if tail:
|
||||
for value_char in tail.split(","):
|
||||
Buffer += pack("=B",int(value_char,16))
|
||||
data_len += len(tail.split(","))
|
||||
elif data_type == "BOOLEAN":
|
||||
Buffer += pack("=B",True) if var_value.upper() == "TRUE" else pack("=B",False)
|
||||
data_len += 1
|
||||
elif data_type == "UINT8":
|
||||
Buffer += pack("=B",GetIntegerValue(var_value))
|
||||
data_len += 1
|
||||
elif data_type == "UINT16":
|
||||
Buffer += pack("=H",GetIntegerValue(var_value))
|
||||
data_len += 2
|
||||
elif data_type == "UINT32":
|
||||
Buffer += pack("=L",GetIntegerValue(var_value))
|
||||
data_len += 4
|
||||
elif data_type == "UINT64":
|
||||
Buffer += pack("=Q",GetIntegerValue(var_value))
|
||||
data_len += 8
|
||||
|
||||
return Buffer
|
||||
|
||||
def PACK_DEFAULT_DATA(self, defaultstoragename,skuid,var_value):
|
||||
Buffer = ""
|
||||
Buffer += pack("=H",6)
|
||||
Buffer += pack("=H",int(defaultstoragename))
|
||||
Buffer += pack("=H",int(skuid))
|
||||
|
||||
for item in var_value:
|
||||
Buffer += pack("=B",item)
|
||||
|
||||
Buffer = pack("=L",len(Buffer)+4) + Buffer
|
||||
|
||||
return Buffer
|
||||
|
||||
def PACK_DELTA_DATA(self,defaultstoragename,skuid,delta_list):
|
||||
Buffer = ""
|
||||
Buffer += pack("=H",6)
|
||||
Buffer += pack("=H",int(defaultstoragename))
|
||||
Buffer += pack("=H",int(skuid))
|
||||
for (delta_offset,value) in delta_list:
|
||||
Buffer += pack("=L",delta_offset)
|
||||
Buffer = Buffer[:-1] + pack("=B",value)
|
||||
|
||||
Buffer = pack("=L",len(Buffer) + 4) + Buffer
|
||||
|
||||
return Buffer
|
||||
|
||||
def AlignData(self,data, align = 4):
|
||||
mybuffer = data
|
||||
for i in range(len(data) % align):
|
||||
mybuffer += pack("=B",0)
|
||||
|
||||
return mybuffer
|
||||
|
||||
def PACK_VARIABLE_NAME(self, var_name):
|
||||
Buffer = ""
|
||||
for name_char in var_name.strip("{").strip("}").split(","):
|
||||
Buffer += pack("=B",int(name_char,16))
|
||||
|
||||
return Buffer
|
|
@ -2201,6 +2201,29 @@ def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Val
|
|||
elif Value == 'FALSE' or Value == '0':
|
||||
Value = '0'
|
||||
return Value
|
||||
## Get the integer value from string like "14U" or integer like 2
|
||||
#
|
||||
# @param Input The object that may be either a integer value or a string
|
||||
#
|
||||
# @retval Value The integer value that the input represents
|
||||
#
|
||||
def GetIntegerValue(Input):
|
||||
if type(Input) in (int, long):
|
||||
return Input
|
||||
String = Input
|
||||
if String.endswith("U"):
|
||||
String = String[:-1]
|
||||
if String.endswith("ULL"):
|
||||
String = String[:-3]
|
||||
if String.endswith("LL"):
|
||||
String = String[:-2]
|
||||
|
||||
if String.startswith("0x") or String.startswith("0X"):
|
||||
return int(String, 16)
|
||||
elif String == '':
|
||||
return 0
|
||||
else:
|
||||
return int(String)
|
||||
|
||||
##
|
||||
#
|
||||
|
|
|
@ -122,12 +122,16 @@ class StructurePcd(PcdClassObject):
|
|||
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 AddOverrideValue (self, FieldName, Value, SkuName, FileName="", LineNo=0):
|
||||
if SkuName not in self.SkuOverrideValues:
|
||||
self.SkuOverrideValues[SkuName] = collections.OrderedDict({})
|
||||
if FieldName in self.SkuOverrideValues[SkuName]:
|
||||
del self.SkuOverrideValues[SkuName][FieldName]
|
||||
self.SkuOverrideValues[SkuName][FieldName] = [Value.strip(), FileName, LineNo]
|
||||
return self.SkuOverrideValues[SkuName][FieldName]
|
||||
|
||||
|
|
Loading…
Reference in New Issue