From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web10.35370.1675060021109841369 for ; Sun, 29 Jan 2023 22:27:01 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=egKo3vTW; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: yuwei.chen@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675060021; x=1706596021; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=PPgu70wv0lfBUIV/8MOzPcndluoEL7uT6M2BhC8RAfI=; b=egKo3vTWDcRYlomV/JoCMgzABi7YoP3ZHvqGPiBnK7K7gy72awqqTzKv 1+Lx8znOMUslgtA2kqrPheWOyaC8dTzqO3VukS3FbEXqDp/fBnLhpAMzk T0OhaD+CIHTTTpM2RZgRjYvRbVBrXhWpvuyRpBR7FgmKFd6KEMt9fidOm sQcSCd4aysYKC0OVKo3IwMv+uPVP1yWOYmsW8NTYOrtFCHIKlBtaqcYog ZaOvsVhboA1VETcwfDKs8kDZEH/JEflqYOJ1YiuNWXdOlQwUxh+yvsPdL yk4NPuZAmQGR+ZiC+ejAeBqWTzux/CfWtWpquGxLKD2GRM4hXKftjazKI Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10605"; a="325182209" X-IronPort-AV: E=Sophos;i="5.97,257,1669104000"; d="scan'208";a="325182209" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jan 2023 22:26:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10605"; a="665967526" X-IronPort-AV: E=Sophos;i="5.97,257,1669104000"; d="scan'208";a="665967526" Received: from yuweipc.ccr.corp.intel.com ([10.239.158.38]) by fmsmga007.fm.intel.com with ESMTP; 29 Jan 2023 22:26:46 -0800 From: "Yuwei Chen" To: devel@edk2.groups.io Cc: Bob Feng , Liming Gao Subject: [Patch V2 3/3] [edk2-staging]BaseTools: Add new build option for Variable default value generation Date: Mon, 30 Jan 2023 14:26:44 +0800 Message-Id: <20230130062644.1688-1-yuwei.chen@intel.com> X-Mailer: git-send-email 2.27.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add new build option "--gen-default-variable-bin" for Variable default value generation from Python VFR tool's extended json output file. Cc: Bob Feng Cc: Liming Gao Signed-off-by: Yuwei Chen --- BaseTools/Source/Python/AutoGen/DataPipe.py | 2 ++ BaseTools/Source/Python/AutoGen/GenDefaultVar.py | 577 ++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++ BaseTools/Source/Python/AutoGen/ModuleAutoGen.py | 8 ++++++++ BaseTools/Source/Python/Common/GlobalData.py | 5 +++++ BaseTools/Source/Python/VfrCompiler/VfrSyntaxVisitor.py | 12 ++++++------ BaseTools/Source/Python/build/build.py | 19 ++++++++++++= ++++++- BaseTools/Source/Python/build/buildoptions.py | 1 + 7 files changed, 617 insertions(+), 7 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/DataPipe.py b/BaseTools/Source= /Python/AutoGen/DataPipe.py index c700baf7b7..e45b4a928a 100755 --- a/BaseTools/Source/Python/AutoGen/DataPipe.py +++ b/BaseTools/Source/Python/AutoGen/DataPipe.py @@ -173,3 +173,5 @@ class MemoryDataPipe(DataPipe): self.DataContainer =3D {"gPlatformFinalPcds":GlobalData.gPlatformF= inalPcds}=0D =0D self.DataContainer =3D {"VfrYamlEnable": GlobalData.gVfrYamlEnable= }=0D +=0D + self.DataContainer =3D {"GenDefaultVarBin": GlobalData.gGenDefault= VarBin}=0D diff --git a/BaseTools/Source/Python/AutoGen/GenDefaultVar.py b/BaseTools/S= ource/Python/AutoGen/GenDefaultVar.py new file mode 100644 index 0000000000..859d4f25eb --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/GenDefaultVar.py @@ -0,0 +1,577 @@ +import json=0D +from ctypes import *=0D +import re=0D +import copy=0D +from struct import unpack=0D +import os=0D +import Common.EdkLogger as EdkLogger=0D +=0D +class GUID(Structure):=0D + _fields_ =3D [=0D + ('Guid1', c_uint32),=0D + ('Guid2', c_uint16),=0D + ('Guid3', c_uint16),=0D + ('Guid4', ARRAY(c_uint8, 8)),=0D + ]=0D +=0D + def from_list(self, listformat):=0D + self.Guid1 =3D listformat[0]=0D + self.Guid2 =3D listformat[1]=0D + self.Guid3 =3D listformat[2]=0D + for i in range(8):=0D + self.Guid4[i] =3D listformat[i+3]=0D +=0D + def __cmp__(self, otherguid):=0D + if isinstance(otherguid, GUID):=0D + return 1=0D + rt =3D False=0D + if self.Guid1 =3D=3D otherguid.Guid1 and self.Guid2 =3D=3D othergu= id.Guid2 and self.Guid3 =3D=3D otherguid.Guid3:=0D + rt =3D True=0D + for i in range(8):=0D + rt =3D rt & (self.Guid4[i] =3D=3D otherguid.Guid4[i])=0D + return rt=0D +=0D +=0D +class TIME(Structure):=0D + _fields_ =3D [=0D + ('Year', c_uint16),=0D + ('Month', c_uint8),=0D + ('Day', c_uint8),=0D + ('Hour', c_uint8),=0D + ('Minute', c_uint8),=0D + ('Second', c_uint8),=0D + ('Pad1', c_uint8),=0D + ('Nanosecond', c_uint32),=0D + ('TimeZone', c_uint16),=0D + ('Daylight', c_uint8),=0D + ('Pad2', c_uint8),=0D + ]=0D + def __init__(self):=0D + self.Year =3D 0x0=0D + self.Month =3D 0x0=0D + self.Day =3D 0x0=0D + self.Hour =3D 0x0=0D + self.Minute =3D 0x0=0D + self.Second =3D 0x0=0D + self.Pad1 =3D 0x0=0D + self.Nanosecond =3D 0x0=0D + self.TimeZone =3D 0x0=0D + self.Daylight =3D 0x0=0D + self.Pad2 =3D 0x0=0D +=0D +=0D +EFI_VARIABLE_GUID =3D [0xddcf3616, 0x3275, 0x4164,=0D + 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d]=0D +EFI_AUTHENTICATED_VARIABLE_GUID =3D [=0D + 0xaaf32c78, 0x947b, 0x439a, 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, = 0x92]=0D +=0D +AuthVarGuid =3D GUID()=0D +AuthVarGuid.from_list(EFI_AUTHENTICATED_VARIABLE_GUID)=0D +VarGuid =3D GUID()=0D +VarGuid.from_list(EFI_VARIABLE_GUID)=0D +=0D +# Variable Store Header Format.=0D +VARIABLE_STORE_FORMATTED =3D 0x5a=0D +# Variable Store Header State.=0D +VARIABLE_STORE_HEALTHY =3D 0xfe=0D +=0D +=0D +class VARIABLE_STORE_HEADER(Structure):=0D + _fields_ =3D [=0D + ('Signature', GUID),=0D + ('Size', c_uint32),=0D + ('Format', c_uint8),=0D + ('State', c_uint8),=0D + ('Reserved', c_uint16),=0D + ('Reserved1', c_uint32),=0D + ]=0D +=0D +=0D +# Variable data start flag.=0D +VARIABLE_DATA =3D 0x55AA=0D +=0D +# Variable State flags.=0D +VAR_IN_DELETED_TRANSITION =3D 0xfe=0D +VAR_DELETED =3D 0xfd=0D +VAR_HEADER_VALID_ONLY =3D 0x7f=0D +VAR_ADDED =3D 0x3f=0D +=0D +=0D +class VARIABLE_HEADER(Structure):=0D + _fields_ =3D [=0D + ('StartId', c_uint16),=0D + ('State', c_uint8),=0D + ('Reserved', c_uint8),=0D + ('Attributes', c_uint32),=0D + ('NameSize', c_uint32),=0D + ('DataSize', c_uint32),=0D + ('VendorGuid', GUID),=0D + ]=0D +=0D +=0D +class AUTHENTICATED_VARIABLE_HEADER(Structure):=0D + _fields_ =3D [=0D + ('StartId', c_uint16),=0D + ('State', c_uint8),=0D + ('Reserved', c_uint8),=0D + ('Attributes', c_uint32),=0D + ('MonotonicCount', c_uint64),=0D + ('TimeStamp', TIME),=0D + ('PubKeyIndex', c_uint32),=0D + ('NameSize', c_uint32),=0D + ('DataSize', c_uint32),=0D + ('VendorGuid', GUID),=0D + ]=0D + _pack_ =3D 1=0D +=0D +=0D +# Alignment of Variable Data Header in Variable Store region.=0D +HEADER_ALIGNMENT =3D 4=0D +=0D +=0D +class DEFAULT_INFO(Structure):=0D + _fields_ =3D [=0D + ('DefaultId', c_uint16),=0D + ('BoardId', c_uint16),=0D + ]=0D +=0D +=0D +class DEFAULT_DATA(Structure):=0D + _fields_ =3D [=0D + ('HeaderSize', c_uint16),=0D + ('DefaultInfo', DEFAULT_INFO),=0D + ]=0D +=0D +class DELTA_DATA(Structure):=0D + _fields_ =3D [=0D + ('Offset', c_uint16),=0D + ('Value', c_uint8),=0D + ]=0D + _pack_ =3D 1=0D +=0D +array_re =3D re.compile(=0D + "(?P[a-z_A-Z][a-z_A-Z0-9]*)\[(?P[1-9][0-9]*)\]")=0D +=0D +=0D +class VarField():=0D + def __init__(self):=0D + self.Offset =3D 0=0D + self.Value =3D 0=0D + self.Size =3D 0=0D +=0D + @property=0D + def Type(self):=0D + if self.Size =3D=3D 1:=0D + return "UINT8"=0D + if self.Size =3D=3D 2:=0D + return "UINT16"=0D + if self.Size =3D=3D 4:=0D + return "UINT32"=0D + if self.Size =3D=3D 8:=0D + return "UINT64"=0D +=0D + return "UINT8"=0D +=0D +=0D +BASIC_TYPE =3D {=0D + "BOOLEAN": 1,=0D + "UINT8": 1,=0D + "UINT16": 2,=0D + "UINT32": 4,=0D + "UINT64": 8=0D +}=0D +=0D +def GetTypeSize(fieldtype, VarAttributes):=0D + num =3D 1=0D + if "[" in fieldtype:=0D + num =3D int(fieldtype.split("[")[1].split("]")[0])=0D + fieldtype =3D fieldtype.split("[")[0]=0D + if fieldtype in VarAttributes:=0D + return VarAttributes[fieldtype]['TotalSize'] * num=0D + elif fieldtype in BASIC_TYPE:=0D + return BASIC_TYPE[fieldtype] * num=0D + else:=0D + return None=0D +=0D +class CStruct():=0D +=0D +=0D + def __init__(self, typedefs):=0D + self.TypeDefs =3D typedefs=0D + self.TypeStack =3D copy.deepcopy(typedefs)=0D + self.finalDefs =3D {}=0D +=0D + def CalStuctSize(self, sType):=0D + rt =3D 0=0D + if sType in BASIC_TYPE:=0D + return BASIC_TYPE[sType]=0D +=0D + ma =3D array_re.match(sType)=0D + if ma:=0D + mType =3D ma.group('mType')=0D + mSize =3D ma.group('mSize')=0D + rt +=3D int(mSize) * self.CalStuctSize(mType)=0D + else:=0D + for subType in self.TypeDefs[sType]:=0D + rt +=3D self.CalStuctSize(subType['Type'])=0D +=0D + return rt=0D +=0D + def expend(self, fielditem):=0D + fieldname =3D fielditem['Name']=0D + fieldType =3D fielditem['Type']=0D + fieldOffset =3D fielditem['Offset']=0D +=0D + ma =3D array_re.match(fieldType)=0D + if ma:=0D + mType =3D ma.group('mType')=0D + mSize =3D ma.group('mSize')=0D + return [{"Name": "%s[%d]" % (fieldname, i), "Type": mType, "Of= fset": (fieldOffset + i*self.CalStuctSize(mType))} for i in range(int(mSize= ))]=0D + else:=0D + return [{"Name": "%s.%s" % (fieldname, item['Name']), "Type":i= tem['Type'], "Offset": (fieldOffset + item['Offset'])} for item in self.Typ= eDefs[fielditem['Type']]]=0D +=0D + def ExpandTypes(self):=0D + if not self.finalDefs:=0D + for datatype in self.TypeStack:=0D + result =3D []=0D + mTypeStack =3D self.TypeStack[datatype]=0D + while len(mTypeStack) > 0:=0D + item =3D mTypeStack.pop()=0D + if item['Type'] in self.BASIC_TYPE:=0D + result.append(item)=0D + elif item['Type'] =3D=3D '(null)':=0D + continue=0D + else:=0D + for expand_item in self.expend(item):=0D + mTypeStack.append(expand_item)=0D + self.finalDefs[datatype] =3D result=0D + self.finalDefs=0D + return self.finalDefs=0D +=0D +def Get_Occupied_Size(FileLength, alignment):=0D + if FileLength % alignment =3D=3D 0:=0D + return FileLength=0D + return FileLength + (alignment-(FileLength % alignment))=0D +=0D +def Occupied_Size(buffer, alignment):=0D + FileLength =3D len(buffer)=0D + if FileLength % alignment !=3D 0:=0D + buffer +=3D b'\0' * (alignment-(FileLength % alignment))=0D + return buffer=0D +=0D +def PackStruct(cStruct):=0D + length =3D sizeof(cStruct)=0D + p =3D cast(pointer(cStruct), POINTER(c_char * length))=0D + return p.contents.raw=0D +=0D +def calculate_delta(default, theother):=0D +=0D + if len(default) - len(theother) !=3D 0:=0D + return []=0D +=0D + data_delta =3D []=0D + for i in range(len(default)):=0D + if default[i] !=3D theother[i]:=0D + data_delta.append([i, theother[i]])=0D + return data_delta=0D +=0D +class Variable():=0D + def __init__(self):=0D + self.mAlign =3D 1=0D + self.mTotalSize =3D 1=0D + self.mValue =3D {} # {defaultstore: value}=0D + self.mBin =3D {}=0D + self.fields =3D {} # {defaultstore: fileds}=0D + self.delta =3D {}=0D + self.attributes =3D 0=0D + self.mType =3D ''=0D + self.guid =3D ''=0D + self.mName =3D ''=0D + self.cDefs =3D None=0D + self.Struct =3D None=0D + self.TypeList =3D {}=0D +=0D + @property=0D + def GuidArray(self):=0D +=0D + guid_array =3D []=0D + guid =3D self.guid.strip().strip("{").strip("}")=0D + for item in guid.split(","):=0D + field =3D item.strip().strip("{").strip("}")=0D + guid_array.append(int(field,16))=0D + return guid_array=0D +=0D + def update_delta_offset(self,base):=0D + for default_id in self.delta:=0D + for delta_list in self.delta[default_id]:=0D + delta_list[0] +=3D base=0D +=0D + def pack(self):=0D +=0D + for defaultid in self.mValue:=0D + var_value =3D self.mValue[defaultid]=0D + auth_var =3D AUTHENTICATED_VARIABLE_HEADER()=0D + auth_var.StartId =3D VARIABLE_DATA=0D + auth_var.State =3D VAR_ADDED=0D + auth_var.Reserved =3D 0x00=0D + auth_var.Attributes =3D 0x00000007=0D + auth_var.MonotonicCount =3D 0x0=0D + auth_var.TimeStamp =3D TIME()=0D + auth_var.PubKeyIndex =3D 0x0=0D + var_name_buffer =3D self.mName.encode('utf-16le') + b'\0\0'=0D + auth_var.NameSize =3D len(var_name_buffer)=0D + auth_var.DataSize =3D len(var_value)=0D + vendor_guid =3D GUID()=0D + vendor_guid.from_list(self.GuidArray)=0D + auth_var.VendorGuid =3D vendor_guid=0D +=0D + self.mBin[defaultid] =3D PackStruct(auth_var) + Occupied_Size(= var_name_buffer + var_value, 4)=0D +=0D + def TypeCheck(self,data_type, data_size):=0D + if BASIC_TYPE[data_type] =3D=3D data_size:=0D + return True=0D + return False=0D +=0D + def ValueToBytes(self,data_type,data_value,data_size):=0D +=0D + rt =3D b''=0D + if not self.TypeCheck(data_type, data_size):=0D + print(data_type,data_value,data_size)=0D +=0D + if data_type =3D=3D "BOOLEAN" or data_type =3D=3D 'UINT8':=0D + p =3D cast(pointer(c_uint8(int(data_value,16))), POINTER(c_cha= r * 1))=0D + rt =3D p.contents.raw=0D + elif data_type =3D=3D 'UINT16':=0D + p =3D cast(pointer(c_uint16(int(data_value,16))), POINTER(c_ch= ar * 2))=0D + rt =3D p.contents.raw=0D + elif data_type =3D=3D 'UINT32':=0D + p =3D cast(pointer(c_uint32(int(data_value,16))), POINTER(c_ch= ar * 4))=0D + rt =3D p.contents.raw=0D + elif data_type =3D=3D 'UINT64':=0D + p =3D cast(pointer(c_uint64(int(data_value,16))), POINTER(c_ch= ar * 8))=0D + rt =3D p.contents.raw=0D +=0D + return rt=0D +=0D + def serial(self):=0D + for defaultstore in self.fields:=0D + vValue =3D b''=0D + vfields =3D {vf.Offset: vf for vf in self.fields[defaultstore]= }=0D + i =3D 0=0D + while i < self.mTotalSize:=0D + if i in vfields:=0D + vfield =3D vfields[i]=0D + if vfield.Size !=3D 0:=0D + vValue +=3D self.ValueToBytes(vfield.Type, vfield.= Value,vfield.Size)=0D + i +=3D vfield.Size=0D + else:=0D + vValue +=3D self.ValueToBytes('UINT8','0x00',1)=0D + i +=3D 1=0D +=0D + self.mValue[defaultstore] =3D vValue=0D + standard_default =3D self.mValue[0]=0D +=0D + for defaultid in self.mValue:=0D + if defaultid =3D=3D 0:=0D + continue=0D + others_default =3D self.mValue[defaultid]=0D +=0D + self.delta.setdefault(defaultid, []).extend(calculate_delta(=0D + standard_default, others_default))=0D +=0D +class DefaultVariableGenerator():=0D + def __init__(self):=0D + self.NvVarInfo =3D []=0D +=0D + def LoadNvVariableInfo(self, VarInfoFilelist):=0D +=0D + VarDataDict =3D {}=0D + DataStruct =3D {}=0D + VarDefine =3D {}=0D + VarAttributes =3D {}=0D + for VarInfoFile in VarInfoFilelist:=0D + with open(VarInfoFile.strip(), "r") as fd:=0D + data =3D json.load(fd)=0D +=0D + DataStruct.update(data.get("DataStruct", {}))=0D + Data =3D data.get("Data")=0D + VarDefine.update(data.get("VarDefine"))=0D + VarAttributes.update(data.get("DataStructAttribute"))=0D +=0D + for vardata in Data:=0D + if vardata['VendorGuid'] =3D=3D 'NA':=0D + continue=0D + if (vardata['VendorGuid'], vardata["VarName"]) in VarDataD= ict and vardata in VarDataDict[(vardata['VendorGuid'], vardata["VarName"])]= :=0D + continue=0D + VarDataDict.setdefault(=0D + (vardata['VendorGuid'], vardata["VarName"]), []).appen= d(vardata)=0D +=0D + cStructDefs =3D CStruct(DataStruct)=0D + for guid, varname in VarDataDict:=0D + v =3D Variable()=0D + v.guid =3D guid=0D + vardef =3D VarDefine.get(varname)=0D + if vardef is None:=0D + for var in VarDefine:=0D + if VarDefine[var]['Type'] =3D=3D varname:=0D + vardef =3D VarDefine[var]=0D + break=0D + else:=0D + continue=0D + v.attributes =3D vardef['Attributes']=0D + v.mType =3D vardef['Type']=0D + v.mAlign =3D VarAttributes[v.mType]['Alignment']=0D + v.mTotalSize =3D VarAttributes[v.mType]['TotalSize']=0D + v.Struct =3D DataStruct[v.mType]=0D + v.mName =3D varname=0D + v.cDefs =3D cStructDefs=0D + v.TypeList =3D VarAttributes=0D + for fieldinfo in VarDataDict.get((guid, varname), []):=0D + vf =3D VarField()=0D + vf.Offset =3D fieldinfo['Offset']=0D + vf.Value =3D fieldinfo['Value']=0D + vf.Size =3D fieldinfo['Size']=0D + v.fields.setdefault(=0D + int(fieldinfo['DefaultStore'], 10), []).append(vf)=0D + v.serial()=0D + v.pack()=0D + self.NvVarInfo.append(v)=0D +=0D + def PackDeltaData(self):=0D +=0D + default_id_set =3D set()=0D + for v in self.NvVarInfo:=0D + default_id_set |=3D set(v.mBin.keys())=0D +=0D + if default_id_set:=0D + default_id_set.remove(0)=0D + delta_buff_set =3D {}=0D + for defaultid in default_id_set:=0D + delta_buff =3D b''=0D + for v in self.NvVarInfo:=0D + delta_list =3D v.delta.get(defaultid,[])=0D + for delta in delta_list:=0D + delta_data =3D DELTA_DATA()=0D + delta_data.Offset, delta_data.Value =3D delta=0D + delta_buff +=3D PackStruct(delta_data)=0D + delta_buff_set[defaultid] =3D delta_buff=0D +=0D + return delta_buff_set=0D +=0D + def PackDefaultData(self):=0D +=0D + default_data_header =3D DEFAULT_DATA()=0D + default_data_header.HeaderSize =3D sizeof(DEFAULT_DATA)=0D + default_data_header.DefaultInfo.DefaultId =3D 0x0=0D + default_data_header.DefaultInfo.BoardId =3D 0x0=0D + default_data_header_buffer =3D PackStruct(default_data_header)=0D +=0D +=0D + variable_store =3D VARIABLE_STORE_HEADER()=0D + variable_store.Signature =3D AuthVarGuid=0D +=0D + variable_store_size =3D Get_Occupied_Size(sizeof(DEFAULT_DATA) + s= izeof(VARIABLE_STORE_HEADER), 4)=0D + for v in self.NvVarInfo:=0D + variable_store_size +=3D Get_Occupied_Size(len(v.mBin[0]), 4)= =0D +=0D + variable_store.Size =3D variable_store_size=0D + variable_store.Format =3D VARIABLE_STORE_FORMATTED=0D + variable_store.State =3D VARIABLE_STORE_HEALTHY=0D + variable_store.Reserved =3D 0x0=0D + variable_store.Reserved2 =3D 0x0=0D +=0D + variable_storage_header_buffer =3D PackStruct(variable_store)=0D +=0D + variable_data =3D b''=0D + v_offset =3D 0=0D + for v in self.NvVarInfo:=0D + v.update_delta_offset(v_offset)=0D + variable_data +=3D Occupied_Size(v.mBin[0],4)=0D + v_offset +=3D Get_Occupied_Size(len(v.mBin[0]),4)=0D +=0D +=0D + final_buff =3D Occupied_Size(default_data_header_buffer + variable= _storage_header_buffer,4) + variable_data=0D +=0D + return final_buff=0D +=0D + def GenVariableInfo(self, build_macro):=0D + VariableInfo =3D []=0D + VariableInfo.append('Variable Information Report\n')=0D + if build_macro:=0D + VariableInfo.append('[Platform Definitions]')=0D + for define_item in build_macro:=0D + if '=3D' in define_item:=0D + VariableInfo.append('* %-20s=3D %s'%(define_item.split= ('=3D')[0], define_item.split('=3D')[1]))=0D + else:=0D + VariableInfo.append('* ' + define_item)=0D + VariableInfo.append('\n[Variable List]')=0D + VariableInfo.append('# {} variables used in current setting:'.form= at(len(self.NvVarInfo)))=0D + for item in self.NvVarInfo:=0D + VariableInfo.append('* ' + item.mName)=0D + VariableInfo.append('\n[Variable Details]')=0D + for item in self.NvVarInfo:=0D + VariableInfo.append('####################')=0D + VariableInfo.append('* Variable Name: ' + item.mName)=0D + VariableInfo.append('* Variable Type: ' + item.mType)=0D + VariableInfo.append('* Variable Guid: ' + item.guid)=0D + VariableInfo.append('* Variable Size: ' + hex(item.mTotalSize)= )=0D +=0D + ## Field structure Info=0D + VariableInfo.append('* Variable Fields: {} fields'.format(len(= item.Struct)))=0D + VariableInfo.append('{')=0D + VariableInfo.append('# %-5s | %-30s | %-15s | %-10s | %s'%('In= dex', 'Name', 'Type', 'TotalSize', 'Offset'))=0D + FieldsNum =3D len(item.Struct)=0D + Name_Offset =3D {}=0D + if FieldsNum =3D=3D 0:=0D + Name_Offset[0] =3D field['Name']=0D + for i in range(FieldsNum):=0D + field =3D item.Struct[i]=0D + Name_Offset[field['Offset']] =3D field['Name']=0D + if i !=3D FieldsNum-1:=0D + nextfield =3D item.Struct[i+1]=0D + for cur_offset in range(field['Offset']+1, nextfield['= Offset']):=0D + Name_Offset[cur_offset] =3D field['Name']=0D + VariableInfo.append(' %-5s | %-30s | %-15s | %-10s | %s'%= (i, field['Name'], field['Type'], GetTypeSize(field['Type'], item.TypeList)= , field['Offset']))=0D + VariableInfo.append('}')=0D +=0D + ## Field value Info=0D + VariableInfo.append('* Field value: ')=0D + VariableInfo.append('{')=0D + VariableInfo.append('# defaultstore %-5s | %-30s | %-15s | %-1= 5s | %s'%('xxxx', 'FieldName', 'FieldType', 'FieldOffset', 'FieldValue'))=0D + storenum =3D len(item.fields)=0D + for storeid in range(storenum):=0D + for Var in item.fields[storeid]:=0D + # print('If Var.Offset in Name_Offset: ', Var.Offset i= n Name_Offset)=0D + if Var.Offset not in Name_Offset:=0D + VariableInfo.append(' defaultstore %-5s | %-30s |= %-15s | %-15s | %s'%(storeid, Var.Offset, Var.Type, Var.Offset, Var.Value)= )=0D + print('Offset:', Var.Offset)=0D + else:=0D + VariableInfo.append(' defaultstore %-5s | %-30s |= %-15s | %-15s | %s'%(storeid, Name_Offset[Var.Offset], Var.Type, Var.Offse= t, Var.Value))=0D + VariableInfo.append('}\n')=0D + return VariableInfo=0D +=0D + def generate(self, jsonlistfile, output_folder, build_macro=3DNone):=0D + if not os.path.exists(jsonlistfile):=0D + return=0D + if not os.path.exists(output_folder):=0D + os.makedirs(output_folder)=0D + try:=0D + with open(jsonlistfile,"r") as fd:=0D + filelist =3D fd.readlines()=0D + genVar =3D DefaultVariableGenerator()=0D + genVar.LoadNvVariableInfo(filelist)=0D + with open(os.path.join(output_folder, "default.bin"), "wb") as= fd:=0D + fd.write(genVar.PackDefaultData())=0D +=0D + delta_set =3D genVar.PackDeltaData()=0D + for default_id in delta_set:=0D + with open(os.path.join(output_folder, "defaultdelta_%s.bin= " % default_id), "wb") as fd:=0D + fd.write(delta_set[default_id])=0D +=0D + VariableInfo =3D genVar.GenVariableInfo(build_macro)=0D + if VariableInfo:=0D + with open(os.path.join(output_folder, "VariableInfo.txt"),= "w") as reportfile:=0D + for item in VariableInfo:=0D + reportfile.write(item + '\n')=0D + except:=0D + EdkLogger.info("generate varbin file failed")=0D diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py b/BaseTools/S= ource/Python/AutoGen/ModuleAutoGen.py index eb81c3f3af..8fdca9df5c 100755 --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py @@ -442,6 +442,14 @@ class ModuleAutoGen(AutoGen): rt.append(os.path.join(self.OutputDir, "{}.i".format(SrcFi= le.BaseName)))=0D return rt=0D =0D + @cached_property=0D + def VarJsonFiles(self):=0D + rt =3D []=0D + for SrcFile in self.SourceFileList:=0D + if SrcFile.Ext.lower() =3D=3D '.vfr':=0D + rt.append(os.path.join(self.OutputDir, "{}.json".format(Sr= cFile.BaseName)))=0D + return rt=0D +=0D ## Return the path of custom file=0D @cached_property=0D def CustomMakefile(self):=0D diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Sourc= e/Python/Common/GlobalData.py index 039a9648aa..951a835f1b 100755 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -127,3 +127,8 @@ file_lock =3D None # Build flag for generate Yaml file from Vfr file=0D #=0D gVfrYamlEnable =3D False=0D +=0D +#=0D +# Build flag for generate default variable binary file=0D +#=0D +gGenDefaultVarBin =3D False=0D diff --git a/BaseTools/Source/Python/VfrCompiler/VfrSyntaxVisitor.py b/Base= Tools/Source/Python/VfrCompiler/VfrSyntaxVisitor.py index 43078f914a..9ae60267f6 100644 --- a/BaseTools/Source/Python/VfrCompiler/VfrSyntaxVisitor.py +++ b/BaseTools/Source/Python/VfrCompiler/VfrSyntaxVisitor.py @@ -4560,7 +4560,7 @@ class VfrSyntaxVisitor(ParseTreeVisitor): '0x%x'%(pVsNode.Guid.Data4[4]), '0x%x'%(pVsNode.Gu= id.Data4[5]), '0x%x'%(pVsNode.Guid.Data4[6]), '0x%x'%(pVsNode.Guid.Data4[7]= )) + ' }}\",\n')=0D f.write(' \"VarName\": \"{}\",\n'.format(st= r(pVsNode.Name)))=0D f.write(' \"DefaultStore\": \"{}\",\n'.form= at(str(pVsNode.Id)))=0D - f.write(' \"Size\": \"{}\",\n'.format(str(p= InfoNode.Width)))=0D + f.write(' \"Size\": {},\n'.format(str(pInfo= Node.Width)))=0D f.write(' \"Offset\": {},\n'.format(str(pIn= foNode.Offset)))=0D #f.write(' \"Value\": \"{}\"\n'.format(str(= pInfoNode.Value)))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_DATE:=0D @@ -4574,15 +4574,15 @@ class VfrSyntaxVisitor(ParseTreeVisitor): if pInfoNode.Type =3D=3D EFI_IFR_TYPE_STRING:=0D f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.string))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_8:= =0D - f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.u8))=0D + f.write(' \"Value\": \"{}\"\n'.format(h= ex(pInfoNode.Value.u8)))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_16:= =0D - f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.u16))=0D + f.write(' \"Value\": \"{}\"\n'.format(h= ex(pInfoNode.Value.u16)))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_32:= =0D - f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.u32))=0D + f.write(' \"Value\": \"{}\"\n'.format(h= ex(pInfoNode.Value.u32)))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_64:= =0D - f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.u64))=0D + f.write(' \"Value\": \"{}\"\n'.format(h= ex(pInfoNode.Value.u64)))=0D if pInfoNode.Type =3D=3D EFI_IFR_TYPE_BOOLEAN:=0D - f.write(' \"Value\": \"{}\"\n'.format(p= InfoNode.Value.b))=0D + f.write(' \"Value\": \"{}\"\n'.format(h= ex(pInfoNode.Value.b)))=0D =0D f.write(' },\n')=0D pInfoNode =3D pInfoNode.Next=0D diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Pyth= on/build/build.py index 7e2f25686d..69217eb3fd 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -749,6 +749,7 @@ class Build(): GlobalData.gEnableGenfdsMultiThread =3D not BuildOptions.NoGenfdsM= ultiThread=0D GlobalData.gDisableIncludePathCheck =3D BuildOptions.DisableInclud= ePathCheck=0D GlobalData.gVfrYamlEnable =3D BuildOptions.VfrYamlEnable=0D + GlobalData.gGenDefaultVarBin =3D BuildOptions.GenDefaultVarBin=0D =0D if GlobalData.gBinCacheDest and not GlobalData.gUseHashCache:=0D EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData=3D"--= binary-destination must be used together with --hash.")=0D @@ -1472,6 +1473,10 @@ class Build(): yamloutputfile =3D inputfile.split(".")[0] + '= .yaml'=0D jsonoutputfile =3D inputfile.split(".")[0] + '= .json'=0D VfrParse(inputfile, yamloutputfile, jsonoutput= file)=0D + if GlobalData.gGenDefaultVarBin:=0D + from AutoGen.GenDefaultVar import DefaultVariableGenerator= =0D + variable_json_filelist =3D os.path.join(AutoGenObject.Buil= dDir,"variable_json_filelist.txt")=0D + DefaultVariableGenerator().generate(variable_json_filelist= , AutoGenObject.FvDir, GlobalData.gOptions.Macros)=0D if GenFdsApi(AutoGenObject.GenFdsCommandDict, self.Db):=0D EdkLogger.error("build", COMMAND_FAILURE)=0D Threshold =3D self.GetFreeSizeThreshold()=0D @@ -2259,7 +2264,9 @@ class Build(): fw.write("BuildDir=3D%s\n" % Wa.BuildDir)=0D fw.write("PlatformGuid=3D%s\n" % str(Wa.AutoGenObjectList[0].G= uid))=0D variable_i_filelist =3D os.path.join(Wa.BuildDir,"variable_i_filel= ist.txt")=0D + variable_json_filelist =3D os.path.join(Wa.BuildDir,"variable_json= _filelist.txt")=0D vfr_var_i =3D []=0D + vfr_var_json =3D []=0D if GlobalData.gVfrYamlEnable:=0D for ma in self.AllModules:=0D vfr_var_i.extend(ma.VarIFiles)=0D @@ -2267,6 +2274,13 @@ class Build(): else:=0D if os.path.exists(variable_i_filelist):=0D os.remove(variable_i_filelist)=0D + if GlobalData.gGenDefaultVarBin:=0D + for ma in self.AllModules:=0D + vfr_var_json.extend(ma.VarJsonFiles)=0D + SaveFileOnChange(variable_json_filelist, "\n".join(vfr_var_jso= n), False)=0D + else:=0D + if os.path.exists(variable_json_filelist):=0D + os.remove(variable_json_filelist)=0D =0D if GlobalData.gBinCacheSource:=0D BuildModules.extend(self.MakeCacheMiss)=0D @@ -2389,8 +2403,11 @@ class Build(): inputfile =3D i_file.replace("\n",= "")=0D yamloutputfile =3D inputfile.split= (".")[0] + '.yaml'=0D jsonoutputfile =3D inputfile.split= (".")[0] + '.json'=0D - print('inputfile ', inputfile)=0D VfrParse(inputfile, yamloutputfile= , jsonoutputfile)=0D + if GlobalData.gGenDefaultVarBin:=0D + from AutoGen.GenDefaultVar import DefaultVaria= bleGenerator=0D + variable_json_filelist =3D os.path.join(Wa.Bui= ldDir,"variable_json_filelist.txt")=0D + DefaultVariableGenerator().generate(variable_j= son_filelist, Wa.FvDir, GlobalData.gOptions.Macros)=0D GenFdsStart =3D time.time()=0D if GenFdsApi(Wa.GenFdsCommandDict, self.Db):=0D EdkLogger.error("build", COMMAND_FAILURE)=0D diff --git a/BaseTools/Source/Python/build/buildoptions.py b/BaseTools/Sour= ce/Python/build/buildoptions.py index c0304c2f98..9d69719741 100644 --- a/BaseTools/Source/Python/build/buildoptions.py +++ b/BaseTools/Source/Python/build/buildoptions.py @@ -104,4 +104,5 @@ class MyOptionParser(): Parser.add_option("--no-genfds-multi-thread", action=3D"store_true= ", dest=3D"NoGenfdsMultiThread", default=3DFalse, help=3D"Disable GenFds mu= lti thread to generate ffs file.")=0D Parser.add_option("--disable-include-path-check", action=3D"store_= true", dest=3D"DisableIncludePathCheck", default=3DFalse, help=3D"Disable t= he include path check for outside of package.")=0D Parser.add_option("--vfr-yaml-enable", action=3D"store_true", dest= =3D"VfrYamlEnable", default=3DFalse, help=3D"Enable the Vfr to yaml functio= n.")=0D + Parser.add_option("--gen-default-variable-bin", action=3D"store_tr= ue", dest=3D"GenDefaultVarBin", default=3DFalse, help=3D"Generate default v= ariable binary file.")=0D self.BuildOption, self.BuildTarget =3D Parser.parse_args()=0D --=20 2.27.0.windows.1