2018-07-17 05:42:21 +02:00
|
|
|
#!/usr/bin/python
|
|
|
|
## @file
|
|
|
|
# Firmware Configuration Editor (FCE) from https://firmware.intel.com/develop
|
|
|
|
# can parse BIOS image and generate Firmware Configuration file.
|
|
|
|
# This script bases on Firmware Configuration file, and generate the structure
|
|
|
|
# PCD setting in DEC/DSC/INF files.
|
|
|
|
#
|
|
|
|
# Copyright (c) 2018, 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.
|
|
|
|
#
|
|
|
|
|
|
|
|
'''
|
|
|
|
ConvertFceToStructurePcd
|
|
|
|
'''
|
|
|
|
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
import datetime
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
#
|
|
|
|
# Globals for help information
|
|
|
|
#
|
|
|
|
__prog__ = 'ConvertFceToStructurePcd'
|
|
|
|
__version__ = '%s Version %s' % (__prog__, '0.1 ')
|
|
|
|
__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'
|
|
|
|
__description__ = 'Generate Structure PCD in DEC/DSC/INF based on Firmware Configuration.\n'
|
|
|
|
|
|
|
|
|
|
|
|
dscstatement='''[Defines]
|
|
|
|
VPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E08
|
|
|
|
|
|
|
|
[SkuIds]
|
|
|
|
0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.
|
|
|
|
|
|
|
|
[DefaultStores]
|
|
|
|
0|STANDARD # UEFI Standard default 0|STANDARD is reserved.
|
|
|
|
1|MANUFACTURING # UEFI Manufacturing default 1|MANUFACTURING is reserved.
|
|
|
|
|
|
|
|
[PcdsDynamicExVpd.common.DEFAULT]
|
|
|
|
gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|*
|
|
|
|
'''
|
|
|
|
|
|
|
|
decstatement = '''[Guids]
|
|
|
|
gStructPcdTokenSpaceGuid = {0x3f1406f4, 0x2b, 0x487a, {0x8b, 0x69, 0x74, 0x29, 0x1b, 0x36, 0x16, 0xf4}}
|
|
|
|
|
|
|
|
[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]
|
|
|
|
'''
|
|
|
|
|
|
|
|
infstatement = '''[Pcd]
|
|
|
|
'''
|
|
|
|
|
|
|
|
SECTION='PcdsDynamicHii'
|
|
|
|
PCD_NAME='gStructPcdTokenSpaceGuid.Pcd'
|
|
|
|
|
|
|
|
WARNING=[]
|
|
|
|
ERRORMSG=[]
|
|
|
|
|
|
|
|
class parser_lst(object):
|
|
|
|
|
|
|
|
def __init__(self,filelist):
|
|
|
|
self._ignore=['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64']
|
|
|
|
self.file=filelist
|
|
|
|
self.text=self.megre_lst()[0]
|
|
|
|
self.content=self.megre_lst()[1]
|
|
|
|
|
|
|
|
def megre_lst(self):
|
|
|
|
alltext=''
|
|
|
|
content={}
|
|
|
|
for file in self.file:
|
|
|
|
with open(file,'r') as f:
|
|
|
|
read =f.read()
|
|
|
|
alltext += read
|
|
|
|
content[file]=read
|
|
|
|
return alltext,content
|
|
|
|
|
|
|
|
def struct_lst(self):#{struct:lst file}
|
|
|
|
structs_file={}
|
|
|
|
name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
|
|
|
|
for i in list(self.content.keys()):
|
|
|
|
structs= name_format.findall(self.content[i])
|
|
|
|
if structs:
|
|
|
|
for j in structs:
|
|
|
|
if j not in self._ignore:
|
|
|
|
structs_file[j]=i
|
|
|
|
else:
|
|
|
|
print("%s"%structs)
|
|
|
|
return structs_file
|
|
|
|
|
|
|
|
def struct(self):#struct:{offset:name}
|
|
|
|
unit_num = re.compile('(\d+)')
|
|
|
|
offset1_re = re.compile('(\d+)\[')
|
|
|
|
pcdname_num_re = re.compile('\w+\[(\S+)\]')
|
|
|
|
pcdname_re = re.compile('\](.*)\<')
|
|
|
|
pcdname2_re = re.compile('(\w+)\[')
|
|
|
|
uint_re = re.compile('\<(\S+)\>')
|
|
|
|
name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
|
|
|
|
name=name_format.findall(self.text)
|
|
|
|
info={}
|
|
|
|
unparse=[]
|
|
|
|
if name:
|
|
|
|
tmp_n = [n for n in name if n not in self._ignore]
|
|
|
|
name = list(set(tmp_n))
|
|
|
|
name.sort(key = tmp_n.index)
|
|
|
|
name.reverse()
|
|
|
|
#name=list(set(name).difference(set(self._ignore)))
|
|
|
|
for struct in name:
|
|
|
|
s_re = re.compile(r'struct %s :(.*?)};'% struct, re.S)
|
|
|
|
content = s_re.search(self.text)
|
|
|
|
if content:
|
|
|
|
tmp_dict = {}
|
|
|
|
text = content.group().split('+')
|
|
|
|
for line in text[1:]:
|
|
|
|
offset = offset1_re.findall(line)
|
|
|
|
t_name = pcdname_re.findall(line)
|
|
|
|
uint = uint_re.findall(line)
|
|
|
|
if offset and uint:
|
|
|
|
offset = offset[0]
|
|
|
|
uint = uint[0]
|
|
|
|
if t_name:
|
|
|
|
t_name = t_name[0].strip()
|
|
|
|
if (' ' in t_name) or ("=" in t_name) or (";" in t_name) or("\\" in name) or (t_name ==''):
|
|
|
|
WARNING.append("Warning:Invalid Pcd name '%s' for Offset %s in struct %s" % (t_name,offset, struct))
|
|
|
|
else:
|
|
|
|
if '[' in t_name:
|
|
|
|
if uint in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
|
|
|
|
offset = int(offset, 10)
|
|
|
|
tmp_name = pcdname2_re.findall(t_name)[0] + '[0]'
|
|
|
|
tmp_dict[offset] = tmp_name
|
|
|
|
pcdname_num = int(pcdname_num_re.findall(t_name)[0],10)
|
|
|
|
uint = int(unit_num.findall(uint)[0],10)
|
|
|
|
bit = uint / 8
|
|
|
|
for i in range(1, pcdname_num):
|
|
|
|
offset += bit
|
|
|
|
tmp_name = pcdname2_re.findall(t_name)[0] + '[%s]' % i
|
|
|
|
tmp_dict[offset] = tmp_name
|
|
|
|
else:
|
|
|
|
tmp_name = pcdname2_re.findall(t_name)[0]
|
|
|
|
pcdname_num = pcdname_num_re.findall(t_name)[0]
|
|
|
|
line = [offset,tmp_name,pcdname_num,uint]
|
|
|
|
line.append(struct)
|
|
|
|
unparse.append(line)
|
|
|
|
else:
|
|
|
|
if uint not in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
|
|
|
|
line = [offset, t_name, 0, uint]
|
|
|
|
line.append(struct)
|
|
|
|
unparse.append(line)
|
|
|
|
else:
|
|
|
|
offset = int(offset,10)
|
|
|
|
tmp_dict[offset] = t_name
|
|
|
|
info[struct] = tmp_dict
|
|
|
|
if len(unparse) != 0:
|
|
|
|
for u in unparse:
|
|
|
|
if u[3] in list(info.keys()):
|
|
|
|
unpar = self.nameISstruct(u,info[u[3]])
|
|
|
|
info[u[4]]= dict(list(info[u[4]].items())+list(unpar[u[4]].items()))
|
|
|
|
else:
|
|
|
|
print("ERROR: No struct name found in %s" % self.file)
|
|
|
|
ERRORMSG.append("ERROR: No struct name found in %s" % self.file)
|
|
|
|
return info
|
|
|
|
|
|
|
|
|
|
|
|
def nameISstruct(self,line,key_dict):
|
|
|
|
dict={}
|
|
|
|
dict2={}
|
|
|
|
s_re = re.compile(r'struct %s :(.*?)};' % line[3], re.S)
|
|
|
|
size_re = re.compile(r'mTotalSize \[(\S+)\]')
|
|
|
|
content = s_re.search(self.text)
|
|
|
|
if content:
|
|
|
|
s_size = size_re.findall(content.group())[0]
|
|
|
|
else:
|
|
|
|
s_size = '0'
|
|
|
|
print("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
|
|
|
|
ERRORMSG.append("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
|
|
|
|
size = int(line[0], 10)
|
|
|
|
if line[2] != 0:
|
|
|
|
for j in range(0, int(line[2], 10)):
|
|
|
|
for k in list(key_dict.keys()):
|
|
|
|
offset = size + k
|
|
|
|
name ='%s.%s' %((line[1]+'[%s]'%j),key_dict[k])
|
|
|
|
dict[offset] = name
|
|
|
|
size = int(s_size,16)+size
|
|
|
|
elif line[2] == 0:
|
|
|
|
for k in list(key_dict.keys()):
|
|
|
|
offset = size + k
|
|
|
|
name = '%s.%s' % (line[1], key_dict[k])
|
|
|
|
dict[offset] = name
|
|
|
|
dict2[line[4]] = dict
|
|
|
|
return dict2
|
|
|
|
|
|
|
|
def efivarstore_parser(self):
|
|
|
|
efivarstore_format = re.compile(r'efivarstore.*?;', re.S)
|
|
|
|
struct_re = re.compile(r'efivarstore(.*?),',re.S)
|
|
|
|
name_re = re.compile(r'name=(\w+)')
|
|
|
|
efivarstore_dict={}
|
|
|
|
efitxt = efivarstore_format.findall(self.text)
|
|
|
|
for i in efitxt:
|
|
|
|
struct = struct_re.findall(i.replace(' ',''))
|
|
|
|
name = name_re.findall(i.replace(' ',''))
|
|
|
|
if struct and name:
|
|
|
|
efivarstore_dict[name[0]]=struct[0]
|
|
|
|
else:
|
|
|
|
print("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
|
|
|
|
ERRORMSG.append("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
|
|
|
|
return efivarstore_dict
|
|
|
|
|
|
|
|
class Config(object):
|
|
|
|
|
|
|
|
def __init__(self,Config):
|
|
|
|
self.config=Config
|
|
|
|
|
|
|
|
#Parser .config file,return list[offset,name,guid,value,help]
|
|
|
|
def config_parser(self):
|
|
|
|
ids_re =re.compile('_ID:(\d+)',re.S)
|
|
|
|
id_re= re.compile('\s+')
|
|
|
|
info = []
|
|
|
|
info_dict={}
|
|
|
|
with open(self.config, 'r') as text:
|
|
|
|
read = text.read()
|
|
|
|
if 'DEFAULT_ID:' in read:
|
|
|
|
all_txt = read.split('FCEKEY DEFAULT')
|
|
|
|
for i in all_txt[1:]:
|
|
|
|
part = [] #save all infomation for DEFAULT_ID
|
|
|
|
str_id=''
|
|
|
|
ids = ids_re.findall(i.replace(' ',''))
|
|
|
|
for m in ids:
|
|
|
|
str_id +=m+'_'
|
|
|
|
str_id=str_id[:-1]
|
|
|
|
part.append(ids)
|
|
|
|
section = i.split('\nQ') #split with '\nQ ' to get every block
|
|
|
|
part +=self.section_parser(section)
|
|
|
|
info_dict[str_id] = self.section_parser(section)
|
|
|
|
info.append(part)
|
|
|
|
else:
|
|
|
|
part = []
|
|
|
|
id=('0','0')
|
|
|
|
str_id='0_0'
|
|
|
|
part.append(id)
|
|
|
|
section = read.split('\nQ')
|
|
|
|
part +=self.section_parser(section)
|
|
|
|
info_dict[str_id] = self.section_parser(section)
|
|
|
|
info.append(part)
|
|
|
|
return info_dict
|
|
|
|
|
|
|
|
def eval_id(self,id):
|
|
|
|
id = id.split("_")
|
|
|
|
default_id=id[0:len(id)//2]
|
|
|
|
platform_id=id[len(id)//2:]
|
|
|
|
text=''
|
|
|
|
for i in range(len(default_id)):
|
|
|
|
text +="%s.common.%s.%s,"%(SECTION,self.id_name(platform_id[i],'PLATFORM'),self.id_name(default_id[i],'DEFAULT'))
|
|
|
|
return '\n[%s]\n'%text[:-1]
|
|
|
|
|
|
|
|
def id_name(self,ID, flag):
|
|
|
|
platform_dict = {'0': 'DEFAULT'}
|
|
|
|
default_dict = {'0': 'STANDARD', '1': 'MANUFACTURING'}
|
|
|
|
if flag == "PLATFORM":
|
|
|
|
try:
|
|
|
|
value = platform_dict[ID]
|
|
|
|
except KeyError:
|
|
|
|
value = 'SKUID%s' % ID
|
|
|
|
elif flag == 'DEFAULT':
|
|
|
|
try:
|
|
|
|
value = default_dict[ID]
|
|
|
|
except KeyError:
|
|
|
|
value = 'DEFAULTID%s' % ID
|
|
|
|
else:
|
|
|
|
value = None
|
|
|
|
return value
|
|
|
|
|
|
|
|
def section_parser(self,section):
|
|
|
|
offset_re = re.compile(r'offset=(\w+)')
|
|
|
|
name_re = re.compile(r'name=(\S+)')
|
|
|
|
guid_re = re.compile(r'guid=(\S+)')
|
|
|
|
# help_re = re.compile(r'help = (.*)')
|
|
|
|
attribute_re=re.compile(r'attribute=(\w+)')
|
|
|
|
value_re = re.compile(r'(//.*)')
|
|
|
|
part = []
|
|
|
|
for x in section[1:]:
|
|
|
|
line=x.split('\n')[0]
|
|
|
|
line=value_re.sub('',line) #delete \\... in "Q...." line
|
|
|
|
list1=line.split(' ')
|
|
|
|
value=self.value_parser(list1)
|
|
|
|
offset = offset_re.findall(x.replace(' ',''))
|
|
|
|
name = name_re.findall(x.replace(' ',''))
|
|
|
|
guid = guid_re.findall(x.replace(' ',''))
|
|
|
|
attribute =attribute_re.findall(x.replace(' ',''))
|
|
|
|
if offset and name and guid and value and attribute:
|
|
|
|
if attribute[0] in ['0x3','0x7']:
|
|
|
|
offset = int(offset[0], 16)
|
|
|
|
#help = help_re.findall(x)
|
|
|
|
text = offset, name[0], guid[0], value, attribute[0]
|
|
|
|
part.append(text)
|
|
|
|
return(part)
|
|
|
|
|
|
|
|
def value_parser(self, list1):
|
|
|
|
list1 = [t for t in list1 if t != ''] # remove '' form list
|
|
|
|
first_num = int(list1[0], 16)
|
|
|
|
if list1[first_num + 1] == 'STRING': # parser STRING
|
2018-10-30 15:59:45 +01:00
|
|
|
if list1[-1] == '""':
|
|
|
|
value = "{0x0, 0x0}"
|
|
|
|
else:
|
|
|
|
value = 'L%s' % list1[-1]
|
2018-07-17 05:42:21 +02:00
|
|
|
elif list1[first_num + 1] == 'ORDERED_LIST': # parser ORDERED_LIST
|
|
|
|
value_total = int(list1[first_num + 2])
|
|
|
|
list2 = list1[-value_total:]
|
|
|
|
tmp = []
|
|
|
|
line = ''
|
|
|
|
for i in list2:
|
|
|
|
if len(i) % 2 == 0 and len(i) != 2:
|
|
|
|
for m in range(0, len(i) // 2):
|
|
|
|
tmp.append('0x%02x' % (int('0x%s' % i, 16) >> m * 8 & 0xff))
|
|
|
|
else:
|
|
|
|
tmp.append('0x%s' % i)
|
|
|
|
for i in tmp:
|
|
|
|
line += '%s,' % i
|
|
|
|
value = '{%s}' % line[:-1]
|
|
|
|
else:
|
|
|
|
value = "0x%01x" % int(list1[-1], 16)
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
#parser Guid file, get guid name form guid value
|
|
|
|
class GUID(object):
|
|
|
|
|
|
|
|
def __init__(self,path):
|
|
|
|
self.path = path
|
|
|
|
self.guidfile = self.gfile()
|
|
|
|
self.guiddict = self.guid_dict()
|
|
|
|
|
|
|
|
def gfile(self):
|
|
|
|
for root, dir, file in os.walk(self.path, topdown=True, followlinks=False):
|
|
|
|
if 'FV' in dir:
|
|
|
|
gfile = os.path.join(root,'Fv','Guid.xref')
|
|
|
|
if os.path.isfile(gfile):
|
|
|
|
return gfile
|
|
|
|
else:
|
|
|
|
print("ERROR: Guid.xref file not found")
|
|
|
|
ERRORMSG.append("ERROR: Guid.xref file not found")
|
|
|
|
exit()
|
|
|
|
|
|
|
|
def guid_dict(self):
|
|
|
|
guiddict={}
|
|
|
|
with open(self.guidfile,'r') as file:
|
|
|
|
lines = file.readlines()
|
|
|
|
guidinfo=lines
|
|
|
|
for line in guidinfo:
|
|
|
|
list=line.strip().split(' ')
|
|
|
|
if list:
|
|
|
|
if len(list)>1:
|
|
|
|
guiddict[list[0].upper()]=list[1]
|
|
|
|
elif list[0] != ''and len(list)==1:
|
|
|
|
print("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
|
|
|
|
ERRORMSG.append("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
|
|
|
|
else:
|
|
|
|
print("ERROR: No data in %s" %self.guidfile)
|
|
|
|
ERRORMSG.append("ERROR: No data in %s" %self.guidfile)
|
|
|
|
return guiddict
|
|
|
|
|
|
|
|
def guid_parser(self,guid):
|
|
|
|
if guid.upper() in self.guiddict:
|
|
|
|
return self.guiddict[guid.upper()]
|
|
|
|
else:
|
|
|
|
print("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
|
|
|
|
ERRORMSG.append("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
|
|
|
|
return guid
|
|
|
|
|
|
|
|
class PATH(object):
|
|
|
|
|
|
|
|
def __init__(self,path):
|
|
|
|
self.path=path
|
|
|
|
self.rootdir=self.get_root_dir()
|
|
|
|
self.usefuldir=[]
|
|
|
|
self.lstinf = {}
|
|
|
|
for path in self.rootdir:
|
|
|
|
for o_root, o_dir, o_file in os.walk(os.path.join(path, "OUTPUT"), topdown=True, followlinks=False):
|
|
|
|
for INF in o_file:
|
|
|
|
if os.path.splitext(INF)[1] == '.inf':
|
|
|
|
for l_root, l_dir, l_file in os.walk(os.path.join(path, "DEBUG"), topdown=True,
|
|
|
|
followlinks=False):
|
|
|
|
for LST in l_file:
|
|
|
|
if os.path.splitext(LST)[1] == '.lst':
|
|
|
|
self.lstinf[os.path.join(l_root, LST)] = os.path.join(o_root, INF)
|
|
|
|
self.usefuldir.append(path)
|
|
|
|
|
|
|
|
def get_root_dir(self):
|
|
|
|
rootdir=[]
|
|
|
|
for root,dir,file in os.walk(self.path,topdown=True,followlinks=False):
|
|
|
|
if "OUTPUT" in root:
|
|
|
|
updir=root.split("OUTPUT",1)[0]
|
|
|
|
rootdir.append(updir)
|
|
|
|
rootdir=list(set(rootdir))
|
|
|
|
return rootdir
|
|
|
|
|
|
|
|
def lst_inf(self):
|
|
|
|
return self.lstinf
|
|
|
|
|
|
|
|
def package(self):
|
|
|
|
package={}
|
|
|
|
package_re=re.compile(r'Packages\.\w+]\n(.*)',re.S)
|
|
|
|
for i in list(self.lstinf.values()):
|
|
|
|
with open(i,'r') as inf:
|
|
|
|
read=inf.read()
|
|
|
|
section=read.split('[')
|
|
|
|
for j in section:
|
|
|
|
p=package_re.findall(j)
|
|
|
|
if p:
|
|
|
|
package[i]=p[0].rstrip()
|
|
|
|
return package
|
|
|
|
|
|
|
|
def header(self,struct):
|
|
|
|
header={}
|
|
|
|
head_re = re.compile(r'} %s;[\s\S\n]+h{1}"'%struct,re.M|re.S)
|
|
|
|
head_re2 = re.compile(r'#line[\s\d]+"(\S+h)"')
|
|
|
|
for i in list(self.lstinf.keys()):
|
|
|
|
with open(i,'r') as lst:
|
|
|
|
read = lst.read()
|
|
|
|
h = head_re.findall(read)
|
|
|
|
if h:
|
|
|
|
head=head_re2.findall(h[0])
|
|
|
|
if head:
|
|
|
|
format = head[0].replace('\\\\','/').replace('\\','/')
|
|
|
|
name =format.split('/')[-1]
|
|
|
|
head = self.makefile(name).replace('\\','/')
|
|
|
|
header[struct] = head
|
|
|
|
return header
|
|
|
|
|
|
|
|
def makefile(self,filename):
|
|
|
|
re_format = re.compile(r'DEBUG_DIR.*(?:\S+Pkg)\\(.*\\%s)'%filename)
|
|
|
|
for i in self.usefuldir:
|
|
|
|
with open(os.path.join(i,'Makefile'),'r') as make:
|
|
|
|
read = make.read()
|
|
|
|
dir = re_format.findall(read)
|
|
|
|
if dir:
|
|
|
|
return dir[0]
|
|
|
|
|
|
|
|
class mainprocess(object):
|
|
|
|
|
|
|
|
def __init__(self,InputPath,Config,OutputPath):
|
|
|
|
self.init = 0xFCD00000
|
|
|
|
self.inputpath = os.path.abspath(InputPath)
|
|
|
|
self.outputpath = os.path.abspath(OutputPath)
|
|
|
|
self.LST = PATH(self.inputpath)
|
|
|
|
self.lst_dict = self.LST.lst_inf()
|
|
|
|
self.Config = Config
|
|
|
|
self.attribute_dict = {'0x3': 'NV, BS', '0x7': 'NV, BS, RT'}
|
|
|
|
self.guid = GUID(self.inputpath)
|
|
|
|
self.header={}
|
|
|
|
|
|
|
|
def main(self):
|
|
|
|
conf=Config(self.Config)
|
|
|
|
config_dict=conf.config_parser() #get {'0_0':[offset,name,guid,value,attribute]...,'1_0':....}
|
|
|
|
lst=parser_lst(list(self.lst_dict.keys()))
|
|
|
|
efi_dict=lst.efivarstore_parser() #get {name:struct} form lst file
|
|
|
|
keys=sorted(config_dict.keys())
|
|
|
|
all_struct=lst.struct()
|
|
|
|
stru_lst=lst.struct_lst()
|
|
|
|
title_list=[]
|
|
|
|
info_list=[]
|
|
|
|
header_list=[]
|
|
|
|
inf_list =[]
|
|
|
|
for i in stru_lst:
|
|
|
|
tmp = self.LST.header(i)
|
|
|
|
self.header.update(tmp)
|
|
|
|
for id_key in keys:
|
|
|
|
tmp_id=[id_key] #['0_0',[(struct,[name...]),(struct,[name...])]]
|
|
|
|
tmp_info={} #{name:struct}
|
|
|
|
for section in config_dict[id_key]:
|
|
|
|
c_offset,c_name,c_guid,c_value,c_attribute = section
|
|
|
|
if c_name in efi_dict:
|
|
|
|
struct = efi_dict[c_name]
|
|
|
|
title='%s%s|L"%s"|%s|0x00||%s\n'%(PCD_NAME,c_name,c_name,self.guid.guid_parser(c_guid),self.attribute_dict[c_attribute])
|
|
|
|
if struct in all_struct:
|
|
|
|
lstfile = stru_lst[struct]
|
|
|
|
struct_dict=all_struct[struct]
|
|
|
|
try:
|
|
|
|
title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, self.header[struct], self.LST.package()[self.lst_dict[lstfile]])
|
|
|
|
except KeyError:
|
|
|
|
WARNING.append("Warning: No <HeaderFiles> for struct %s"%struct)
|
|
|
|
title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, '', self.LST.package()[self.lst_dict[lstfile]])
|
|
|
|
header_list.append(title2)
|
|
|
|
else:
|
|
|
|
struct_dict ={}
|
|
|
|
print("ERROR: Struct %s can't found in lst file" %struct)
|
|
|
|
ERRORMSG.append("ERROR: Struct %s can't found in lst file" %struct)
|
|
|
|
if c_offset in struct_dict:
|
|
|
|
offset_name=struct_dict[c_offset]
|
|
|
|
info = "%s%s.%s|%s\n"%(PCD_NAME,c_name,offset_name,c_value)
|
|
|
|
inf = "%s%s\n"%(PCD_NAME,c_name)
|
|
|
|
inf_list.append(inf)
|
|
|
|
tmp_info[info]=title
|
|
|
|
else:
|
|
|
|
print("ERROR: Can't find offset %s with struct name %s"%(c_offset,struct))
|
|
|
|
ERRORMSG.append("ERROR: Can't find offset %s with name %s"%(c_offset,struct))
|
|
|
|
else:
|
|
|
|
print("ERROR: Can't find name %s in lst file"%(c_name))
|
|
|
|
ERRORMSG.append("ERROR: Can't find name %s in lst file"%(c_name))
|
|
|
|
tmp_id.append(list(self.reverse_dict(tmp_info).items()))
|
|
|
|
id,tmp_title_list,tmp_info_list = self.read_list(tmp_id)
|
|
|
|
title_list +=tmp_title_list
|
|
|
|
info_list.append(tmp_info_list)
|
|
|
|
inf_list = self.del_repeat(inf_list)
|
|
|
|
header_list = self.plus(self.del_repeat(header_list))
|
|
|
|
title_all=list(set(title_list))
|
2018-10-30 15:59:45 +01:00
|
|
|
info_list = self.remove_bracket(self.del_repeat(info_list))
|
2018-07-17 05:42:21 +02:00
|
|
|
for i in range(len(info_list)-1,-1,-1):
|
|
|
|
if len(info_list[i]) == 0:
|
|
|
|
info_list.remove(info_list[i])
|
|
|
|
return keys,title_all,info_list,header_list,inf_list
|
|
|
|
|
2018-10-30 15:59:45 +01:00
|
|
|
def remove_bracket(self,List):
|
|
|
|
for i in List:
|
|
|
|
for j in i:
|
|
|
|
tmp = j.split("|")
|
|
|
|
if (('L"' in j) and ("[" in j)) or (tmp[1].strip() == '{0x0, 0x0}'):
|
|
|
|
tmp[0] = tmp[0][:tmp[0].index('[')]
|
|
|
|
List[List.index(i)][i.index(j)] = "|".join(tmp)
|
|
|
|
else:
|
|
|
|
List[List.index(i)][i.index(j)] = j
|
|
|
|
return List
|
2018-07-17 05:42:21 +02:00
|
|
|
|
|
|
|
def write_all(self):
|
|
|
|
title_flag=1
|
|
|
|
info_flag=1
|
|
|
|
if not os.path.isdir(self.outputpath):
|
|
|
|
os.makedirs(self.outputpath)
|
|
|
|
decwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dec'))
|
|
|
|
dscwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dsc'))
|
|
|
|
infwrite = write2file(os.path.join(self.outputpath, 'StructurePcd.inf'))
|
|
|
|
conf = Config(self.Config)
|
|
|
|
ids,title,info,header,inf=self.main()
|
|
|
|
decwrite.add2file(decstatement)
|
|
|
|
decwrite.add2file(header)
|
|
|
|
infwrite.add2file(infstatement)
|
|
|
|
infwrite.add2file(inf)
|
|
|
|
dscwrite.add2file(dscstatement)
|
|
|
|
for id in ids:
|
|
|
|
dscwrite.add2file(conf.eval_id(id))
|
|
|
|
if title_flag:
|
|
|
|
dscwrite.add2file(title)
|
|
|
|
title_flag=0
|
|
|
|
if len(info) == 1:
|
|
|
|
dscwrite.add2file(info)
|
|
|
|
elif len(info) == 2:
|
|
|
|
if info_flag:
|
|
|
|
dscwrite.add2file(info[0])
|
|
|
|
info_flag =0
|
|
|
|
else:
|
|
|
|
dscwrite.add2file(info[1])
|
|
|
|
|
|
|
|
def del_repeat(self,List):
|
|
|
|
if len(List) == 1 or len(List) == 0:
|
|
|
|
return List
|
|
|
|
else:
|
|
|
|
if type(List[0]) != type('xxx'):
|
|
|
|
alist=[]
|
|
|
|
for i in range(len(List)):
|
|
|
|
if i == 0:
|
|
|
|
alist.append(List[0])
|
|
|
|
else:
|
|
|
|
plist = []
|
|
|
|
for j in range(i):
|
|
|
|
plist += List[j]
|
|
|
|
alist.append(self.__del(list(set(plist)), List[i]))
|
|
|
|
return alist
|
|
|
|
else:
|
|
|
|
return list(set(List))
|
|
|
|
|
|
|
|
|
|
|
|
def __del(self,list1,list2):
|
|
|
|
return list(set(list2).difference(set(list1)))
|
|
|
|
|
|
|
|
def reverse_dict(self,dict):
|
|
|
|
data={}
|
|
|
|
for i in list(dict.items()):
|
|
|
|
if i[1] not in list(data.keys()):
|
|
|
|
data[i[1]]=[i[0]]
|
|
|
|
else:
|
|
|
|
data[i[1]].append(i[0])
|
|
|
|
return data
|
|
|
|
|
|
|
|
def read_list(self,list):
|
|
|
|
title_list=[]
|
|
|
|
info_list=[]
|
|
|
|
for i in list[1]:
|
|
|
|
title_list.append(i[0])
|
|
|
|
for j in i[1]:
|
|
|
|
info_list.append(j)
|
|
|
|
return list[0],title_list,info_list
|
|
|
|
|
|
|
|
def plus(self,list):
|
|
|
|
nums=[]
|
|
|
|
for i in list:
|
|
|
|
if type(i) != type([0]):
|
|
|
|
self.init += 1
|
|
|
|
num = "0x%01x" % self.init
|
|
|
|
j=i.replace('0xFCD00000',num.upper())
|
|
|
|
nums.append(j)
|
|
|
|
return nums
|
|
|
|
|
|
|
|
class write2file(object):
|
|
|
|
|
|
|
|
def __init__(self,Output):
|
|
|
|
self.output=Output
|
|
|
|
self.text=''
|
|
|
|
if os.path.exists(self.output):
|
|
|
|
os.remove(self.output)
|
|
|
|
|
|
|
|
def add2file(self,content):
|
|
|
|
self.text = ''
|
|
|
|
with open(self.output,'a+') as file:
|
|
|
|
file.write(self.__gen(content))
|
|
|
|
|
|
|
|
def __gen(self,content):
|
|
|
|
if type(content) == type(''):
|
|
|
|
return content
|
|
|
|
elif type(content) == type([0,0])or type(content) == type((0,0)):
|
|
|
|
return self.__readlist(content)
|
|
|
|
elif type(content) == type({0:0}):
|
|
|
|
return self.__readdict(content)
|
|
|
|
|
|
|
|
def __readlist(self,list):
|
|
|
|
for i in list:
|
|
|
|
if type(i) == type([0,0])or type(i) == type((0,0)):
|
|
|
|
self.__readlist(i)
|
|
|
|
elif type(i) == type('') :
|
|
|
|
self.text +=i
|
|
|
|
return self.text
|
|
|
|
|
|
|
|
def __readdict(self,dict):
|
|
|
|
content=list(dict.items())
|
|
|
|
return self.__readlist(content)
|
|
|
|
|
|
|
|
def stamp():
|
|
|
|
return datetime.datetime.now()
|
|
|
|
|
|
|
|
def dtime(start,end,id=None):
|
|
|
|
if id:
|
|
|
|
pass
|
|
|
|
print("%s time:%s" % (id,str(end - start)))
|
|
|
|
else:
|
|
|
|
print("Total time:%s" %str(end-start)[:-7])
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
start = stamp()
|
|
|
|
parser = argparse.ArgumentParser(prog = __prog__,
|
|
|
|
description = __description__ + __copyright__,
|
|
|
|
conflict_handler = 'resolve')
|
|
|
|
parser.add_argument('-v', '--version', action = 'version',version = __version__, help="show program's version number and exit")
|
|
|
|
parser.add_argument('-p', '--path', metavar='PATH', dest='path', help="platform build output directory")
|
|
|
|
parser.add_argument('-c', '--config',metavar='FILENAME', dest='config', help="firmware configuration file")
|
|
|
|
parser.add_argument('-o', '--outputdir', metavar='PATH', dest='output', help="output directoy")
|
|
|
|
options = parser.parse_args()
|
|
|
|
if options.config:
|
|
|
|
if options.path:
|
|
|
|
if options.output:
|
|
|
|
run = mainprocess(options.path, options.config, options.output)
|
|
|
|
print("Running...")
|
|
|
|
run.write_all()
|
|
|
|
if WARNING:
|
|
|
|
warning = list(set(WARNING))
|
|
|
|
for j in warning:
|
|
|
|
print(j)
|
|
|
|
if ERRORMSG:
|
|
|
|
ERROR = list(set(ERRORMSG))
|
|
|
|
with open("ERROR.log", 'w+') as error:
|
|
|
|
for i in ERROR:
|
|
|
|
error.write(i + '\n')
|
|
|
|
print("Some error find, error log in ERROR.log")
|
|
|
|
print('Finished, Output files in directory %s'%os.path.abspath(options.output))
|
|
|
|
else:
|
|
|
|
print('Error command, no output path, use -h for help')
|
|
|
|
else:
|
|
|
|
print('Error command, no build path input, use -h for help')
|
|
|
|
else:
|
|
|
|
print('Error command, no output file, use -h for help')
|
|
|
|
end = stamp()
|
|
|
|
dtime(start, end)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|