]>
Commit | Line | Data |
---|---|---|
656d2539 | 1 | # Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r |
2e351cbe | 2 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
82a6a960 BF |
3 | \r |
4 | #\r | |
5 | # This file is used to collect the Variable checking information\r | |
6 | #\r | |
7 | \r | |
8 | # #\r | |
9 | # Import Modules\r | |
10 | #\r | |
11 | import os\r | |
12 | from Common.RangeExpression import RangeExpression\r | |
13 | from Common.Misc import *\r | |
86379ac4 | 14 | from io import BytesIO\r |
82a6a960 | 15 | from struct import pack\r |
656d2539 | 16 | from Common.DataType import *\r |
82a6a960 BF |
17 | \r |
18 | class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):\r | |
19 | def __init__(self):\r | |
20 | self.var_check_info = []\r | |
f7496d71 | 21 | \r |
82a6a960 BF |
22 | def push_back(self, var_check_tab):\r |
23 | for tab in self.var_check_info:\r | |
24 | if tab.equal(var_check_tab):\r | |
25 | tab.merge(var_check_tab)\r | |
26 | break\r | |
27 | else:\r | |
28 | self.var_check_info.append(var_check_tab)\r | |
f7496d71 | 29 | \r |
82a6a960 | 30 | def dump(self, dest, Phase):\r |
f7496d71 | 31 | \r |
82a6a960 BF |
32 | if not os.path.isabs(dest):\r |
33 | return\r | |
34 | if not os.path.exists(dest):\r | |
35 | os.mkdir(dest)\r | |
36 | BinFileName = "PcdVarCheck.bin"\r | |
37 | BinFilePath = os.path.join(dest, BinFileName)\r | |
d943b0c3 | 38 | Buffer = bytearray()\r |
82a6a960 BF |
39 | index = 0\r |
40 | for var_check_tab in self.var_check_info:\r | |
41 | index += 1\r | |
42 | realLength = 0\r | |
43 | realLength += 32\r | |
44 | Name = var_check_tab.Name[1:-1]\r | |
45 | NameChars = Name.split(",")\r | |
46 | realLength += len(NameChars)\r | |
47 | 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):\r | |
48 | realLength += (4 - (realLength % 4))\r | |
49 | itemIndex = 0\r | |
50 | for item in var_check_tab.validtab:\r | |
51 | itemIndex += 1\r | |
52 | realLength += 5\r | |
53 | for v_data in item.data:\r | |
af881abc | 54 | if isinstance(v_data, int):\r |
82a6a960 BF |
55 | realLength += item.StorageWidth\r |
56 | else:\r | |
57 | realLength += item.StorageWidth\r | |
58 | realLength += item.StorageWidth\r | |
59 | if (index == len(self.var_check_info)) :\r | |
60 | if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:\r | |
61 | realLength += (4 - (realLength % 4))\r | |
62 | else:\r | |
63 | if realLength % 4:\r | |
64 | realLength += (4 - (realLength % 4))\r | |
65 | var_check_tab.Length = realLength\r | |
66 | realLength = 0\r | |
67 | index = 0\r | |
68 | for var_check_tab in self.var_check_info:\r | |
69 | index += 1\r | |
70 | \r | |
71 | b = pack("=H", var_check_tab.Revision)\r | |
72 | Buffer += b\r | |
73 | realLength += 2\r | |
74 | \r | |
75 | b = pack("=H", var_check_tab.HeaderLength)\r | |
76 | Buffer += b\r | |
77 | realLength += 2\r | |
78 | \r | |
79 | b = pack("=L", var_check_tab.Length)\r | |
80 | Buffer += b\r | |
81 | realLength += 4\r | |
82 | \r | |
83 | b = pack("=B", var_check_tab.Type)\r | |
84 | Buffer += b\r | |
85 | realLength += 1\r | |
86 | \r | |
87 | for i in range(0, 3):\r | |
88 | b = pack("=B", var_check_tab.Reserved)\r | |
89 | Buffer += b\r | |
90 | realLength += 1\r | |
91 | \r | |
92 | b = pack("=L", var_check_tab.Attributes)\r | |
93 | Buffer += b\r | |
94 | realLength += 4\r | |
95 | \r | |
96 | Guid = var_check_tab.Guid\r | |
d0a0c52c | 97 | b = PackByteFormatGUID(Guid)\r |
82a6a960 BF |
98 | Buffer += b\r |
99 | realLength += 16\r | |
100 | \r | |
101 | Name = var_check_tab.Name[1:-1]\r | |
102 | NameChars = Name.split(",")\r | |
103 | for NameChar in NameChars:\r | |
104 | NameCharNum = int(NameChar, 16)\r | |
105 | b = pack("=B", NameCharNum)\r | |
106 | Buffer += b\r | |
107 | realLength += 1\r | |
108 | \r | |
109 | 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):\r | |
110 | for i in range(4 - (realLength % 4)):\r | |
111 | b = pack("=B", var_check_tab.pad)\r | |
112 | Buffer += b\r | |
113 | realLength += 1\r | |
114 | itemIndex = 0\r | |
115 | for item in var_check_tab.validtab:\r | |
116 | itemIndex += 1\r | |
117 | \r | |
118 | b = pack("=B", item.Type)\r | |
119 | Buffer += b\r | |
120 | realLength += 1\r | |
121 | \r | |
122 | b = pack("=B", item.Length)\r | |
123 | Buffer += b\r | |
124 | realLength += 1\r | |
125 | \r | |
126 | b = pack("=H", int(item.VarOffset, 16))\r | |
127 | Buffer += b\r | |
128 | realLength += 2\r | |
129 | \r | |
130 | b = pack("=B", item.StorageWidth)\r | |
131 | Buffer += b\r | |
132 | realLength += 1\r | |
82a6a960 | 133 | for v_data in item.data:\r |
af881abc | 134 | if isinstance(v_data, int):\r |
d0a0c52c | 135 | b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data)\r |
82a6a960 BF |
136 | Buffer += b\r |
137 | realLength += item.StorageWidth\r | |
138 | else:\r | |
d0a0c52c | 139 | b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data[0])\r |
82a6a960 BF |
140 | Buffer += b\r |
141 | realLength += item.StorageWidth\r | |
d0a0c52c | 142 | b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data[1])\r |
82a6a960 BF |
143 | Buffer += b\r |
144 | realLength += item.StorageWidth\r | |
145 | \r | |
146 | if (index == len(self.var_check_info)) :\r | |
147 | if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:\r | |
148 | for i in range(4 - (realLength % 4)):\r | |
149 | b = pack("=B", var_check_tab.pad)\r | |
150 | Buffer += b\r | |
151 | realLength += 1\r | |
152 | else:\r | |
153 | if realLength % 4:\r | |
154 | for i in range(4 - (realLength % 4)):\r | |
155 | b = pack("=B", var_check_tab.pad)\r | |
156 | Buffer += b\r | |
157 | realLength += 1\r | |
f7496d71 | 158 | \r |
86379ac4 | 159 | DbFile = BytesIO()\r |
82a6a960 BF |
160 | if Phase == 'DXE' and os.path.exists(BinFilePath):\r |
161 | BinFile = open(BinFilePath, "rb")\r | |
162 | BinBuffer = BinFile.read()\r | |
163 | BinFile.close()\r | |
164 | BinBufferSize = len(BinBuffer)\r | |
165 | if (BinBufferSize % 4):\r | |
166 | for i in range(4 - (BinBufferSize % 4)):\r | |
167 | b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad)\r | |
168 | BinBuffer += b\r | |
169 | Buffer = BinBuffer + Buffer\r | |
170 | DbFile.write(Buffer)\r | |
171 | SaveFileOnChange(BinFilePath, DbFile.getvalue(), True)\r | |
f7496d71 | 172 | \r |
82a6a960 BF |
173 | \r |
174 | class VAR_CHECK_PCD_VARIABLE_TAB(object):\r | |
175 | pad = 0xDA\r | |
176 | def __init__(self, TokenSpaceGuid, PcdCName):\r | |
177 | self.Revision = 0x0001\r | |
178 | self.HeaderLength = 0\r | |
179 | self.Length = 0 # Length include this header\r | |
180 | self.Type = 0\r | |
181 | self.Reserved = 0\r | |
182 | self.Attributes = 0x00000000\r | |
183 | self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]")\r | |
184 | self.Name = PcdCName\r | |
185 | self.validtab = []\r | |
186 | \r | |
187 | def UpdateSize(self):\r | |
188 | self.HeaderLength = 32 + len(self.Name.split(","))\r | |
189 | self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen()\r | |
f7496d71 | 190 | \r |
82a6a960 BF |
191 | def GetValidTabLen(self):\r |
192 | validtablen = 0\r | |
193 | for item in self.validtab:\r | |
f7496d71 LG |
194 | validtablen += item.Length\r |
195 | return validtablen\r | |
196 | \r | |
82a6a960 BF |
197 | def SetAttributes(self, attributes):\r |
198 | self.Attributes = attributes\r | |
f7496d71 | 199 | \r |
82a6a960 BF |
200 | def push_back(self, valid_obj):\r |
201 | if valid_obj is not None:\r | |
202 | self.validtab.append(valid_obj)\r | |
f7496d71 | 203 | \r |
82a6a960 BF |
204 | def equal(self, varchecktab):\r |
205 | if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name:\r | |
206 | return True\r | |
207 | else:\r | |
208 | return False\r | |
f7496d71 | 209 | \r |
82a6a960 BF |
210 | def merge(self, varchecktab):\r |
211 | for validobj in varchecktab.validtab:\r | |
212 | if validobj in self.validtab:\r | |
213 | continue\r | |
214 | self.validtab.append(validobj)\r | |
215 | self.UpdateSize()\r | |
216 | \r | |
217 | \r | |
218 | class VAR_CHECK_PCD_VALID_OBJ(object):\r | |
219 | def __init__(self, VarOffset, data, PcdDataType):\r | |
220 | self.Type = 1\r | |
221 | self.Length = 0 # Length include this header\r | |
222 | self.VarOffset = VarOffset\r | |
82a6a960 BF |
223 | self.PcdDataType = PcdDataType.strip()\r |
224 | self.rawdata = data\r | |
225 | self.data = set()\r | |
a7360838 | 226 | try:\r |
5565a8c4 | 227 | self.StorageWidth = MAX_SIZE_TYPE[self.PcdDataType]\r |
def89ed0 | 228 | self.ValidData = True\r |
a7360838 | 229 | except:\r |
82a6a960 BF |
230 | self.StorageWidth = 0\r |
231 | self.ValidData = False\r | |
f7496d71 LG |
232 | \r |
233 | def __eq__(self, validObj):\r | |
b7b51025 | 234 | return validObj and self.VarOffset == validObj.VarOffset\r |
f7496d71 | 235 | \r |
82a6a960 BF |
236 | class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ):\r |
237 | def __init__(self, VarOffset, validlist, PcdDataType):\r | |
1ccc4d89 | 238 | super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType)\r |
82a6a960 | 239 | self.Type = 1\r |
82a6a960 | 240 | valid_num_list = []\r |
82a6a960 BF |
241 | for item in self.rawdata:\r |
242 | valid_num_list.extend(item.split(','))\r | |
f7496d71 | 243 | \r |
82a6a960 BF |
244 | for valid_num in valid_num_list:\r |
245 | valid_num = valid_num.strip()\r | |
246 | \r | |
247 | if valid_num.startswith('0x') or valid_num.startswith('0X'):\r | |
0caa769d | 248 | self.data.add(int(valid_num, 16))\r |
82a6a960 | 249 | else:\r |
0caa769d | 250 | self.data.add(int(valid_num))\r |
82a6a960 | 251 | \r |
f7496d71 | 252 | \r |
82a6a960 | 253 | self.Length = 5 + len(self.data) * self.StorageWidth\r |
f7496d71 LG |
254 | \r |
255 | \r | |
82a6a960 BF |
256 | class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ):\r |
257 | def __init__(self, VarOffset, validrange, PcdDataType):\r | |
1ccc4d89 | 258 | super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType)\r |
82a6a960 | 259 | self.Type = 2\r |
82a6a960 | 260 | RangeExpr = ""\r |
82a6a960 BF |
261 | i = 0\r |
262 | for item in self.rawdata:\r | |
263 | if i == 0:\r | |
264 | RangeExpr = "( " + item + " )"\r | |
265 | else:\r | |
266 | RangeExpr = RangeExpr + "OR ( " + item + " )"\r | |
267 | range_result = RangeExpression(RangeExpr, self.PcdDataType)(True)\r | |
268 | for rangelist in range_result:\r | |
269 | for obj in rangelist.pop():\r | |
0caa769d | 270 | self.data.add((obj.start, obj.end))\r |
82a6a960 | 271 | self.Length = 5 + len(self.data) * 2 * self.StorageWidth\r |
f7496d71 | 272 | \r |
82a6a960 | 273 | \r |
92a4eebb CJ |
274 | def GetValidationObject(PcdClass, VarOffset):\r |
275 | if PcdClass.validateranges:\r | |
276 | return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType)\r | |
277 | if PcdClass.validlists:\r | |
278 | return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType)\r | |
279 | else:\r | |
280 | return None\r |