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 io
import BytesIO
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
):
38 if not os
.path
.isabs(dest
):
40 if not os
.path
.exists(dest
):
42 BinFileName
= "PcdVarCheck.bin"
43 BinFilePath
= os
.path
.join(dest
, BinFileName
)
46 for var_check_tab
in self
.var_check_info
:
50 Name
= var_check_tab
.Name
[1:-1]
51 NameChars
= Name
.split(",")
52 realLength
+= len(NameChars
)
53 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):
54 realLength
+= (4 - (realLength
% 4))
56 for item
in var_check_tab
.validtab
:
59 for v_data
in item
.data
:
60 if type(v_data
) in (int, long):
61 realLength
+= item
.StorageWidth
63 realLength
+= item
.StorageWidth
64 realLength
+= item
.StorageWidth
65 if (index
== len(self
.var_check_info
)) :
66 if (itemIndex
< len(var_check_tab
.validtab
)) and realLength
% 4:
67 realLength
+= (4 - (realLength
% 4))
70 realLength
+= (4 - (realLength
% 4))
71 var_check_tab
.Length
= realLength
74 for var_check_tab
in self
.var_check_info
:
77 b
= pack("=H", var_check_tab
.Revision
)
81 b
= pack("=H", var_check_tab
.HeaderLength
)
85 b
= pack("=L", var_check_tab
.Length
)
89 b
= pack("=B", var_check_tab
.Type
)
94 b
= pack("=B", var_check_tab
.Reserved
)
98 b
= pack("=L", var_check_tab
.Attributes
)
102 Guid
= var_check_tab
.Guid
103 b
= PackByteFormatGUID(Guid
)
107 Name
= var_check_tab
.Name
[1:-1]
108 NameChars
= Name
.split(",")
109 for NameChar
in NameChars
:
110 NameCharNum
= int(NameChar
, 16)
111 b
= pack("=B", NameCharNum
)
115 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):
116 for i
in range(4 - (realLength
% 4)):
117 b
= pack("=B", var_check_tab
.pad
)
121 for item
in var_check_tab
.validtab
:
124 b
= pack("=B", item
.Type
)
128 b
= pack("=B", item
.Length
)
132 b
= pack("=H", int(item
.VarOffset
, 16))
136 b
= pack("=B", item
.StorageWidth
)
139 for v_data
in item
.data
:
140 if type(v_data
) in (int, long):
141 b
= pack(PACK_CODE_BY_SIZE
[item
.StorageWidth
], v_data
)
143 realLength
+= item
.StorageWidth
145 b
= pack(PACK_CODE_BY_SIZE
[item
.StorageWidth
], v_data
[0])
147 realLength
+= item
.StorageWidth
148 b
= pack(PACK_CODE_BY_SIZE
[item
.StorageWidth
], v_data
[1])
150 realLength
+= item
.StorageWidth
152 if (index
== len(self
.var_check_info
)) :
153 if (itemIndex
< len(var_check_tab
.validtab
)) and realLength
% 4:
154 for i
in range(4 - (realLength
% 4)):
155 b
= pack("=B", var_check_tab
.pad
)
160 for i
in range(4 - (realLength
% 4)):
161 b
= pack("=B", var_check_tab
.pad
)
166 if Phase
== 'DXE' and os
.path
.exists(BinFilePath
):
167 BinFile
= open(BinFilePath
, "rb")
168 BinBuffer
= BinFile
.read()
170 BinBufferSize
= len(BinBuffer
)
171 if (BinBufferSize
% 4):
172 for i
in range(4 - (BinBufferSize
% 4)):
173 b
= pack("=B", VAR_CHECK_PCD_VARIABLE_TAB
.pad
)
175 Buffer
= BinBuffer
+ Buffer
177 SaveFileOnChange(BinFilePath
, DbFile
.getvalue(), True)
180 class VAR_CHECK_PCD_VARIABLE_TAB(object):
182 def __init__(self
, TokenSpaceGuid
, PcdCName
):
183 self
.Revision
= 0x0001
184 self
.HeaderLength
= 0
185 self
.Length
= 0 # Length include this header
188 self
.Attributes
= 0x00000000
189 self
.Guid
= eval("[" + TokenSpaceGuid
.replace("{", "").replace("}", "") + "]")
193 def UpdateSize(self
):
194 self
.HeaderLength
= 32 + len(self
.Name
.split(","))
195 self
.Length
= 32 + len(self
.Name
.split(",")) + self
.GetValidTabLen()
197 def GetValidTabLen(self
):
199 for item
in self
.validtab
:
200 validtablen
+= item
.Length
203 def SetAttributes(self
, attributes
):
204 self
.Attributes
= attributes
206 def push_back(self
, valid_obj
):
207 if valid_obj
is not None:
208 self
.validtab
.append(valid_obj
)
210 def equal(self
, varchecktab
):
211 if self
.Guid
== varchecktab
.Guid
and self
.Name
== varchecktab
.Name
:
216 def merge(self
, varchecktab
):
217 for validobj
in varchecktab
.validtab
:
218 if validobj
in self
.validtab
:
220 self
.validtab
.append(validobj
)
224 class VAR_CHECK_PCD_VALID_OBJ(object):
225 def __init__(self
, VarOffset
, data
, PcdDataType
):
227 self
.Length
= 0 # Length include this header
228 self
.VarOffset
= VarOffset
229 self
.PcdDataType
= PcdDataType
.strip()
233 self
.StorageWidth
= MAX_SIZE_TYPE
[self
.PcdDataType
]
234 self
.ValidData
= True
236 self
.StorageWidth
= 0
237 self
.ValidData
= False
239 def __eq__(self
, validObj
):
240 return validObj
and self
.VarOffset
== validObj
.VarOffset
242 class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ
):
243 def __init__(self
, VarOffset
, validlist
, PcdDataType
):
244 super(VAR_CHECK_PCD_VALID_LIST
, self
).__init
__(VarOffset
, validlist
, PcdDataType
)
247 for item
in self
.rawdata
:
248 valid_num_list
.extend(item
.split(','))
250 for valid_num
in valid_num_list
:
251 valid_num
= valid_num
.strip()
253 if valid_num
.startswith('0x') or valid_num
.startswith('0X'):
254 self
.data
.add(int(valid_num
, 16))
256 self
.data
.add(int(valid_num
))
259 self
.Length
= 5 + len(self
.data
) * self
.StorageWidth
262 class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ
):
263 def __init__(self
, VarOffset
, validrange
, PcdDataType
):
264 super(VAR_CHECK_PCD_VALID_RANGE
, self
).__init
__(VarOffset
, validrange
, PcdDataType
)
268 for item
in self
.rawdata
:
270 RangeExpr
= "( " + item
+ " )"
272 RangeExpr
= RangeExpr
+ "OR ( " + item
+ " )"
273 range_result
= RangeExpression(RangeExpr
, self
.PcdDataType
)(True)
274 for rangelist
in range_result
:
275 for obj
in rangelist
.pop():
276 self
.data
.add((obj
.start
, obj
.end
))
277 self
.Length
= 5 + len(self
.data
) * 2 * self
.StorageWidth
280 def GetValidationObject(PcdClass
, VarOffset
):
281 if PcdClass
.validateranges
:
282 return VAR_CHECK_PCD_VALID_RANGE(VarOffset
, PcdClass
.validateranges
, PcdClass
.DatumType
)
283 if PcdClass
.validlists
:
284 return VAR_CHECK_PCD_VALID_LIST(VarOffset
, PcdClass
.validlists
, PcdClass
.DatumType
)