blob: edd40a1498ffd4ffc8c5d6247d087479127c22d1 [file] [log] [blame]
# Copyright (c) 2015 - 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.
#
# This file is used to collect the Variable checking information
#
# #
# Import Modules
#
import os
from Common.RangeExpression import RangeExpression
from Common.Misc import *
from io import BytesIO
from struct import pack
from Common.DataType import *
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):
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) in (int, long):
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 = PackByteFormatGUID(Guid)
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) in (int, long):
b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data)
Buffer += b
realLength += item.StorageWidth
else:
b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data[0])
Buffer += b
realLength += item.StorageWidth
b = pack(PACK_CODE_BY_SIZE[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 = BytesIO()
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.PcdDataType = PcdDataType.strip()
self.rawdata = data
self.data = set()
try:
self.StorageWidth = MAX_SIZE_TYPE[self.PcdDataType]
self.ValidData = True
except:
self.StorageWidth = 0
self.ValidData = False
def __eq__(self, validObj):
return validObj and self.VarOffset == validObj.VarOffset
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
valid_num_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'):
self.data.add(int(valid_num, 16))
else:
self.data.add(int(valid_num))
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
RangeExpr = ""
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():
self.data.add((obj.start, obj.end))
self.Length = 5 + len(self.data) * 2 * self.StorageWidth
def GetValidationObject(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