1# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 2# This program and the accompanying materials 3# are licensed and made available under the terms and conditions of the BSD License 4# which accompanies this distribution. The full text of the license may be found at 5# http://opensource.org/licenses/bsd-license.php 6# 7# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 8# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 9 10# 11# This file is used to collect the Variable checking information 12# 13 14# # 15# Import Modules 16# 17import os 18from Common.RangeExpression import RangeExpression 19from Common.Misc import * 20from StringIO import StringIO 21from struct import pack 22 23class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object): 24 def __init__(self): 25 self.var_check_info = [] 26 27 def push_back(self, var_check_tab): 28 for tab in self.var_check_info: 29 if tab.equal(var_check_tab): 30 tab.merge(var_check_tab) 31 break 32 else: 33 self.var_check_info.append(var_check_tab) 34 35 def dump(self, dest, Phase): 36 37 FormatMap = {} 38 FormatMap[1] = "=B" 39 FormatMap[2] = "=H" 40 FormatMap[4] = "=L" 41 FormatMap[8] = "=Q" 42 43 if not os.path.isabs(dest): 44 return 45 if not os.path.exists(dest): 46 os.mkdir(dest) 47 BinFileName = "PcdVarCheck.bin" 48 BinFilePath = os.path.join(dest, BinFileName) 49 Buffer = '' 50 index = 0 51 for var_check_tab in self.var_check_info: 52 index += 1 53 realLength = 0 54 realLength += 32 55 Name = var_check_tab.Name[1:-1] 56 NameChars = Name.split(",") 57 realLength += len(NameChars) 58 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): 59 realLength += (4 - (realLength % 4)) 60 itemIndex = 0 61 for item in var_check_tab.validtab: 62 itemIndex += 1 63 realLength += 5 64 for v_data in item.data: 65 if type(v_data) in (int, long): 66 realLength += item.StorageWidth 67 else: 68 realLength += item.StorageWidth 69 realLength += item.StorageWidth 70 if (index == len(self.var_check_info)) : 71 if (itemIndex < len(var_check_tab.validtab)) and realLength % 4: 72 realLength += (4 - (realLength % 4)) 73 else: 74 if realLength % 4: 75 realLength += (4 - (realLength % 4)) 76 var_check_tab.Length = realLength 77 realLength = 0 78 index = 0 79 for var_check_tab in self.var_check_info: 80 index += 1 81 82 b = pack("=H", var_check_tab.Revision) 83 Buffer += b 84 realLength += 2 85 86 b = pack("=H", var_check_tab.HeaderLength) 87 Buffer += b 88 realLength += 2 89 90 b = pack("=L", var_check_tab.Length) 91 Buffer += b 92 realLength += 4 93 94 b = pack("=B", var_check_tab.Type) 95 Buffer += b 96 realLength += 1 97 98 for i in range(0, 3): 99 b = pack("=B", var_check_tab.Reserved) 100 Buffer += b 101 realLength += 1 102 103 b = pack("=L", var_check_tab.Attributes) 104 Buffer += b 105 realLength += 4 106 107 Guid = var_check_tab.Guid 108 b = pack('=LHHBBBBBBBB', 109 Guid[0], 110 Guid[1], 111 Guid[2], 112 Guid[3], 113 Guid[4], 114 Guid[5], 115 Guid[6], 116 Guid[7], 117 Guid[8], 118 Guid[9], 119 Guid[10], 120 ) 121 Buffer += b 122 realLength += 16 123 124 Name = var_check_tab.Name[1:-1] 125 NameChars = Name.split(",") 126 for NameChar in NameChars: 127 NameCharNum = int(NameChar, 16) 128 b = pack("=B", NameCharNum) 129 Buffer += b 130 realLength += 1 131 132 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): 133 for i in range(4 - (realLength % 4)): 134 b = pack("=B", var_check_tab.pad) 135 Buffer += b 136 realLength += 1 137 itemIndex = 0 138 for item in var_check_tab.validtab: 139 itemIndex += 1 140 141 b = pack("=B", item.Type) 142 Buffer += b 143 realLength += 1 144 145 b = pack("=B", item.Length) 146 Buffer += b 147 realLength += 1 148 149 b = pack("=H", int(item.VarOffset, 16)) 150 Buffer += b 151 realLength += 2 152 153 b = pack("=B", item.StorageWidth) 154 Buffer += b 155 realLength += 1 156 for v_data in item.data: 157 if type(v_data) in (int, long): 158 b = pack(FormatMap[item.StorageWidth], v_data) 159 Buffer += b 160 realLength += item.StorageWidth 161 else: 162 b = pack(FormatMap[item.StorageWidth], v_data[0]) 163 Buffer += b 164 realLength += item.StorageWidth 165 b = pack(FormatMap[item.StorageWidth], v_data[1]) 166 Buffer += b 167 realLength += item.StorageWidth 168 169 if (index == len(self.var_check_info)) : 170 if (itemIndex < len(var_check_tab.validtab)) and realLength % 4: 171 for i in range(4 - (realLength % 4)): 172 b = pack("=B", var_check_tab.pad) 173 Buffer += b 174 realLength += 1 175 else: 176 if realLength % 4: 177 for i in range(4 - (realLength % 4)): 178 b = pack("=B", var_check_tab.pad) 179 Buffer += b 180 realLength += 1 181 182 DbFile = StringIO() 183 if Phase == 'DXE' and os.path.exists(BinFilePath): 184 BinFile = open(BinFilePath, "rb") 185 BinBuffer = BinFile.read() 186 BinFile.close() 187 BinBufferSize = len(BinBuffer) 188 if (BinBufferSize % 4): 189 for i in range(4 - (BinBufferSize % 4)): 190 b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad) 191 BinBuffer += b 192 Buffer = BinBuffer + Buffer 193 DbFile.write(Buffer) 194 SaveFileOnChange(BinFilePath, DbFile.getvalue(), True) 195 196 197class VAR_CHECK_PCD_VARIABLE_TAB(object): 198 pad = 0xDA 199 def __init__(self, TokenSpaceGuid, PcdCName): 200 self.Revision = 0x0001 201 self.HeaderLength = 0 202 self.Length = 0 # Length include this header 203 self.Type = 0 204 self.Reserved = 0 205 self.Attributes = 0x00000000 206 self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]") 207 self.Name = PcdCName 208 self.validtab = [] 209 210 def UpdateSize(self): 211 self.HeaderLength = 32 + len(self.Name.split(",")) 212 self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen() 213 214 def GetValidTabLen(self): 215 validtablen = 0 216 for item in self.validtab: 217 validtablen += item.Length 218 return validtablen 219 220 def SetAttributes(self, attributes): 221 self.Attributes = attributes 222 223 def push_back(self, valid_obj): 224 if valid_obj is not None: 225 self.validtab.append(valid_obj) 226 227 def equal(self, varchecktab): 228 if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name: 229 return True 230 else: 231 return False 232 233 def merge(self, varchecktab): 234 for validobj in varchecktab.validtab: 235 if validobj in self.validtab: 236 continue 237 self.validtab.append(validobj) 238 self.UpdateSize() 239 240 241class VAR_CHECK_PCD_VALID_OBJ(object): 242 def __init__(self, VarOffset, data, PcdDataType): 243 self.Type = 1 244 self.Length = 0 # Length include this header 245 self.VarOffset = VarOffset 246 self.StorageWidth = 0 247 self.PcdDataType = PcdDataType.strip() 248 self.rawdata = data 249 self.data = set() 250 self.ValidData = True 251 self.updateStorageWidth() 252 def updateStorageWidth(self): 253 if self.PcdDataType == "UINT8" or self.PcdDataType == "BOOLEAN": 254 self.StorageWidth = 1 255 elif self.PcdDataType == "UINT16": 256 self.StorageWidth = 2 257 elif self.PcdDataType == "UINT32": 258 self.StorageWidth = 4 259 elif self.PcdDataType == "UINT64": 260 self.StorageWidth = 8 261 else: 262 self.StorageWidth = 0 263 self.ValidData = False 264 265 def __eq__(self, validObj): 266 if self.VarOffset == validObj.VarOffset: 267 return True 268 else: 269 return False 270 271class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ): 272 def __init__(self, VarOffset, validlist, PcdDataType): 273 super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType) 274 self.Type = 1 275 self.update_data() 276 self.update_size() 277 def update_data(self): 278 valid_num_list = [] 279 data_list = [] 280 for item in self.rawdata: 281 valid_num_list.extend(item.split(',')) 282 283 for valid_num in valid_num_list: 284 valid_num = valid_num.strip() 285 286 if valid_num.startswith('0x') or valid_num.startswith('0X'): 287 data_list.append(int(valid_num, 16)) 288 else: 289 data_list.append(int(valid_num)) 290 291 292 self.data = set(data_list) 293 294 def update_size(self): 295 self.Length = 5 + len(self.data) * self.StorageWidth 296 297 298class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ): 299 def __init__(self, VarOffset, validrange, PcdDataType): 300 super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType) 301 self.Type = 2 302 self.update_data() 303 self.update_size() 304 def update_data(self): 305 RangeExpr = "" 306 data_list = [] 307 i = 0 308 for item in self.rawdata: 309 if i == 0: 310 RangeExpr = "( " + item + " )" 311 else: 312 RangeExpr = RangeExpr + "OR ( " + item + " )" 313 range_result = RangeExpression(RangeExpr, self.PcdDataType)(True) 314 for rangelist in range_result: 315 for obj in rangelist.pop(): 316 data_list.append((obj.start, obj.end)) 317 self.data = set(data_list) 318 319 def update_size(self): 320 self.Length = 5 + len(self.data) * 2 * self.StorageWidth 321 322 323class VAR_VALID_OBJECT_FACTORY(object): 324 def __init__(self): 325 pass 326 @staticmethod 327 def Get_valid_object(PcdClass, VarOffset): 328 if PcdClass.validateranges: 329 return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType) 330 if PcdClass.validlists: 331 return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType) 332 else: 333 return None 334 335if __name__ == "__main__": 336 class TestObj(object): 337 def __init__(self, number1): 338 self.number_1 = number1 339 def __eq__(self, testobj): 340 if self.number_1 == testobj.number_1: 341 return True 342 else: 343 return False 344 test1 = TestObj(1) 345 test2 = TestObj(2) 346 347 testarr = [test1, test2] 348 print TestObj(2) in testarr 349 print TestObj(2) == test2 350 351