1 # Copyright (c) 2015 - 2018, 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
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.
11 # This file is used to collect the Variable checking information
18 from Common
.RangeExpression
import RangeExpression
19 from Common
.Misc
import *
20 from StringIO
import StringIO
21 from struct
import pack
22 from Common
.DataType
import *
24 class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):
26 self
.var_check_info
= []
28 def push_back(self
, var_check_tab
):
29 for tab
in self
.var_check_info
:
30 if tab
.equal(var_check_tab
):
31 tab
.merge(var_check_tab
)
34 self
.var_check_info
.append(var_check_tab
)
36 def dump(self
, dest
, Phase
):
44 if not os
.path
.isabs(dest
):
46 if not os
.path
.exists(dest
):
48 BinFileName
= "PcdVarCheck.bin"
49 BinFilePath
= os
.path
.join(dest
, BinFileName
)
52 for var_check_tab
in self
.var_check_info
:
56 Name
= var_check_tab
.Name
[1:-1]
57 NameChars
= Name
.split(",")
58 realLength
+= len(NameChars
)
59 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):
60 realLength
+= (4 - (realLength
% 4))
62 for item
in var_check_tab
.validtab
:
65 for v_data
in item
.data
:
66 if type(v_data
) in (int, long):
67 realLength
+= item
.StorageWidth
69 realLength
+= item
.StorageWidth
70 realLength
+= item
.StorageWidth
71 if (index
== len(self
.var_check_info
)) :
72 if (itemIndex
< len(var_check_tab
.validtab
)) and realLength
% 4:
73 realLength
+= (4 - (realLength
% 4))
76 realLength
+= (4 - (realLength
% 4))
77 var_check_tab
.Length
= realLength
80 for var_check_tab
in self
.var_check_info
:
83 b
= pack("=H", var_check_tab
.Revision
)
87 b
= pack("=H", var_check_tab
.HeaderLength
)
91 b
= pack("=L", var_check_tab
.Length
)
95 b
= pack("=B", var_check_tab
.Type
)
100 b
= pack("=B", var_check_tab
.Reserved
)
104 b
= pack("=L", var_check_tab
.Attributes
)
108 Guid
= var_check_tab
.Guid
109 b
= pack('=LHHBBBBBBBB',
125 Name
= var_check_tab
.Name
[1:-1]
126 NameChars
= Name
.split(",")
127 for NameChar
in NameChars
:
128 NameCharNum
= int(NameChar
, 16)
129 b
= pack("=B", NameCharNum
)
133 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):
134 for i
in range(4 - (realLength
% 4)):
135 b
= pack("=B", var_check_tab
.pad
)
139 for item
in var_check_tab
.validtab
:
142 b
= pack("=B", item
.Type
)
146 b
= pack("=B", item
.Length
)
150 b
= pack("=H", int(item
.VarOffset
, 16))
154 b
= pack("=B", item
.StorageWidth
)
157 for v_data
in item
.data
:
158 if type(v_data
) in (int, long):
159 b
= pack(FormatMap
[item
.StorageWidth
], v_data
)
161 realLength
+= item
.StorageWidth
163 b
= pack(FormatMap
[item
.StorageWidth
], v_data
[0])
165 realLength
+= item
.StorageWidth
166 b
= pack(FormatMap
[item
.StorageWidth
], v_data
[1])
168 realLength
+= item
.StorageWidth
170 if (index
== len(self
.var_check_info
)) :
171 if (itemIndex
< len(var_check_tab
.validtab
)) and realLength
% 4:
172 for i
in range(4 - (realLength
% 4)):
173 b
= pack("=B", var_check_tab
.pad
)
178 for i
in range(4 - (realLength
% 4)):
179 b
= pack("=B", var_check_tab
.pad
)
184 if Phase
== 'DXE' and os
.path
.exists(BinFilePath
):
185 BinFile
= open(BinFilePath
, "rb")
186 BinBuffer
= BinFile
.read()
188 BinBufferSize
= len(BinBuffer
)
189 if (BinBufferSize
% 4):
190 for i
in range(4 - (BinBufferSize
% 4)):
191 b
= pack("=B", VAR_CHECK_PCD_VARIABLE_TAB
.pad
)
193 Buffer
= BinBuffer
+ Buffer
195 SaveFileOnChange(BinFilePath
, DbFile
.getvalue(), True)
198 class VAR_CHECK_PCD_VARIABLE_TAB(object):
200 def __init__(self
, TokenSpaceGuid
, PcdCName
):
201 self
.Revision
= 0x0001
202 self
.HeaderLength
= 0
203 self
.Length
= 0 # Length include this header
206 self
.Attributes
= 0x00000000
207 self
.Guid
= eval("[" + TokenSpaceGuid
.replace("{", "").replace("}", "") + "]")
211 def UpdateSize(self
):
212 self
.HeaderLength
= 32 + len(self
.Name
.split(","))
213 self
.Length
= 32 + len(self
.Name
.split(",")) + self
.GetValidTabLen()
215 def GetValidTabLen(self
):
217 for item
in self
.validtab
:
218 validtablen
+= item
.Length
221 def SetAttributes(self
, attributes
):
222 self
.Attributes
= attributes
224 def push_back(self
, valid_obj
):
225 if valid_obj
is not None:
226 self
.validtab
.append(valid_obj
)
228 def equal(self
, varchecktab
):
229 if self
.Guid
== varchecktab
.Guid
and self
.Name
== varchecktab
.Name
:
234 def merge(self
, varchecktab
):
235 for validobj
in varchecktab
.validtab
:
236 if validobj
in self
.validtab
:
238 self
.validtab
.append(validobj
)
242 class VAR_CHECK_PCD_VALID_OBJ(object):
243 def __init__(self
, VarOffset
, data
, PcdDataType
):
245 self
.Length
= 0 # Length include this header
246 self
.VarOffset
= VarOffset
247 self
.StorageWidth
= 0
248 self
.PcdDataType
= PcdDataType
.strip()
251 self
.ValidData
= True
252 self
.updateStorageWidth()
254 def updateStorageWidth(self
):
256 self
.StorageWidth
= int(MAX_SIZE_TYPE
[self
.PcdDataType
])
258 self
.StorageWidth
= 0
259 self
.ValidData
= False
261 def __eq__(self
, validObj
):
262 return validObj
and self
.VarOffset
== validObj
.VarOffset
264 class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ
):
265 def __init__(self
, VarOffset
, validlist
, PcdDataType
):
266 super(VAR_CHECK_PCD_VALID_LIST
, self
).__init
__(VarOffset
, validlist
, PcdDataType
)
270 def update_data(self
):
273 for item
in self
.rawdata
:
274 valid_num_list
.extend(item
.split(','))
276 for valid_num
in valid_num_list
:
277 valid_num
= valid_num
.strip()
279 if valid_num
.startswith('0x') or valid_num
.startswith('0X'):
280 data_list
.append(int(valid_num
, 16))
282 data_list
.append(int(valid_num
))
285 self
.data
= set(data_list
)
287 def update_size(self
):
288 self
.Length
= 5 + len(self
.data
) * self
.StorageWidth
291 class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ
):
292 def __init__(self
, VarOffset
, validrange
, PcdDataType
):
293 super(VAR_CHECK_PCD_VALID_RANGE
, self
).__init
__(VarOffset
, validrange
, PcdDataType
)
297 def update_data(self
):
301 for item
in self
.rawdata
:
303 RangeExpr
= "( " + item
+ " )"
305 RangeExpr
= RangeExpr
+ "OR ( " + item
+ " )"
306 range_result
= RangeExpression(RangeExpr
, self
.PcdDataType
)(True)
307 for rangelist
in range_result
:
308 for obj
in rangelist
.pop():
309 data_list
.append((obj
.start
, obj
.end
))
310 self
.data
= set(data_list
)
312 def update_size(self
):
313 self
.Length
= 5 + len(self
.data
) * 2 * self
.StorageWidth
316 class VAR_VALID_OBJECT_FACTORY(object):
320 def Get_valid_object(PcdClass
, VarOffset
):
321 if PcdClass
.validateranges
:
322 return VAR_CHECK_PCD_VALID_RANGE(VarOffset
, PcdClass
.validateranges
, PcdClass
.DatumType
)
323 if PcdClass
.validlists
:
324 return VAR_CHECK_PCD_VALID_LIST(VarOffset
, PcdClass
.validlists
, PcdClass
.DatumType
)