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