]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/Eot.py
BaseTools: Eot - fix variable names
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Eot.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to be the main entrance of EOT tool\r
3#\r
d498274f 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
64429fbd 17from __future__ import absolute_import\r
1be2ed90 18import Common.LongFilePathOs as os, time, glob\r
52302d4d 19import Common.EdkLogger as EdkLogger\r
64429fbd 20from . import EotGlobalData\r
52302d4d 21from optparse import OptionParser\r
5a57246e 22from Common.StringUtils import NormPath\r
52302d4d 23from Common import BuildToolError\r
e95a0dfb 24from Common.Misc import GuidStructureStringToGuidString, sdict\r
64429fbd
GL
25from .InfParserLite import *\r
26from . import c\r
27from . import Database\r
52302d4d 28from array import array\r
64429fbd 29from .Report import Report\r
b36d134f 30from Common.BuildVersion import gBUILD_VERSION\r
64429fbd 31from .Parser import ConvertGuid\r
1be2ed90 32from Common.LongFilePathSupport import OpenLongFilePath as open\r
e95a0dfb
JC
33import struct\r
34import uuid\r
35import copy\r
36import codecs\r
37\r
38gGuidStringFormat = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"\r
39gPeiAprioriFileNameGuid = '1b45cc0a-156a-428a-af62-49864da0e6e6'\r
40gAprioriGuid = 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'\r
41gIndention = -4\r
42\r
43class Image(array):\r
44 _HEADER_ = struct.Struct("")\r
45 _HEADER_SIZE_ = _HEADER_.size\r
46\r
47 def __new__(cls, *args, **kwargs):\r
48 return array.__new__(cls, 'B')\r
49\r
50 def __init__(self, ID=None):\r
51 if ID is None:\r
52 self._ID_ = str(uuid.uuid1()).upper()\r
53 else:\r
54 self._ID_ = ID\r
55 self._BUF_ = None\r
56 self._LEN_ = None\r
57 self._OFF_ = None\r
58\r
59 self._SubImages = sdict() # {offset: Image()}\r
60\r
61 array.__init__(self, 'B')\r
62\r
63 def __repr__(self):\r
64 return self._ID_\r
65\r
66 def __len__(self):\r
67 Len = array.__len__(self)\r
68 for Offset in self._SubImages:\r
69 Len += len(self._SubImages[Offset])\r
70 return Len\r
71\r
72 def _Unpack(self):\r
73 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
74 return len(self)\r
75\r
76 def _Pack(self, PadByte=0xFF):\r
77 raise NotImplementedError\r
78\r
79 def frombuffer(self, Buffer, Offset=0, Size=None):\r
80 self._BUF_ = Buffer\r
81 self._OFF_ = Offset\r
82 # we may need the Size information in advance if it's given\r
83 self._LEN_ = Size\r
84 self._LEN_ = self._Unpack()\r
85\r
86 def empty(self):\r
87 del self[0:]\r
88\r
89 def GetField(self, FieldStruct, Offset=0):\r
90 return FieldStruct.unpack_from(self, Offset)\r
91\r
92 def SetField(self, FieldStruct, Offset, *args):\r
93 # check if there's enough space\r
94 Size = FieldStruct.size\r
95 if Size > len(self):\r
96 self.extend([0] * (Size - len(self)))\r
97 FieldStruct.pack_into(self, Offset, *args)\r
98\r
99 def _SetData(self, Data):\r
100 if len(self) < self._HEADER_SIZE_:\r
101 self.extend([0] * (self._HEADER_SIZE_ - len(self)))\r
102 else:\r
103 del self[self._HEADER_SIZE_:]\r
104 self.extend(Data)\r
105\r
106 def _GetData(self):\r
107 if len(self) > self._HEADER_SIZE_:\r
108 return self[self._HEADER_SIZE_:]\r
109 return None\r
110\r
111 Data = property(_GetData, _SetData)\r
112\r
113## CompressedImage() class\r
114#\r
115# A class for Compressed Image\r
116#\r
117class CompressedImage(Image):\r
118 # UncompressedLength = 4-byte\r
119 # CompressionType = 1-byte\r
120 _HEADER_ = struct.Struct("1I 1B")\r
121 _HEADER_SIZE_ = _HEADER_.size\r
122\r
123 _ORIG_SIZE_ = struct.Struct("1I")\r
124 _CMPRS_TYPE_ = struct.Struct("4x 1B")\r
125\r
4fea08b9
CJ
126 def __init__(self, CompressedData=None, CompressionType=None, UncompressedLength=None):\r
127 Image.__init__(self)\r
e95a0dfb 128 if UncompressedLength is not None:\r
4fea08b9 129 self.UncompressedLength = UncompressedLength\r
e95a0dfb 130 if CompressionType is not None:\r
4fea08b9 131 self.CompressionType = CompressionType\r
e95a0dfb 132 if CompressedData is not None:\r
4fea08b9 133 self.Data = CompressedData\r
e95a0dfb 134\r
4fea08b9 135 def __str__(self):\r
e95a0dfb 136 global gIndention\r
4fea08b9
CJ
137 S = "algorithm=%s uncompressed=%x" % (self.CompressionType, self.UncompressedLength)\r
138 for Sec in self.Sections:\r
e95a0dfb
JC
139 S += '\n' + str(Sec)\r
140\r
141 return S\r
142\r
4fea08b9
CJ
143 def _SetOriginalSize(self, Size):\r
144 self.SetField(self._ORIG_SIZE_, 0, Size)\r
e95a0dfb 145\r
4fea08b9
CJ
146 def _GetOriginalSize(self):\r
147 return self.GetField(self._ORIG_SIZE_)[0]\r
e95a0dfb 148\r
4fea08b9
CJ
149 def _SetCompressionType(self, Type):\r
150 self.SetField(self._CMPRS_TYPE_, 0, Type)\r
e95a0dfb 151\r
4fea08b9
CJ
152 def _GetCompressionType(self):\r
153 return self.GetField(self._CMPRS_TYPE_)[0]\r
e95a0dfb 154\r
4fea08b9 155 def _GetSections(self):\r
e95a0dfb 156 try:\r
64429fbd 157 from . import EfiCompressor\r
e95a0dfb 158 TmpData = EfiCompressor.FrameworkDecompress(\r
4fea08b9
CJ
159 self[self._HEADER_SIZE_:],\r
160 len(self) - self._HEADER_SIZE_\r
e95a0dfb
JC
161 )\r
162 DecData = array('B')\r
163 DecData.fromstring(TmpData)\r
164 except:\r
64429fbd 165 from . import EfiCompressor\r
e95a0dfb 166 TmpData = EfiCompressor.UefiDecompress(\r
4fea08b9
CJ
167 self[self._HEADER_SIZE_:],\r
168 len(self) - self._HEADER_SIZE_\r
e95a0dfb
JC
169 )\r
170 DecData = array('B')\r
171 DecData.fromstring(TmpData)\r
172\r
173 SectionList = []\r
174 Offset = 0\r
175 while Offset < len(DecData):\r
176 Sec = Section()\r
177 try:\r
178 Sec.frombuffer(DecData, Offset)\r
179 Offset += Sec.Size\r
180 # the section is aligned to 4-byte boundary\r
181 except:\r
182 break\r
183 SectionList.append(Sec)\r
184 return SectionList\r
185\r
186 UncompressedLength = property(_GetOriginalSize, _SetOriginalSize)\r
187 CompressionType = property(_GetCompressionType, _SetCompressionType)\r
188 Sections = property(_GetSections)\r
189\r
190## Ui() class\r
191#\r
192# A class for Ui\r
193#\r
194class Ui(Image):\r
195 _HEADER_ = struct.Struct("")\r
196 _HEADER_SIZE_ = 0\r
197\r
4fea08b9
CJ
198 def __init__(self):\r
199 Image.__init__(self)\r
e95a0dfb 200\r
4fea08b9
CJ
201 def __str__(self):\r
202 return self.String\r
e95a0dfb 203\r
4fea08b9 204 def _Unpack(self):\r
e95a0dfb 205 # keep header in this Image object\r
4fea08b9
CJ
206 self.empty()\r
207 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
208 return len(self)\r
e95a0dfb 209\r
4fea08b9
CJ
210 def _GetUiString(self):\r
211 return codecs.utf_16_decode(self[0:-2].tostring())[0]\r
e95a0dfb
JC
212\r
213 String = property(_GetUiString)\r
214\r
215## Depex() class\r
216#\r
217# A class for Depex\r
218#\r
219class Depex(Image):\r
220 _HEADER_ = struct.Struct("")\r
221 _HEADER_SIZE_ = 0\r
222\r
223 _GUID_ = struct.Struct("1I2H8B")\r
224 _OPCODE_ = struct.Struct("1B")\r
225\r
226 _OPCODE_STRING_ = {\r
227 0x00 : "BEFORE",\r
228 0x01 : "AFTER",\r
229 0x02 : "PUSH",\r
230 0x03 : "AND",\r
231 0x04 : "OR",\r
232 0x05 : "NOT",\r
233 0x06 : "TRUE",\r
234 0x07 : "FALSE",\r
235 0x08 : "END",\r
236 0x09 : "SOR"\r
237 }\r
238\r
239 _NEXT_ = {\r
240 -1 : _OPCODE_, # first one in depex must be an opcdoe\r
241 0x00 : _GUID_, #"BEFORE",\r
242 0x01 : _GUID_, #"AFTER",\r
243 0x02 : _GUID_, #"PUSH",\r
244 0x03 : _OPCODE_, #"AND",\r
245 0x04 : _OPCODE_, #"OR",\r
246 0x05 : _OPCODE_, #"NOT",\r
247 0x06 : _OPCODE_, #"TRUE",\r
248 0x07 : _OPCODE_, #"FALSE",\r
249 0x08 : None, #"END",\r
250 0x09 : _OPCODE_, #"SOR"\r
251 }\r
252\r
4fea08b9
CJ
253 def __init__(self):\r
254 Image.__init__(self)\r
255 self._ExprList = []\r
e95a0dfb 256\r
4fea08b9 257 def __str__(self):\r
e95a0dfb
JC
258 global gIndention\r
259 gIndention += 4\r
260 Indention = ' ' * gIndention\r
261 S = '\n'\r
4fea08b9
CJ
262 for T in self.Expression:\r
263 if T in self._OPCODE_STRING_:\r
264 S += Indention + self._OPCODE_STRING_[T]\r
e95a0dfb
JC
265 if T not in [0x00, 0x01, 0x02]:\r
266 S += '\n'\r
267 else:\r
268 S += ' ' + gGuidStringFormat % T + '\n'\r
269 gIndention -= 4\r
270 return S\r
271\r
4fea08b9 272 def _Unpack(self):\r
e95a0dfb 273 # keep header in this Image object\r
4fea08b9
CJ
274 self.empty()\r
275 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
276 return len(self)\r
e95a0dfb 277\r
4fea08b9
CJ
278 def _GetExpression(self):\r
279 if self._ExprList == []:\r
e95a0dfb 280 Offset = 0\r
4fea08b9
CJ
281 CurrentData = self._OPCODE_\r
282 while Offset < len(self):\r
283 Token = CurrentData.unpack_from(self, Offset)\r
e95a0dfb
JC
284 Offset += CurrentData.size\r
285 if len(Token) == 1:\r
286 Token = Token[0]\r
4fea08b9
CJ
287 if Token in self._NEXT_:\r
288 CurrentData = self._NEXT_[Token]\r
e95a0dfb 289 else:\r
4fea08b9 290 CurrentData = self._GUID_\r
e95a0dfb 291 else:\r
4fea08b9
CJ
292 CurrentData = self._OPCODE_\r
293 self._ExprList.append(Token)\r
e95a0dfb
JC
294 if CurrentData is None:\r
295 break\r
4fea08b9 296 return self._ExprList\r
e95a0dfb
JC
297\r
298 Expression = property(_GetExpression)\r
299\r
300## FirmwareVolume() class\r
301#\r
302# A class for Firmware Volume\r
303#\r
304class FirmwareVolume(Image):\r
305 # Read FvLength, Attributes, HeaderLength, Checksum\r
306 _HEADER_ = struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")\r
307 _HEADER_SIZE_ = _HEADER_.size\r
308\r
309 _FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"\r
310\r
311 _GUID_ = struct.Struct("16x 1I2H8B")\r
312 _LENGTH_ = struct.Struct("16x 16x 1Q")\r
313 _SIG_ = struct.Struct("16x 16x 8x 1I")\r
314 _ATTR_ = struct.Struct("16x 16x 8x 4x 1I")\r
315 _HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")\r
316 _CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")\r
317\r
318 def __init__(self, Name=''):\r
319 Image.__init__(self)\r
320 self.Name = Name\r
321 self.FfsDict = sdict()\r
322 self.OrderedFfsDict = sdict()\r
323 self.UnDispatchedFfsDict = sdict()\r
324 self.ProtocolList = sdict()\r
325\r
326 def CheckArchProtocol(self):\r
327 for Item in EotGlobalData.gArchProtocolGuids:\r
328 if Item.lower() not in EotGlobalData.gProtocolList:\r
e95a0dfb 329 return False\r
e95a0dfb
JC
330 return True\r
331\r
332 def ParseDepex(self, Depex, Type):\r
333 List = None\r
334 if Type == 'Ppi':\r
335 List = EotGlobalData.gPpiList\r
336 if Type == 'Protocol':\r
337 List = EotGlobalData.gProtocolList\r
338 DepexStack = []\r
339 DepexList = []\r
340 DepexString = ''\r
341 FileDepex = None\r
342 CouldBeLoaded = True\r
343 for Index in range(0, len(Depex.Expression)):\r
344 Item = Depex.Expression[Index]\r
345 if Item == 0x00:\r
346 Index = Index + 1\r
347 Guid = gGuidStringFormat % Depex.Expression[Index]\r
348 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
349 return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE'])\r
350 elif Item == 0x01:\r
351 Index = Index + 1\r
352 Guid = gGuidStringFormat % Depex.Expression[Index]\r
353 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
354 return (True, 'AFTER %s' % Guid, [Guid, 'AFTER'])\r
355 elif Item == 0x02:\r
356 Index = Index + 1\r
357 Guid = gGuidStringFormat % Depex.Expression[Index]\r
358 if Guid.lower() in List:\r
359 DepexStack.append(True)\r
360 DepexList.append(Guid)\r
361 else:\r
362 DepexStack.append(False)\r
363 DepexList.append(Guid)\r
364 continue\r
365 elif Item == 0x03 or Item == 0x04:\r
366 DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
367 DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCODE_STRING_[Item].upper() + ' ' + str(DepexList.pop()))\r
368 elif Item == 0x05:\r
369 DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
370 DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexList.pop()))\r
371 elif Item == 0x06:\r
372 DepexStack.append(True)\r
373 DepexList.append('TRUE')\r
374 DepexString = DepexString + 'TRUE' + ' '\r
375 elif Item == 0x07:\r
376 DepexStack.append(False)\r
377 DepexList.append('False')\r
378 DepexString = DepexString + 'FALSE' + ' '\r
379 elif Item == 0x08:\r
380 if Index != len(Depex.Expression) - 1:\r
381 CouldBeLoaded = False\r
382 else:\r
383 CouldBeLoaded = DepexStack.pop()\r
384 else:\r
385 CouldBeLoaded = False\r
386 if DepexList != []:\r
387 DepexString = DepexList[0].strip()\r
388 return (CouldBeLoaded, DepexString, FileDepex)\r
389\r
390 def Dispatch(self, Db = None):\r
391 if Db is None:\r
392 return False\r
393 self.UnDispatchedFfsDict = copy.copy(self.FfsDict)\r
394 # Find PeiCore, DexCore, PeiPriori, DxePriori first\r
395 FfsSecCoreGuid = None\r
396 FfsPeiCoreGuid = None\r
397 FfsDxeCoreGuid = None\r
398 FfsPeiPrioriGuid = None\r
399 FfsDxePrioriGuid = None\r
400 for FfsID in self.UnDispatchedFfsDict:\r
401 Ffs = self.UnDispatchedFfsDict[FfsID]\r
402 if Ffs.Type == 0x03:\r
403 FfsSecCoreGuid = FfsID\r
404 continue\r
405 if Ffs.Type == 0x04:\r
406 FfsPeiCoreGuid = FfsID\r
407 continue\r
408 if Ffs.Type == 0x05:\r
409 FfsDxeCoreGuid = FfsID\r
410 continue\r
411 if Ffs.Guid.lower() == gPeiAprioriFileNameGuid:\r
412 FfsPeiPrioriGuid = FfsID\r
413 continue\r
414 if Ffs.Guid.lower() == gAprioriGuid:\r
415 FfsDxePrioriGuid = FfsID\r
416 continue\r
417\r
418 # Parse SEC_CORE first\r
419 if FfsSecCoreGuid is not None:\r
420 self.OrderedFfsDict[FfsSecCoreGuid] = self.UnDispatchedFfsDict.pop(FfsSecCoreGuid)\r
421 self.LoadPpi(Db, FfsSecCoreGuid)\r
422\r
423 # Parse PEI first\r
424 if FfsPeiCoreGuid is not None:\r
425 self.OrderedFfsDict[FfsPeiCoreGuid] = self.UnDispatchedFfsDict.pop(FfsPeiCoreGuid)\r
426 self.LoadPpi(Db, FfsPeiCoreGuid)\r
427 if FfsPeiPrioriGuid is not None:\r
428 # Load PEIM described in priori file\r
429 FfsPeiPriori = self.UnDispatchedFfsDict.pop(FfsPeiPrioriGuid)\r
430 if len(FfsPeiPriori.Sections) == 1:\r
431 Section = FfsPeiPriori.Sections.popitem()[1]\r
432 if Section.Type == 0x19:\r
433 GuidStruct = struct.Struct('1I2H8B')\r
434 Start = 4\r
435 while len(Section) > Start:\r
436 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
437 GuidString = gGuidStringFormat % Guid\r
438 Start = Start + 16\r
439 if GuidString in self.UnDispatchedFfsDict:\r
440 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
441 self.LoadPpi(Db, GuidString)\r
e95a0dfb
JC
442 self.DisPatchPei(Db)\r
443\r
444 # Parse DXE then\r
445 if FfsDxeCoreGuid is not None:\r
446 self.OrderedFfsDict[FfsDxeCoreGuid] = self.UnDispatchedFfsDict.pop(FfsDxeCoreGuid)\r
447 self.LoadProtocol(Db, FfsDxeCoreGuid)\r
448 if FfsDxePrioriGuid is not None:\r
449 # Load PEIM described in priori file\r
450 FfsDxePriori = self.UnDispatchedFfsDict.pop(FfsDxePrioriGuid)\r
451 if len(FfsDxePriori.Sections) == 1:\r
452 Section = FfsDxePriori.Sections.popitem()[1]\r
453 if Section.Type == 0x19:\r
454 GuidStruct = struct.Struct('1I2H8B')\r
455 Start = 4\r
456 while len(Section) > Start:\r
457 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
458 GuidString = gGuidStringFormat % Guid\r
459 Start = Start + 16\r
460 if GuidString in self.UnDispatchedFfsDict:\r
461 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
462 self.LoadProtocol(Db, GuidString)\r
e95a0dfb
JC
463 self.DisPatchDxe(Db)\r
464\r
465 def LoadProtocol(self, Db, ModuleGuid):\r
466 SqlCommand = """select GuidValue from Report\r
467 where SourceFileFullPath in\r
468 (select Value1 from Inf where BelongsToFile =\r
469 (select BelongsToFile from Inf\r
470 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
471 and Model = %s)\r
472 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \\r
473 % (ModuleGuid, 5001, 3007)\r
474 RecordSet = Db.TblReport.Exec(SqlCommand)\r
475 for Record in RecordSet:\r
476 SqlCommand = """select Value2 from Inf where BelongsToFile =\r
477 (select DISTINCT BelongsToFile from Inf\r
478 where Value1 =\r
479 (select SourceFileFullPath from Report\r
480 where GuidValue like '%s' and ItemMode = 'Callback'))\r
481 and Value1 = 'FILE_GUID'""" % Record[0]\r
482 CallBackSet = Db.TblReport.Exec(SqlCommand)\r
483 if CallBackSet != []:\r
484 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
485 else:\r
486 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
487\r
488 def LoadPpi(self, Db, ModuleGuid):\r
489 SqlCommand = """select GuidValue from Report\r
490 where SourceFileFullPath in\r
491 (select Value1 from Inf where BelongsToFile =\r
492 (select BelongsToFile from Inf\r
493 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
494 and Model = %s)\r
495 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \\r
496 % (ModuleGuid, 5001, 3007)\r
497 RecordSet = Db.TblReport.Exec(SqlCommand)\r
498 for Record in RecordSet:\r
499 EotGlobalData.gPpiList[Record[0].lower()] = ModuleGuid\r
500\r
501 def DisPatchDxe(self, Db):\r
502 IsInstalled = False\r
503 ScheduleList = sdict()\r
504 for FfsID in self.UnDispatchedFfsDict:\r
505 CouldBeLoaded = False\r
506 DepexString = ''\r
507 FileDepex = None\r
508 Ffs = self.UnDispatchedFfsDict[FfsID]\r
509 if Ffs.Type == 0x07:\r
510 # Get Depex\r
511 IsFoundDepex = False\r
512 for Section in Ffs.Sections.values():\r
513 # Find Depex\r
514 if Section.Type == 0x13:\r
515 IsFoundDepex = True\r
516 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Protocol')\r
517 break\r
518 if Section.Type == 0x01:\r
519 CompressSections = Section._SubImages[4]\r
520 for CompressSection in CompressSections.Sections:\r
521 if CompressSection.Type == 0x13:\r
522 IsFoundDepex = True\r
523 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Protocol')\r
524 break\r
525 if CompressSection.Type == 0x02:\r
526 NewSections = CompressSection._SubImages[4]\r
527 for NewSection in NewSections.Sections:\r
528 if NewSection.Type == 0x13:\r
529 IsFoundDepex = True\r
530 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Protocol')\r
531 break\r
532\r
533 # Not find Depex\r
534 if not IsFoundDepex:\r
535 CouldBeLoaded = self.CheckArchProtocol()\r
536 DepexString = ''\r
537 FileDepex = None\r
538\r
539 # Append New Ffs\r
540 if CouldBeLoaded:\r
541 IsInstalled = True\r
542 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
543 NewFfs.Depex = DepexString\r
544 if FileDepex is not None:\r
545 ScheduleList.insert(FileDepex[1], FfsID, NewFfs, FileDepex[0])\r
546 else:\r
547 ScheduleList[FfsID] = NewFfs\r
548 else:\r
549 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
550\r
551 for FfsID in ScheduleList:\r
552 NewFfs = ScheduleList.pop(FfsID)\r
553 FfsName = 'UnKnown'\r
554 self.OrderedFfsDict[FfsID] = NewFfs\r
555 self.LoadProtocol(Db, FfsID)\r
556\r
557 SqlCommand = """select Value2 from Inf\r
558 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
559 and Model = %s and Value1='BASE_NAME'""" % (FfsID, 5001, 5001)\r
560 RecordSet = Db.TblReport.Exec(SqlCommand)\r
561 if RecordSet != []:\r
562 FfsName = RecordSet[0][0]\r
e95a0dfb
JC
563 if IsInstalled:\r
564 self.DisPatchDxe(Db)\r
565\r
566 def DisPatchPei(self, Db):\r
567 IsInstalled = False\r
568 for FfsID in self.UnDispatchedFfsDict:\r
569 CouldBeLoaded = True\r
570 DepexString = ''\r
571 FileDepex = None\r
572 Ffs = self.UnDispatchedFfsDict[FfsID]\r
573 if Ffs.Type == 0x06 or Ffs.Type == 0x08:\r
574 # Get Depex\r
575 for Section in Ffs.Sections.values():\r
576 if Section.Type == 0x1B:\r
577 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')\r
578 break\r
579\r
580 if Section.Type == 0x01:\r
581 CompressSections = Section._SubImages[4]\r
582 for CompressSection in CompressSections.Sections:\r
583 if CompressSection.Type == 0x1B:\r
584 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Ppi')\r
585 break\r
586 if CompressSection.Type == 0x02:\r
587 NewSections = CompressSection._SubImages[4]\r
588 for NewSection in NewSections.Sections:\r
589 if NewSection.Type == 0x1B:\r
590 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Ppi')\r
591 break\r
592\r
593 # Append New Ffs\r
594 if CouldBeLoaded:\r
595 IsInstalled = True\r
596 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
597 NewFfs.Depex = DepexString\r
598 self.OrderedFfsDict[FfsID] = NewFfs\r
599 self.LoadPpi(Db, FfsID)\r
600 else:\r
601 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
602\r
603 if IsInstalled:\r
604 self.DisPatchPei(Db)\r
605\r
e95a0dfb
JC
606 def __str__(self):\r
607 global gIndention\r
608 gIndention += 4\r
609 FvInfo = '\n' + ' ' * gIndention\r
610 FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)\r
611 FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])\r
612 gIndention -= 4\r
613 return FvInfo + FfsInfo\r
614\r
615 def _Unpack(self):\r
616 Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]\r
617 self.empty()\r
618 self.extend(self._BUF_[self._OFF_:self._OFF_+Size])\r
619\r
620 # traverse the FFS\r
621 EndOfFv = Size\r
622 FfsStartAddress = self.HeaderSize\r
623 LastFfsObj = None\r
624 while FfsStartAddress < EndOfFv:\r
625 FfsObj = Ffs()\r
626 FfsObj.frombuffer(self, FfsStartAddress)\r
627 FfsId = repr(FfsObj)\r
628 if ((self.Attributes & 0x00000800) != 0 and len(FfsObj) == 0xFFFFFF) \\r
629 or ((self.Attributes & 0x00000800) == 0 and len(FfsObj) == 0):\r
630 if LastFfsObj is not None:\r
631 LastFfsObj.FreeSpace = EndOfFv - LastFfsObj._OFF_ - len(LastFfsObj)\r
632 else:\r
633 if FfsId in self.FfsDict:\r
634 EdkLogger.error("FV", 0, "Duplicate GUID in FFS",\r
635 ExtraData="\t%s @ %s\n\t%s @ %s" \\r
636 % (FfsObj.Guid, FfsObj.Offset,\r
637 self.FfsDict[FfsId].Guid, self.FfsDict[FfsId].Offset))\r
638 self.FfsDict[FfsId] = FfsObj\r
639 if LastFfsObj is not None:\r
640 LastFfsObj.FreeSpace = FfsStartAddress - LastFfsObj._OFF_ - len(LastFfsObj)\r
641\r
642 FfsStartAddress += len(FfsObj)\r
643 #\r
644 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))\r
645 # The next FFS must be at the latest next 8-byte aligned address\r
646 #\r
647 FfsStartAddress = (FfsStartAddress + 7) & (~7)\r
648 LastFfsObj = FfsObj\r
649\r
650 def _GetAttributes(self):\r
651 return self.GetField(self._ATTR_, 0)[0]\r
652\r
653 def _GetSize(self):\r
654 return self.GetField(self._LENGTH_, 0)[0]\r
655\r
656 def _GetChecksum(self):\r
657 return self.GetField(self._CHECKSUM_, 0)[0]\r
658\r
659 def _GetHeaderLength(self):\r
660 return self.GetField(self._HLEN_, 0)[0]\r
661\r
662 def _GetFileSystemGuid(self):\r
663 return gGuidStringFormat % self.GetField(self._GUID_, 0)\r
664\r
665 Attributes = property(_GetAttributes)\r
666 Size = property(_GetSize)\r
667 Checksum = property(_GetChecksum)\r
668 HeaderSize = property(_GetHeaderLength)\r
669 FileSystemGuid = property(_GetFileSystemGuid)\r
670\r
671## GuidDefinedImage() class\r
672#\r
673# A class for GUID Defined Image\r
674#\r
675class GuidDefinedImage(Image):\r
676 _HEADER_ = struct.Struct("1I2H8B 1H 1H")\r
677 _HEADER_SIZE_ = _HEADER_.size\r
678\r
679 _GUID_ = struct.Struct("1I2H8B")\r
680 _DATA_OFFSET_ = struct.Struct("16x 1H")\r
681 _ATTR_ = struct.Struct("18x 1H")\r
682\r
683 CRC32_GUID = "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"\r
684 TIANO_COMPRESS_GUID = 'A31280AD-481E-41B6-95E8-127F4C984779'\r
685 LZMA_COMPRESS_GUID = 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'\r
686\r
4fea08b9
CJ
687 def __init__(self, SectionDefinitionGuid=None, DataOffset=None, Attributes=None, Data=None):\r
688 Image.__init__(self)\r
e95a0dfb 689 if SectionDefinitionGuid is not None:\r
4fea08b9 690 self.SectionDefinitionGuid = SectionDefinitionGuid\r
e95a0dfb 691 if DataOffset is not None:\r
4fea08b9 692 self.DataOffset = DataOffset\r
e95a0dfb 693 if Attributes is not None:\r
4fea08b9 694 self.Attributes = Attributes\r
e95a0dfb 695 if Data is not None:\r
4fea08b9 696 self.Data = Data\r
e95a0dfb 697\r
4fea08b9
CJ
698 def __str__(self):\r
699 S = "guid=%s" % (gGuidStringFormat % self.SectionDefinitionGuid)\r
700 for Sec in self.Sections:\r
e95a0dfb
JC
701 S += "\n" + str(Sec)\r
702 return S\r
703\r
4fea08b9 704 def _Unpack(self):\r
e95a0dfb 705 # keep header in this Image object\r
4fea08b9
CJ
706 self.empty()\r
707 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
708 return len(self)\r
e95a0dfb 709\r
4fea08b9
CJ
710 def _SetAttribute(self, Attribute):\r
711 self.SetField(self._ATTR_, 0, Attribute)\r
e95a0dfb 712\r
4fea08b9
CJ
713 def _GetAttribute(self):\r
714 return self.GetField(self._ATTR_)[0]\r
e95a0dfb 715\r
4fea08b9
CJ
716 def _SetGuid(self, Guid):\r
717 self.SetField(self._GUID_, 0, Guid)\r
e95a0dfb 718\r
4fea08b9
CJ
719 def _GetGuid(self):\r
720 return self.GetField(self._GUID_)\r
e95a0dfb 721\r
4fea08b9
CJ
722 def _SetDataOffset(self, Offset):\r
723 self.SetField(self._DATA_OFFSET_, 0, Offset)\r
e95a0dfb 724\r
4fea08b9
CJ
725 def _GetDataOffset(self):\r
726 return self.GetField(self._DATA_OFFSET_)[0]\r
e95a0dfb 727\r
4fea08b9 728 def _GetSections(self):\r
e95a0dfb 729 SectionList = []\r
4fea08b9
CJ
730 Guid = gGuidStringFormat % self.SectionDefinitionGuid\r
731 if Guid == self.CRC32_GUID:\r
e95a0dfb 732 # skip the CRC32 value, we don't do CRC32 verification here\r
4fea08b9
CJ
733 Offset = self.DataOffset - 4\r
734 while Offset < len(self):\r
e95a0dfb
JC
735 Sec = Section()\r
736 try:\r
4fea08b9 737 Sec.frombuffer(self, Offset)\r
e95a0dfb
JC
738 Offset += Sec.Size\r
739 # the section is aligned to 4-byte boundary\r
740 Offset = (Offset + 3) & (~3)\r
741 except:\r
742 break\r
743 SectionList.append(Sec)\r
4fea08b9 744 elif Guid == self.TIANO_COMPRESS_GUID:\r
e95a0dfb 745 try:\r
64429fbd 746 from . import EfiCompressor\r
e95a0dfb 747 # skip the header\r
4fea08b9
CJ
748 Offset = self.DataOffset - 4\r
749 TmpData = EfiCompressor.FrameworkDecompress(self[Offset:], len(self)-Offset)\r
e95a0dfb
JC
750 DecData = array('B')\r
751 DecData.fromstring(TmpData)\r
752 Offset = 0\r
753 while Offset < len(DecData):\r
754 Sec = Section()\r
755 try:\r
756 Sec.frombuffer(DecData, Offset)\r
757 Offset += Sec.Size\r
758 # the section is aligned to 4-byte boundary\r
759 Offset = (Offset + 3) & (~3)\r
760 except:\r
761 break\r
762 SectionList.append(Sec)\r
763 except:\r
764 pass\r
4fea08b9 765 elif Guid == self.LZMA_COMPRESS_GUID:\r
e95a0dfb 766 try:\r
64429fbd 767 from . import LzmaCompressor\r
e95a0dfb 768 # skip the header\r
4fea08b9
CJ
769 Offset = self.DataOffset - 4\r
770 TmpData = LzmaCompressor.LzmaDecompress(self[Offset:], len(self)-Offset)\r
e95a0dfb
JC
771 DecData = array('B')\r
772 DecData.fromstring(TmpData)\r
773 Offset = 0\r
774 while Offset < len(DecData):\r
775 Sec = Section()\r
776 try:\r
777 Sec.frombuffer(DecData, Offset)\r
778 Offset += Sec.Size\r
779 # the section is aligned to 4-byte boundary\r
780 Offset = (Offset + 3) & (~3)\r
781 except:\r
782 break\r
783 SectionList.append(Sec)\r
784 except:\r
785 pass\r
786\r
787 return SectionList\r
788\r
789 Attributes = property(_GetAttribute, _SetAttribute)\r
790 SectionDefinitionGuid = property(_GetGuid, _SetGuid)\r
791 DataOffset = property(_GetDataOffset, _SetDataOffset)\r
792 Sections = property(_GetSections)\r
793\r
794## Section() class\r
795#\r
796# A class for Section\r
797#\r
798class Section(Image):\r
799 _TypeName = {\r
800 0x00 : "<unknown>",\r
801 0x01 : "COMPRESSION",\r
802 0x02 : "GUID_DEFINED",\r
803 0x10 : "PE32",\r
804 0x11 : "PIC",\r
805 0x12 : "TE",\r
806 0x13 : "DXE_DEPEX",\r
807 0x14 : "VERSION",\r
808 0x15 : "USER_INTERFACE",\r
809 0x16 : "COMPATIBILITY16",\r
810 0x17 : "FIRMWARE_VOLUME_IMAGE",\r
811 0x18 : "FREEFORM_SUBTYPE_GUID",\r
812 0x19 : "RAW",\r
813 0x1B : "PEI_DEPEX"\r
814 }\r
815\r
816 _SectionSubImages = {\r
817 0x01 : CompressedImage,\r
818 0x02 : GuidDefinedImage,\r
819 0x17 : FirmwareVolume,\r
820 0x13 : Depex,\r
821 0x1B : Depex,\r
822 0x15 : Ui\r
823 }\r
824\r
825 # Size = 3-byte\r
826 # Type = 1-byte\r
827 _HEADER_ = struct.Struct("3B 1B")\r
828 _HEADER_SIZE_ = _HEADER_.size\r
829\r
830 # SubTypeGuid\r
831 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")\r
e95a0dfb
JC
832 _SIZE_ = struct.Struct("3B")\r
833 _TYPE_ = struct.Struct("3x 1B")\r
834\r
4fea08b9
CJ
835 def __init__(self, Type=None, Size=None):\r
836 Image.__init__(self)\r
837 self._Alignment = 1\r
e95a0dfb 838 if Type is not None:\r
4fea08b9 839 self.Type = Type\r
e95a0dfb 840 if Size is not None:\r
4fea08b9 841 self.Size = Size\r
e95a0dfb 842\r
4fea08b9 843 def __str__(self):\r
e95a0dfb
JC
844 global gIndention\r
845 gIndention += 4\r
846 SectionInfo = ' ' * gIndention\r
4fea08b9
CJ
847 if self.Type in self._TypeName:\r
848 SectionInfo += "[SECTION:%s] offset=%x size=%x" % (self._TypeName[self.Type], self._OFF_, self.Size)\r
e95a0dfb 849 else:\r
4fea08b9
CJ
850 SectionInfo += "[SECTION:%x<unknown>] offset=%x size=%x " % (self.Type, self._OFF_, self.Size)\r
851 for Offset in self._SubImages:\r
852 SectionInfo += ", " + str(self._SubImages[Offset])\r
e95a0dfb
JC
853 gIndention -= 4\r
854 return SectionInfo\r
855\r
4fea08b9
CJ
856 def _Unpack(self):\r
857 self.empty()\r
858 Type, = self._TYPE_.unpack_from(self._BUF_, self._OFF_)\r
859 Size1, Size2, Size3 = self._SIZE_.unpack_from(self._BUF_, self._OFF_)\r
e95a0dfb
JC
860 Size = Size1 + (Size2 << 8) + (Size3 << 16)\r
861\r
4fea08b9 862 if Type not in self._SectionSubImages:\r
e95a0dfb 863 # no need to extract sub-image, keep all in this Image object\r
4fea08b9 864 self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size])\r
e95a0dfb
JC
865 else:\r
866 # keep header in this Image object\r
4fea08b9 867 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._HEADER_SIZE_])\r
e95a0dfb
JC
868 #\r
869 # use new Image object to represent payload, which may be another kind\r
870 # of image such as PE32\r
871 #\r
4fea08b9
CJ
872 PayloadOffset = self._HEADER_SIZE_\r
873 PayloadLen = self.Size - self._HEADER_SIZE_\r
874 Payload = self._SectionSubImages[self.Type]()\r
875 Payload.frombuffer(self._BUF_, self._OFF_ + self._HEADER_SIZE_, PayloadLen)\r
876 self._SubImages[PayloadOffset] = Payload\r
e95a0dfb
JC
877\r
878 return Size\r
879\r
4fea08b9 880 def _SetSize(self, Size):\r
e95a0dfb
JC
881 Size1 = Size & 0xFF\r
882 Size2 = (Size & 0xFF00) >> 8\r
883 Size3 = (Size & 0xFF0000) >> 16\r
4fea08b9 884 self.SetField(self._SIZE_, 0, Size1, Size2, Size3)\r
e95a0dfb 885\r
4fea08b9
CJ
886 def _GetSize(self):\r
887 Size1, Size2, Size3 = self.GetField(self._SIZE_)\r
e95a0dfb
JC
888 return Size1 + (Size2 << 8) + (Size3 << 16)\r
889\r
4fea08b9
CJ
890 def _SetType(self, Type):\r
891 self.SetField(self._TYPE_, 0, Type)\r
e95a0dfb 892\r
4fea08b9
CJ
893 def _GetType(self):\r
894 return self.GetField(self._TYPE_)[0]\r
e95a0dfb 895\r
4fea08b9
CJ
896 def _GetAlignment(self):\r
897 return self._Alignment\r
e95a0dfb 898\r
4fea08b9
CJ
899 def _SetAlignment(self, Alignment):\r
900 self._Alignment = Alignment\r
e95a0dfb
JC
901 AlignmentMask = Alignment - 1\r
902 # section alignment is actually for payload, so we need to add header size\r
4fea08b9 903 PayloadOffset = self._OFF_ + self._HEADER_SIZE_\r
e95a0dfb
JC
904 if (PayloadOffset & (~AlignmentMask)) == 0:\r
905 return\r
906 NewOffset = (PayloadOffset + AlignmentMask) & (~AlignmentMask)\r
4fea08b9
CJ
907 while (NewOffset - PayloadOffset) < self._HEADER_SIZE_:\r
908 NewOffset += self._Alignment\r
e95a0dfb 909\r
4fea08b9
CJ
910 def tofile(self, f):\r
911 self.Size = len(self)\r
912 Image.tofile(self, f)\r
913 for Offset in self._SubImages:\r
914 self._SubImages[Offset].tofile(f)\r
e95a0dfb
JC
915\r
916 Type = property(_GetType, _SetType)\r
917 Size = property(_GetSize, _SetSize)\r
918 Alignment = property(_GetAlignment, _SetAlignment)\r
919\r
920## Ffs() class\r
921#\r
922# A class for Ffs Section\r
923#\r
924class Ffs(Image):\r
925 _FfsFormat = "24B%(payload_size)sB"\r
926 # skip IntegrityCheck\r
927 _HEADER_ = struct.Struct("1I2H8B 2x 1B 1B 3B 1B")\r
928 _HEADER_SIZE_ = _HEADER_.size\r
929\r
930 _NAME_ = struct.Struct("1I2H8B")\r
931 _INT_CHECK_ = struct.Struct("16x 1H")\r
932 _TYPE_ = struct.Struct("18x 1B")\r
933 _ATTR_ = struct.Struct("19x 1B")\r
934 _SIZE_ = struct.Struct("20x 3B")\r
935 _STATE_ = struct.Struct("23x 1B")\r
936\r
937 VTF_GUID = "1BA0062E-C779-4582-8566-336AE8F78F09"\r
938\r
939 FFS_ATTRIB_FIXED = 0x04\r
940 FFS_ATTRIB_DATA_ALIGNMENT = 0x38\r
941 FFS_ATTRIB_CHECKSUM = 0x40\r
942\r
943 _TypeName = {\r
944 0x00 : "<unknown>",\r
945 0x01 : "RAW",\r
946 0x02 : "FREEFORM",\r
947 0x03 : "SECURITY_CORE",\r
948 0x04 : "PEI_CORE",\r
949 0x05 : "DXE_CORE",\r
950 0x06 : "PEIM",\r
951 0x07 : "DRIVER",\r
952 0x08 : "COMBINED_PEIM_DRIVER",\r
953 0x09 : "APPLICATION",\r
954 0x0A : "SMM",\r
955 0x0B : "FIRMWARE_VOLUME_IMAGE",\r
956 0x0C : "COMBINED_SMM_DXE",\r
957 0x0D : "SMM_CORE",\r
958 0x0E : "MM_STANDALONE",\r
959 0x0F : "MM_CORE_STANDALONE",\r
960 0xc0 : "OEM_MIN",\r
961 0xdf : "OEM_MAX",\r
962 0xe0 : "DEBUG_MIN",\r
963 0xef : "DEBUG_MAX",\r
964 0xf0 : "FFS_MIN",\r
965 0xff : "FFS_MAX",\r
966 0xf0 : "FFS_PAD",\r
967 }\r
968\r
969 def __init__(self):\r
970 Image.__init__(self)\r
971 self.FreeSpace = 0\r
972\r
973 self.Sections = sdict()\r
974 self.Depex = ''\r
975\r
976 self.__ID__ = None\r
977\r
978 def __str__(self):\r
979 global gIndention\r
980 gIndention += 4\r
981 Indention = ' ' * gIndention\r
982 FfsInfo = Indention\r
983 FfsInfo += "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \\r
984 (Ffs._TypeName[self.Type], self._OFF_, self.Size, self.Guid, self.FreeSpace, self.Alignment)\r
985 SectionInfo = '\n'.join([str(self.Sections[Offset]) for Offset in self.Sections])\r
986 gIndention -= 4\r
987 return FfsInfo + SectionInfo + "\n"\r
988\r
989 def __len__(self):\r
990 return self.Size\r
991\r
992 def __repr__(self):\r
993 return self.__ID__\r
994\r
995 def _Unpack(self):\r
996 Size1, Size2, Size3 = self._SIZE_.unpack_from(self._BUF_, self._OFF_)\r
997 Size = Size1 + (Size2 << 8) + (Size3 << 16)\r
998 self.empty()\r
999 self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size])\r
1000\r
1001 # Pad FFS may use the same GUID. We need to avoid it.\r
1002 if self.Type == 0xf0:\r
1003 self.__ID__ = str(uuid.uuid1()).upper()\r
1004 else:\r
1005 self.__ID__ = self.Guid\r
1006\r
1007 # Traverse the SECTION. RAW and PAD do not have sections\r
1008 if self.Type not in [0xf0, 0x01] and Size > 0 and Size < 0xFFFFFF:\r
1009 EndOfFfs = Size\r
1010 SectionStartAddress = self._HEADER_SIZE_\r
1011 while SectionStartAddress < EndOfFfs:\r
1012 SectionObj = Section()\r
1013 SectionObj.frombuffer(self, SectionStartAddress)\r
1014 #f = open(repr(SectionObj), 'wb')\r
1015 #SectionObj.Size = 0\r
1016 #SectionObj.tofile(f)\r
1017 #f.close()\r
1018 self.Sections[SectionStartAddress] = SectionObj\r
1019 SectionStartAddress += len(SectionObj)\r
1020 SectionStartAddress = (SectionStartAddress + 3) & (~3)\r
1021\r
1022 def Pack(self):\r
1023 pass\r
1024\r
1025 def SetFreeSpace(self, Size):\r
1026 self.FreeSpace = Size\r
1027\r
1028 def _GetGuid(self):\r
1029 return gGuidStringFormat % self.Name\r
1030\r
1031 def _SetName(self, Value):\r
1032 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1033 self.SetField(self._NAME_, 0, Value)\r
1034\r
1035 def _GetName(self):\r
1036 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1037 return self.GetField(self._NAME_)\r
1038\r
4fea08b9 1039 def _SetSize(self, Size):\r
e95a0dfb
JC
1040 Size1 = Size & 0xFF\r
1041 Size2 = (Size & 0xFF00) >> 8\r
1042 Size3 = (Size & 0xFF0000) >> 16\r
4fea08b9 1043 self.SetField(self._SIZE_, 0, Size1, Size2, Size3)\r
e95a0dfb 1044\r
4fea08b9
CJ
1045 def _GetSize(self):\r
1046 Size1, Size2, Size3 = self.GetField(self._SIZE_)\r
e95a0dfb
JC
1047 return Size1 + (Size2 << 8) + (Size3 << 16)\r
1048\r
4fea08b9
CJ
1049 def _SetType(self, Type):\r
1050 self.SetField(self._TYPE_, 0, Type)\r
e95a0dfb 1051\r
4fea08b9
CJ
1052 def _GetType(self):\r
1053 return self.GetField(self._TYPE_)[0]\r
e95a0dfb
JC
1054\r
1055 def _SetAttributes(self, Value):\r
4fea08b9 1056 self.SetField(self._ATTR_, 0, Value)\r
e95a0dfb
JC
1057\r
1058 def _GetAttributes(self):\r
1059 return self.GetField(self._ATTR_)[0]\r
1060\r
1061 def _GetFixed(self):\r
1062 if (self.Attributes & self.FFS_ATTRIB_FIXED) != 0:\r
1063 return True\r
1064 return False\r
1065\r
1066 def _GetCheckSum(self):\r
1067 if (self.Attributes & self.FFS_ATTRIB_CHECKSUM) != 0:\r
1068 return True\r
1069 return False\r
1070\r
1071 def _GetAlignment(self):\r
1072 return (self.Attributes & self.FFS_ATTRIB_DATA_ALIGNMENT) >> 3\r
1073\r
1074 def _SetState(self, Value):\r
4fea08b9 1075 self.SetField(self._STATE_, 0, Value)\r
e95a0dfb
JC
1076\r
1077 def _GetState(self):\r
4fea08b9 1078 return self.GetField(self._STATE_)[0]\r
e95a0dfb
JC
1079\r
1080 Name = property(_GetName, _SetName)\r
1081 Guid = property(_GetGuid)\r
1082 Type = property(_GetType, _SetType)\r
1083 Size = property(_GetSize, _SetSize)\r
1084 Attributes = property(_GetAttributes, _SetAttributes)\r
1085 Fixed = property(_GetFixed)\r
1086 Checksum = property(_GetCheckSum)\r
1087 Alignment = property(_GetAlignment)\r
1088 State = property(_GetState, _SetState)\r
1089\r
1090## FirmwareVolume() class\r
1091#\r
1092# A class for Firmware Volume\r
1093#\r
1094class FirmwareVolume(Image):\r
1095 # Read FvLength, Attributes, HeaderLength, Checksum\r
1096 _HEADER_ = struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")\r
1097 _HEADER_SIZE_ = _HEADER_.size\r
1098\r
1099 _FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"\r
1100\r
1101 _GUID_ = struct.Struct("16x 1I2H8B")\r
1102 _LENGTH_ = struct.Struct("16x 16x 1Q")\r
1103 _SIG_ = struct.Struct("16x 16x 8x 1I")\r
1104 _ATTR_ = struct.Struct("16x 16x 8x 4x 1I")\r
1105 _HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")\r
1106 _CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")\r
1107\r
1108 def __init__(self, Name=''):\r
1109 Image.__init__(self)\r
1110 self.Name = Name\r
1111 self.FfsDict = sdict()\r
1112 self.OrderedFfsDict = sdict()\r
1113 self.UnDispatchedFfsDict = sdict()\r
1114 self.ProtocolList = sdict()\r
1115\r
1116 def CheckArchProtocol(self):\r
1117 for Item in EotGlobalData.gArchProtocolGuids:\r
1118 if Item.lower() not in EotGlobalData.gProtocolList:\r
e95a0dfb 1119 return False\r
e95a0dfb
JC
1120 return True\r
1121\r
1122 def ParseDepex(self, Depex, Type):\r
1123 List = None\r
1124 if Type == 'Ppi':\r
1125 List = EotGlobalData.gPpiList\r
1126 if Type == 'Protocol':\r
1127 List = EotGlobalData.gProtocolList\r
1128 DepexStack = []\r
1129 DepexList = []\r
1130 DepexString = ''\r
1131 FileDepex = None\r
1132 CouldBeLoaded = True\r
1133 for Index in range(0, len(Depex.Expression)):\r
1134 Item = Depex.Expression[Index]\r
1135 if Item == 0x00:\r
1136 Index = Index + 1\r
1137 Guid = gGuidStringFormat % Depex.Expression[Index]\r
1138 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
1139 return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE'])\r
1140 elif Item == 0x01:\r
1141 Index = Index + 1\r
1142 Guid = gGuidStringFormat % Depex.Expression[Index]\r
1143 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
1144 return (True, 'AFTER %s' % Guid, [Guid, 'AFTER'])\r
1145 elif Item == 0x02:\r
1146 Index = Index + 1\r
1147 Guid = gGuidStringFormat % Depex.Expression[Index]\r
1148 if Guid.lower() in List:\r
1149 DepexStack.append(True)\r
1150 DepexList.append(Guid)\r
1151 else:\r
1152 DepexStack.append(False)\r
1153 DepexList.append(Guid)\r
1154 continue\r
1155 elif Item == 0x03 or Item == 0x04:\r
1156 DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
1157 DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCODE_STRING_[Item].upper() + ' ' + str(DepexList.pop()))\r
1158 elif Item == 0x05:\r
1159 DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
1160 DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexList.pop()))\r
1161 elif Item == 0x06:\r
1162 DepexStack.append(True)\r
1163 DepexList.append('TRUE')\r
1164 DepexString = DepexString + 'TRUE' + ' '\r
1165 elif Item == 0x07:\r
1166 DepexStack.append(False)\r
1167 DepexList.append('False')\r
1168 DepexString = DepexString + 'FALSE' + ' '\r
1169 elif Item == 0x08:\r
1170 if Index != len(Depex.Expression) - 1:\r
1171 CouldBeLoaded = False\r
1172 else:\r
1173 CouldBeLoaded = DepexStack.pop()\r
1174 else:\r
1175 CouldBeLoaded = False\r
1176 if DepexList != []:\r
1177 DepexString = DepexList[0].strip()\r
1178 return (CouldBeLoaded, DepexString, FileDepex)\r
1179\r
1180 def Dispatch(self, Db = None):\r
1181 if Db is None:\r
1182 return False\r
1183 self.UnDispatchedFfsDict = copy.copy(self.FfsDict)\r
1184 # Find PeiCore, DexCore, PeiPriori, DxePriori first\r
1185 FfsSecCoreGuid = None\r
1186 FfsPeiCoreGuid = None\r
1187 FfsDxeCoreGuid = None\r
1188 FfsPeiPrioriGuid = None\r
1189 FfsDxePrioriGuid = None\r
1190 for FfsID in self.UnDispatchedFfsDict:\r
1191 Ffs = self.UnDispatchedFfsDict[FfsID]\r
1192 if Ffs.Type == 0x03:\r
1193 FfsSecCoreGuid = FfsID\r
1194 continue\r
1195 if Ffs.Type == 0x04:\r
1196 FfsPeiCoreGuid = FfsID\r
1197 continue\r
1198 if Ffs.Type == 0x05:\r
1199 FfsDxeCoreGuid = FfsID\r
1200 continue\r
1201 if Ffs.Guid.lower() == gPeiAprioriFileNameGuid:\r
1202 FfsPeiPrioriGuid = FfsID\r
1203 continue\r
1204 if Ffs.Guid.lower() == gAprioriGuid:\r
1205 FfsDxePrioriGuid = FfsID\r
1206 continue\r
1207\r
1208 # Parse SEC_CORE first\r
1209 if FfsSecCoreGuid is not None:\r
1210 self.OrderedFfsDict[FfsSecCoreGuid] = self.UnDispatchedFfsDict.pop(FfsSecCoreGuid)\r
1211 self.LoadPpi(Db, FfsSecCoreGuid)\r
1212\r
1213 # Parse PEI first\r
1214 if FfsPeiCoreGuid is not None:\r
1215 self.OrderedFfsDict[FfsPeiCoreGuid] = self.UnDispatchedFfsDict.pop(FfsPeiCoreGuid)\r
1216 self.LoadPpi(Db, FfsPeiCoreGuid)\r
1217 if FfsPeiPrioriGuid is not None:\r
1218 # Load PEIM described in priori file\r
1219 FfsPeiPriori = self.UnDispatchedFfsDict.pop(FfsPeiPrioriGuid)\r
1220 if len(FfsPeiPriori.Sections) == 1:\r
1221 Section = FfsPeiPriori.Sections.popitem()[1]\r
1222 if Section.Type == 0x19:\r
1223 GuidStruct = struct.Struct('1I2H8B')\r
1224 Start = 4\r
1225 while len(Section) > Start:\r
1226 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
1227 GuidString = gGuidStringFormat % Guid\r
1228 Start = Start + 16\r
1229 if GuidString in self.UnDispatchedFfsDict:\r
1230 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
1231 self.LoadPpi(Db, GuidString)\r
1232\r
1233 self.DisPatchPei(Db)\r
1234\r
1235 # Parse DXE then\r
1236 if FfsDxeCoreGuid is not None:\r
1237 self.OrderedFfsDict[FfsDxeCoreGuid] = self.UnDispatchedFfsDict.pop(FfsDxeCoreGuid)\r
1238 self.LoadProtocol(Db, FfsDxeCoreGuid)\r
1239 if FfsDxePrioriGuid is not None:\r
1240 # Load PEIM described in priori file\r
1241 FfsDxePriori = self.UnDispatchedFfsDict.pop(FfsDxePrioriGuid)\r
1242 if len(FfsDxePriori.Sections) == 1:\r
1243 Section = FfsDxePriori.Sections.popitem()[1]\r
1244 if Section.Type == 0x19:\r
1245 GuidStruct = struct.Struct('1I2H8B')\r
1246 Start = 4\r
1247 while len(Section) > Start:\r
1248 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
1249 GuidString = gGuidStringFormat % Guid\r
1250 Start = Start + 16\r
1251 if GuidString in self.UnDispatchedFfsDict:\r
1252 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
1253 self.LoadProtocol(Db, GuidString)\r
1254\r
1255 self.DisPatchDxe(Db)\r
1256\r
1257 def LoadProtocol(self, Db, ModuleGuid):\r
1258 SqlCommand = """select GuidValue from Report\r
1259 where SourceFileFullPath in\r
1260 (select Value1 from Inf where BelongsToFile =\r
1261 (select BelongsToFile from Inf\r
1262 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
1263 and Model = %s)\r
1264 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \\r
1265 % (ModuleGuid, 5001, 3007)\r
1266 RecordSet = Db.TblReport.Exec(SqlCommand)\r
1267 for Record in RecordSet:\r
1268 SqlCommand = """select Value2 from Inf where BelongsToFile =\r
1269 (select DISTINCT BelongsToFile from Inf\r
1270 where Value1 =\r
1271 (select SourceFileFullPath from Report\r
1272 where GuidValue like '%s' and ItemMode = 'Callback'))\r
1273 and Value1 = 'FILE_GUID'""" % Record[0]\r
1274 CallBackSet = Db.TblReport.Exec(SqlCommand)\r
1275 if CallBackSet != []:\r
1276 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
1277 else:\r
1278 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
1279\r
1280 def LoadPpi(self, Db, ModuleGuid):\r
1281 SqlCommand = """select GuidValue from Report\r
1282 where SourceFileFullPath in\r
1283 (select Value1 from Inf where BelongsToFile =\r
1284 (select BelongsToFile from Inf\r
1285 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
1286 and Model = %s)\r
1287 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \\r
1288 % (ModuleGuid, 5001, 3007)\r
1289 RecordSet = Db.TblReport.Exec(SqlCommand)\r
1290 for Record in RecordSet:\r
1291 EotGlobalData.gPpiList[Record[0].lower()] = ModuleGuid\r
1292\r
1293 def DisPatchDxe(self, Db):\r
1294 IsInstalled = False\r
1295 ScheduleList = sdict()\r
1296 for FfsID in self.UnDispatchedFfsDict:\r
1297 CouldBeLoaded = False\r
1298 DepexString = ''\r
1299 FileDepex = None\r
1300 Ffs = self.UnDispatchedFfsDict[FfsID]\r
1301 if Ffs.Type == 0x07:\r
1302 # Get Depex\r
1303 IsFoundDepex = False\r
1304 for Section in Ffs.Sections.values():\r
1305 # Find Depex\r
1306 if Section.Type == 0x13:\r
1307 IsFoundDepex = True\r
1308 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Protocol')\r
1309 break\r
1310 if Section.Type == 0x01:\r
1311 CompressSections = Section._SubImages[4]\r
1312 for CompressSection in CompressSections.Sections:\r
1313 if CompressSection.Type == 0x13:\r
1314 IsFoundDepex = True\r
1315 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Protocol')\r
1316 break\r
1317 if CompressSection.Type == 0x02:\r
1318 NewSections = CompressSection._SubImages[4]\r
1319 for NewSection in NewSections.Sections:\r
1320 if NewSection.Type == 0x13:\r
1321 IsFoundDepex = True\r
1322 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Protocol')\r
1323 break\r
1324\r
1325 # Not find Depex\r
1326 if not IsFoundDepex:\r
1327 CouldBeLoaded = self.CheckArchProtocol()\r
1328 DepexString = ''\r
1329 FileDepex = None\r
1330\r
1331 # Append New Ffs\r
1332 if CouldBeLoaded:\r
1333 IsInstalled = True\r
1334 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
1335 NewFfs.Depex = DepexString\r
1336 if FileDepex is not None:\r
1337 ScheduleList.insert(FileDepex[1], FfsID, NewFfs, FileDepex[0])\r
1338 else:\r
1339 ScheduleList[FfsID] = NewFfs\r
1340 else:\r
1341 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
1342\r
1343 for FfsID in ScheduleList:\r
1344 NewFfs = ScheduleList.pop(FfsID)\r
1345 FfsName = 'UnKnown'\r
1346 self.OrderedFfsDict[FfsID] = NewFfs\r
1347 self.LoadProtocol(Db, FfsID)\r
1348\r
1349 SqlCommand = """select Value2 from Inf\r
1350 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
1351 and Model = %s and Value1='BASE_NAME'""" % (FfsID, 5001, 5001)\r
1352 RecordSet = Db.TblReport.Exec(SqlCommand)\r
1353 if RecordSet != []:\r
1354 FfsName = RecordSet[0][0]\r
1355\r
1356 if IsInstalled:\r
1357 self.DisPatchDxe(Db)\r
1358\r
1359 def DisPatchPei(self, Db):\r
1360 IsInstalled = False\r
1361 for FfsID in self.UnDispatchedFfsDict:\r
1362 CouldBeLoaded = True\r
1363 DepexString = ''\r
1364 FileDepex = None\r
1365 Ffs = self.UnDispatchedFfsDict[FfsID]\r
1366 if Ffs.Type == 0x06 or Ffs.Type == 0x08:\r
1367 # Get Depex\r
1368 for Section in Ffs.Sections.values():\r
1369 if Section.Type == 0x1B:\r
1370 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')\r
1371 break\r
e95a0dfb
JC
1372 if Section.Type == 0x01:\r
1373 CompressSections = Section._SubImages[4]\r
1374 for CompressSection in CompressSections.Sections:\r
1375 if CompressSection.Type == 0x1B:\r
1376 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Ppi')\r
1377 break\r
1378 if CompressSection.Type == 0x02:\r
1379 NewSections = CompressSection._SubImages[4]\r
1380 for NewSection in NewSections.Sections:\r
1381 if NewSection.Type == 0x1B:\r
1382 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Ppi')\r
1383 break\r
1384\r
1385 # Append New Ffs\r
1386 if CouldBeLoaded:\r
1387 IsInstalled = True\r
1388 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
1389 NewFfs.Depex = DepexString\r
1390 self.OrderedFfsDict[FfsID] = NewFfs\r
1391 self.LoadPpi(Db, FfsID)\r
1392 else:\r
1393 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
1394\r
1395 if IsInstalled:\r
1396 self.DisPatchPei(Db)\r
1397\r
1398\r
1399 def __str__(self):\r
1400 global gIndention\r
1401 gIndention += 4\r
1402 FvInfo = '\n' + ' ' * gIndention\r
1403 FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)\r
1404 FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])\r
1405 gIndention -= 4\r
1406 return FvInfo + FfsInfo\r
1407\r
1408 def _Unpack(self):\r
1409 Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]\r
1410 self.empty()\r
1411 self.extend(self._BUF_[self._OFF_:self._OFF_+Size])\r
1412\r
1413 # traverse the FFS\r
1414 EndOfFv = Size\r
1415 FfsStartAddress = self.HeaderSize\r
1416 LastFfsObj = None\r
1417 while FfsStartAddress < EndOfFv:\r
1418 FfsObj = Ffs()\r
1419 FfsObj.frombuffer(self, FfsStartAddress)\r
1420 FfsId = repr(FfsObj)\r
1421 if ((self.Attributes & 0x00000800) != 0 and len(FfsObj) == 0xFFFFFF) \\r
1422 or ((self.Attributes & 0x00000800) == 0 and len(FfsObj) == 0):\r
1423 if LastFfsObj is not None:\r
1424 LastFfsObj.FreeSpace = EndOfFv - LastFfsObj._OFF_ - len(LastFfsObj)\r
1425 else:\r
1426 if FfsId in self.FfsDict:\r
1427 EdkLogger.error("FV", 0, "Duplicate GUID in FFS",\r
1428 ExtraData="\t%s @ %s\n\t%s @ %s" \\r
1429 % (FfsObj.Guid, FfsObj.Offset,\r
1430 self.FfsDict[FfsId].Guid, self.FfsDict[FfsId].Offset))\r
1431 self.FfsDict[FfsId] = FfsObj\r
1432 if LastFfsObj is not None:\r
1433 LastFfsObj.FreeSpace = FfsStartAddress - LastFfsObj._OFF_ - len(LastFfsObj)\r
1434\r
1435 FfsStartAddress += len(FfsObj)\r
1436 #\r
1437 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))\r
1438 # The next FFS must be at the latest next 8-byte aligned address\r
1439 #\r
1440 FfsStartAddress = (FfsStartAddress + 7) & (~7)\r
1441 LastFfsObj = FfsObj\r
1442\r
1443 def _GetAttributes(self):\r
1444 return self.GetField(self._ATTR_, 0)[0]\r
1445\r
1446 def _GetSize(self):\r
1447 return self.GetField(self._LENGTH_, 0)[0]\r
1448\r
1449 def _GetChecksum(self):\r
1450 return self.GetField(self._CHECKSUM_, 0)[0]\r
1451\r
1452 def _GetHeaderLength(self):\r
1453 return self.GetField(self._HLEN_, 0)[0]\r
1454\r
1455 def _GetFileSystemGuid(self):\r
1456 return gGuidStringFormat % self.GetField(self._GUID_, 0)\r
1457\r
1458 Attributes = property(_GetAttributes)\r
1459 Size = property(_GetSize)\r
1460 Checksum = property(_GetChecksum)\r
1461 HeaderSize = property(_GetHeaderLength)\r
1462 FileSystemGuid = property(_GetFileSystemGuid)\r
52302d4d 1463\r
d498274f
CJ
1464## MultipleFv() class\r
1465#\r
1466# A class for Multiple FV\r
1467#\r
1468class MultipleFv(FirmwareVolume):\r
1469 def __init__(self, FvList):\r
1470 FirmwareVolume.__init__(self)\r
1471 self.BasicInfo = []\r
1472 for FvPath in FvList:\r
1473 FvName = os.path.splitext(os.path.split(FvPath)[1])[0]\r
1474 Fd = open(FvPath, 'rb')\r
1475 Buf = array('B')\r
1476 try:\r
1477 Buf.fromfile(Fd, os.path.getsize(FvPath))\r
1478 except EOFError:\r
1479 pass\r
1480\r
1481 Fv = FirmwareVolume(FvName)\r
1482 Fv.frombuffer(Buf, 0, len(Buf))\r
1483\r
1484 self.BasicInfo.append([Fv.Name, Fv.FileSystemGuid, Fv.Size])\r
f7496d71 1485 self.FfsDict.append(Fv.FfsDict)\r
d498274f 1486\r
52302d4d
LG
1487## Class Eot\r
1488#\r
1489# This class is used to define Eot main entrance\r
1490#\r
1491# @param object: Inherited from object class\r
1492#\r
1493class Eot(object):\r
1494 ## The constructor\r
1495 #\r
1496 # @param self: The object pointer\r
1497 #\r
1498 def __init__(self, CommandLineOption=True, IsInit=True, SourceFileList=None, \\r
1499 IncludeDirList=None, DecFileList=None, GuidList=None, LogFile=None,\r
1500 FvFileList="", MapFileList="", Report='Report.html', Dispatch=None):\r
1501 # Version and Copyright\r
b36d134f 1502 self.VersionNumber = ("0.02" + " " + gBUILD_VERSION)\r
52302d4d 1503 self.Version = "%prog Version " + self.VersionNumber\r
f7496d71 1504 self.Copyright = "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."\r
52302d4d
LG
1505 self.Report = Report\r
1506\r
1507 self.IsInit = IsInit\r
1508 self.SourceFileList = SourceFileList\r
1509 self.IncludeDirList = IncludeDirList\r
1510 self.DecFileList = DecFileList\r
1511 self.GuidList = GuidList\r
1512 self.LogFile = LogFile\r
1513 self.FvFileList = FvFileList\r
1514 self.MapFileList = MapFileList\r
1515 self.Dispatch = Dispatch\r
f7496d71 1516\r
52302d4d
LG
1517 # Check workspace environment\r
1518 if "EFI_SOURCE" not in os.environ:\r
1519 if "EDK_SOURCE" not in os.environ:\r
1520 pass\r
1521 else:\r
1522 EotGlobalData.gEDK_SOURCE = os.path.normpath(os.getenv("EDK_SOURCE"))\r
1523 else:\r
1524 EotGlobalData.gEFI_SOURCE = os.path.normpath(os.getenv("EFI_SOURCE"))\r
1525 EotGlobalData.gEDK_SOURCE = os.path.join(EotGlobalData.gEFI_SOURCE, 'Edk')\r
1526\r
1527 if "WORKSPACE" not in os.environ:\r
1528 EdkLogger.error("EOT", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
1529 ExtraData="WORKSPACE")\r
1530 else:\r
1531 EotGlobalData.gWORKSPACE = os.path.normpath(os.getenv("WORKSPACE"))\r
1532\r
1533 EotGlobalData.gMACRO['WORKSPACE'] = EotGlobalData.gWORKSPACE\r
1534 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gEFI_SOURCE\r
1535 EotGlobalData.gMACRO['EDK_SOURCE'] = EotGlobalData.gEDK_SOURCE\r
1536\r
1537 # Parse the options and args\r
1538 if CommandLineOption:\r
1539 self.ParseOption()\r
1540\r
1541 if self.FvFileList:\r
1542 for FvFile in GetSplitValueList(self.FvFileList, ' '):\r
1543 FvFile = os.path.normpath(FvFile)\r
1544 if not os.path.isfile(FvFile):\r
1545 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % FvFile)\r
1546 EotGlobalData.gFV_FILE.append(FvFile)\r
1547 else:\r
1548 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "The fv file list of target platform was not specified")\r
1549\r
1550 if self.MapFileList:\r
1551 for MapFile in GetSplitValueList(self.MapFileList, ' '):\r
1552 MapFile = os.path.normpath(MapFile)\r
1553 if not os.path.isfile(MapFile):\r
1554 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % MapFile)\r
1555 EotGlobalData.gMAP_FILE.append(MapFile)\r
f7496d71 1556\r
52302d4d
LG
1557 # Generate source file list\r
1558 self.GenerateSourceFileList(self.SourceFileList, self.IncludeDirList)\r
1559\r
1560 # Generate guid list of dec file list\r
1561 self.ParseDecFile(self.DecFileList)\r
f7496d71 1562\r
52302d4d
LG
1563 # Generate guid list from GUID list file\r
1564 self.ParseGuidList(self.GuidList)\r
1565\r
1566 # Init Eot database\r
1567 EotGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
1568 EotGlobalData.gDb.InitDatabase(self.IsInit)\r
1569\r
1570 # Build ECC database\r
1571 self.BuildDatabase()\r
1572\r
1573 # Parse Ppi/Protocol\r
1574 self.ParseExecutionOrder()\r
1575\r
1576 # Merge Identifier tables\r
1577 self.GenerateQueryTable()\r
1578\r
1579 # Generate report database\r
1580 self.GenerateReportDatabase()\r
1581\r
1582 # Load Fv Info\r
1583 self.LoadFvInfo()\r
1584\r
1585 # Load Map Info\r
1586 self.LoadMapInfo()\r
1587\r
1588 # Generate Report\r
1589 self.GenerateReport()\r
1590\r
1591 # Convert log file\r
1592 self.ConvertLogFile(self.LogFile)\r
1593\r
1594 # DONE\r
1595 EdkLogger.quiet("EOT FINISHED!")\r
1596\r
1597 # Close Database\r
1598 EotGlobalData.gDb.Close()\r
1599\r
1600 ## ParseDecFile() method\r
1601 #\r
1602 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}\r
1603 # The Dict is stored in EotGlobalData.gGuidDict\r
1604 #\r
1605 # @param self: The object pointer\r
1606 # @param DecFileList: A list of all DEC files\r
1607 #\r
1608 def ParseDecFile(self, DecFileList):\r
1609 if DecFileList:\r
1610 path = os.path.normpath(DecFileList)\r
1611 lfr = open(path, 'rb')\r
1612 for line in lfr:\r
1613 path = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1614 if os.path.exists(path):\r
1615 dfr = open(path, 'rb')\r
1616 for line in dfr:\r
1617 line = CleanString(line)\r
1618 list = line.split('=')\r
1619 if len(list) == 2:\r
1620 EotGlobalData.gGuidDict[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())\r
1621\r
f7496d71 1622\r
52302d4d
LG
1623 ## ParseGuidList() method\r
1624 #\r
1625 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}\r
1626 # The Dict is stored in EotGlobalData.gGuidDict\r
1627 #\r
1628 # @param self: The object pointer\r
1629 # @param GuidList: A list of all GUID and its value\r
1630 #\r
1631 def ParseGuidList(self, GuidList):\r
1632 Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList)\r
1633 if os.path.isfile(Path):\r
1634 for Line in open(Path):\r
1635 (GuidName, GuidValue) = Line.split()\r
1636 EotGlobalData.gGuidDict[GuidName] = GuidValue\r
f7496d71 1637\r
52302d4d
LG
1638 ## ConvertLogFile() method\r
1639 #\r
1640 # Parse a real running log file to get real dispatch order\r
1641 # The result is saved to old file name + '.new'\r
1642 #\r
1643 # @param self: The object pointer\r
1644 # @param LogFile: A real running log file name\r
1645 #\r
1646 def ConvertLogFile(self, LogFile):\r
1647 newline = []\r
1648 lfr = None\r
1649 lfw = None\r
1650 if LogFile:\r
1651 lfr = open(LogFile, 'rb')\r
1652 lfw = open(LogFile + '.new', 'wb')\r
1653 for line in lfr:\r
1654 line = line.strip()\r
1655 line = line.replace('.efi', '')\r
1656 index = line.find("Loading PEIM at ")\r
1657 if index > -1:\r
1658 newline.append(line[index + 55 : ])\r
1659 continue\r
1660 index = line.find("Loading driver at ")\r
1661 if index > -1:\r
1662 newline.append(line[index + 57 : ])\r
1663 continue\r
1664\r
1665 for line in newline:\r
1666 lfw.write(line + '\r\n')\r
1667\r
1668 if lfr:\r
1669 lfr.close()\r
1670 if lfw:\r
1671 lfw.close()\r
1672\r
1673 ## GenerateSourceFileList() method\r
1674 #\r
1675 # Generate a list of all source files\r
1676 # 1. Search the file list one by one\r
1677 # 2. Store inf file name with source file names under it like\r
1678 # { INF file name: [source file1, source file2, ...]}\r
1679 # 3. Search the include list to find all .h files\r
1680 # 4. Store source file list to EotGlobalData.gSOURCE_FILES\r
1681 # 5. Store INF file list to EotGlobalData.gINF_FILES\r
1682 #\r
1683 # @param self: The object pointer\r
1684 # @param SourceFileList: A list of all source files\r
1685 # @param IncludeFileList: A list of all include files\r
1686 #\r
1687 def GenerateSourceFileList(self, SourceFileList, IncludeFileList):\r
1688 EdkLogger.quiet("Generating source files list ... ")\r
1689 mSourceFileList = []\r
1690 mInfFileList = []\r
1691 mDecFileList = []\r
1692 mFileList = {}\r
1693 mCurrentInfFile = ''\r
1694 mCurrentSourceFileList = []\r
1695\r
1696 if SourceFileList:\r
1697 sfl = open(SourceFileList, 'rb')\r
1698 for line in sfl:\r
1699 line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1700 if line[-2:].upper() == '.C' or line[-2:].upper() == '.H':\r
1701 if line not in mCurrentSourceFileList:\r
1702 mCurrentSourceFileList.append(line)\r
1703 mSourceFileList.append(line)\r
1704 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % line)\r
1705 if line[-4:].upper() == '.INF':\r
1706 if mCurrentInfFile != '':\r
1707 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1708 mCurrentSourceFileList = []\r
1709 mCurrentInfFile = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line))\r
1710 EotGlobalData.gOP_INF.write('%s\n' % mCurrentInfFile)\r
1711 if mCurrentInfFile not in mFileList:\r
1712 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1713\r
1714 # Get all include files from packages\r
1715 if IncludeFileList:\r
1716 ifl = open(IncludeFileList, 'rb')\r
1717 for line in ifl:\r
1718 if not line.strip():\r
1719 continue\r
1720 newline = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1721 for Root, Dirs, Files in os.walk(str(newline)):\r
1722 for File in Files:\r
1723 FullPath = os.path.normpath(os.path.join(Root, File))\r
1724 if FullPath not in mSourceFileList and File[-2:].upper() == '.H':\r
1725 mSourceFileList.append(FullPath)\r
1726 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % FullPath)\r
1727 if FullPath not in mDecFileList and File.upper().find('.DEC') > -1:\r
1728 mDecFileList.append(FullPath)\r
1729\r
1730 EotGlobalData.gSOURCE_FILES = mSourceFileList\r
1731 EotGlobalData.gOP_SOURCE_FILES.close()\r
1732\r
1733 EotGlobalData.gINF_FILES = mFileList\r
1734 EotGlobalData.gOP_INF.close()\r
1735\r
52302d4d
LG
1736 ## GenerateReport() method\r
1737 #\r
1738 # Generate final HTML report\r
1739 #\r
1740 # @param self: The object pointer\r
1741 #\r
1742 def GenerateReport(self):\r
1743 EdkLogger.quiet("Generating report file ... ")\r
1744 Rep = Report(self.Report, EotGlobalData.gFV, self.Dispatch)\r
1745 Rep.GenerateReport()\r
1746\r
1747 ## LoadMapInfo() method\r
1748 #\r
1749 # Load map files and parse them\r
1750 #\r
1751 # @param self: The object pointer\r
1752 #\r
1753 def LoadMapInfo(self):\r
1754 if EotGlobalData.gMAP_FILE != []:\r
1755 EdkLogger.quiet("Parsing Map file ... ")\r
1756 EotGlobalData.gMap = ParseMapFile(EotGlobalData.gMAP_FILE)\r
1757\r
1758 ## LoadFvInfo() method\r
1759 #\r
1760 # Load FV binary files and parse them\r
1761 #\r
1762 # @param self: The object pointer\r
1763 #\r
1764 def LoadFvInfo(self):\r
1765 EdkLogger.quiet("Parsing FV file ... ")\r
1766 EotGlobalData.gFV = MultipleFv(EotGlobalData.gFV_FILE)\r
1767 EotGlobalData.gFV.Dispatch(EotGlobalData.gDb)\r
1768\r
1769 for Protocol in EotGlobalData.gProtocolList:\r
1770 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s\n' %Protocol)\r
1771\r
1772 ## GenerateReportDatabase() method\r
1773 #\r
1774 # Generate data for the information needed by report\r
1775 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID\r
1776 # 2. Install hard coded PPI/PROTOCOL\r
1777 #\r
1778 # @param self: The object pointer\r
1779 #\r
1780 def GenerateReportDatabase(self):\r
1781 EdkLogger.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")\r
1782\r
1783 # Update Protocol/Ppi Guid\r
1784 SqlCommand = """select DISTINCT GuidName from Report"""\r
1785 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1786 for Record in RecordSet:\r
1787 GuidName = Record[0]\r
1788 GuidMacro = ''\r
1789 GuidMacro2 = ''\r
1790 GuidValue = ''\r
1791\r
52302d4d
LG
1792 # Find guid value defined in Dec file\r
1793 if GuidName in EotGlobalData.gGuidDict:\r
1794 GuidValue = EotGlobalData.gGuidDict[GuidName]\r
1795 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1796 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1797 continue\r
1798\r
1799 # Search defined Macros for guid name\r
1800 SqlCommand ="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName\r
1801 GuidMacroSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1802 # Ignore NULL result\r
1803 if not GuidMacroSet:\r
1804 continue\r
1805 GuidMacro = GuidMacroSet[0][0].strip()\r
1806 if not GuidMacro:\r
1807 continue\r
1808 # Find Guid value of Guid Macro\r
1809 SqlCommand ="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro, MODEL_IDENTIFIER_MACRO_DEFINE)\r
1810 GuidValueSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1811 if GuidValueSet != []:\r
1812 GuidValue = GuidValueSet[0][0]\r
1813 GuidValue = GuidValue[GuidValue.find(GuidMacro) + len(GuidMacro) :]\r
1814 GuidValue = GuidValue.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()\r
1815 GuidValue = GuidStructureStringToGuidString(GuidValue)\r
1816 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1817 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1818 continue\r
1819\r
1820 # Update Hard Coded Ppi/Protocol\r
1821 SqlCommand = """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""\r
1822 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1823 for Record in RecordSet:\r
e95a0dfb
JC
1824 if Record[1] == 'Ppi':\r
1825 EotGlobalData.gPpiList[Record[0].lower()] = -2\r
52302d4d
LG
1826 if Record[1] == 'Protocol':\r
1827 EotGlobalData.gProtocolList[Record[0].lower()] = -2\r
1828\r
1829 ## GenerateQueryTable() method\r
1830 #\r
1831 # Generate two tables improve query performance\r
1832 #\r
1833 # @param self: The object pointer\r
1834 #\r
1835 def GenerateQueryTable(self):\r
1836 EdkLogger.quiet("Generating temp query table for analysis ... ")\r
1837 for Identifier in EotGlobalData.gIdentifierTableList:\r
1838 SqlCommand = """insert into Query (Name, Modifier, Value, Model)\r
1839 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \\r
1840 % (Identifier[0], MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
1841 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1842 SqlCommand = """insert into Query2 (Name, Modifier, Value, Model)\r
1843 select Name, Modifier, Value, Model from %s where Model = %s""" \\r
1844 % (Identifier[0], MODEL_IDENTIFIER_MACRO_DEFINE)\r
1845 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1846\r
1847 ## ParseExecutionOrder() method\r
1848 #\r
1849 # Get final execution order\r
1850 # 1. Search all PPI\r
1851 # 2. Search all PROTOCOL\r
1852 #\r
1853 # @param self: The object pointer\r
1854 #\r
1855 def ParseExecutionOrder(self):\r
1856 EdkLogger.quiet("Searching Ppi/Protocol ... ")\r
1857 for Identifier in EotGlobalData.gIdentifierTableList:\r
1858 ModuleID, ModuleName, ModuleGuid, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, Enabled = \\r
1859 -1, '', '', -1, '', '', '', '', '', '', '', '', 0\r
1860\r
1861 SourceFileID = Identifier[0].replace('Identifier', '')\r
1862 SourceFileFullPath = Identifier[1]\r
1863 Identifier = Identifier[0]\r
1864\r
1865 # Find Ppis\r
1866 ItemMode = 'Produced'\r
1867 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1868 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1869 % (Identifier, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1870 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1871\r
1872 ItemMode = 'Produced'\r
1873 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1874 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1875 % (Identifier, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1876 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1877\r
1878 SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1879\r
1880 ItemMode = 'Consumed'\r
1881 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1882 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1883 % (Identifier, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1884 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1885\r
1886 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Ppi', ItemMode)\r
1887\r
1888 ItemMode = 'Callback'\r
1889 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1890 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1891 % (Identifier, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1892 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1893\r
1894 # Find Procotols\r
1895 ItemMode = 'Produced'\r
1896 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1897 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1898 % (Identifier, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1899 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1900\r
1901 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1902 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1903 % (Identifier, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1904 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1905\r
1906 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1907\r
1908 ItemMode = 'Consumed'\r
1909 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1910 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1911 % (Identifier, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1912 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1913\r
1914 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1915 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1916 % (Identifier, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1917 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1918\r
1919 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1920\r
1921 ItemMode = 'Callback'\r
1922 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1923 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1924 % (Identifier, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1925 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1926\r
1927 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1928\r
1929 # Hard Code\r
1930 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)\r
1931 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)\r
1932 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)\r
1933 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)\r
1934 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)\r
1935 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)\r
1936 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)\r
1937 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)\r
1938 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)\r
1939\r
1940 EotGlobalData.gDb.Conn.commit()\r
1941\r
1942\r
1943 ## BuildDatabase() methoc\r
1944 #\r
1945 # Build the database for target\r
1946 #\r
1947 # @param self: The object pointer\r
1948 #\r
1949 def BuildDatabase(self):\r
1950 # Clean report table\r
1951 EotGlobalData.gDb.TblReport.Drop()\r
1952 EotGlobalData.gDb.TblReport.Create()\r
1953\r
1954 # Build database\r
1955 if self.IsInit:\r
1956 self.BuildMetaDataFileDatabase(EotGlobalData.gINF_FILES)\r
1957 EdkLogger.quiet("Building database for source code ...")\r
1958 c.CreateCCodeDB(EotGlobalData.gSOURCE_FILES)\r
1959 EdkLogger.quiet("Building database for source code done!")\r
1960\r
1961 EotGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EotGlobalData.gDb)\r
1962\r
1963 ## BuildMetaDataFileDatabase() method\r
1964 #\r
1965 # Build the database for meta data files\r
1966 #\r
1967 # @param self: The object pointer\r
1968 # @param Inf_Files: A list for all INF files\r
1969 #\r
1970 def BuildMetaDataFileDatabase(self, Inf_Files):\r
1971 EdkLogger.quiet("Building database for meta data files ...")\r
1972 for InfFile in Inf_Files:\r
1973 EdkLogger.quiet("Parsing %s ..." % str(InfFile))\r
1974 EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '')\r
1975\r
1976 EotGlobalData.gDb.Conn.commit()\r
1977 EdkLogger.quiet("Building database for meta data files done!")\r
1978\r
1979 ## ParseOption() method\r
1980 #\r
1981 # Parse command line options\r
1982 #\r
1983 # @param self: The object pointer\r
1984 #\r
1985 def ParseOption(self):\r
1986 (Options, Target) = self.EotOptionParser()\r
1987\r
1988 # Set log level\r
1989 self.SetLogLevel(Options)\r
1990\r
1991 if Options.FvFileList:\r
1992 self.FvFileList = Options.FvFileList\r
f7496d71 1993\r
52302d4d
LG
1994 if Options.MapFileList:\r
1995 self.MapFileList = Options.FvMapFileList\r
1996\r
1997 if Options.SourceFileList:\r
1998 self.SourceFileList = Options.SourceFileList\r
1999\r
2000 if Options.IncludeDirList:\r
2001 self.IncludeDirList = Options.IncludeDirList\r
2002\r
2003 if Options.DecFileList:\r
2004 self.DecFileList = Options.DecFileList\r
f7496d71 2005\r
52302d4d
LG
2006 if Options.GuidList:\r
2007 self.GuidList = Options.GuidList\r
2008\r
2009 if Options.LogFile:\r
2010 self.LogFile = Options.LogFile\r
2011\r
2012 if Options.keepdatabase:\r
2013 self.IsInit = False\r
2014\r
2015 ## SetLogLevel() method\r
2016 #\r
2017 # Set current log level of the tool based on args\r
2018 #\r
2019 # @param self: The object pointer\r
2020 # @param Option: The option list including log level setting\r
2021 #\r
2022 def SetLogLevel(self, Option):\r
4231a819 2023 if Option.verbose is not None:\r
52302d4d 2024 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
4231a819 2025 elif Option.quiet is not None:\r
52302d4d 2026 EdkLogger.SetLevel(EdkLogger.QUIET)\r
4231a819 2027 elif Option.debug is not None:\r
52302d4d
LG
2028 EdkLogger.SetLevel(Option.debug + 1)\r
2029 else:\r
2030 EdkLogger.SetLevel(EdkLogger.INFO)\r
2031\r
2032 ## EotOptionParser() method\r
2033 #\r
2034 # Using standard Python module optparse to parse command line option of this tool.\r
2035 #\r
2036 # @param self: The object pointer\r
2037 #\r
2038 # @retval Opt A optparse.Values object containing the parsed options\r
2039 # @retval Args Target of build command\r
2040 #\r
2041 def EotOptionParser(self):\r
2042 Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Eot.exe", usage = "%prog [options]")\r
2043 Parser.add_option("-m", "--makefile filename", action="store", type="string", dest='MakeFile',\r
2044 help="Specify a makefile for the platform.")\r
2045 Parser.add_option("-c", "--dsc filename", action="store", type="string", dest="DscFile",\r
2046 help="Specify a dsc file for the platform.")\r
2047 Parser.add_option("-f", "--fv filename", action="store", type="string", dest="FvFileList",\r
2048 help="Specify fv file list, quoted by \"\".")\r
2049 Parser.add_option("-a", "--map filename", action="store", type="string", dest="MapFileList",\r
2050 help="Specify map file list, quoted by \"\".")\r
2051 Parser.add_option("-s", "--source files", action="store", type="string", dest="SourceFileList",\r
2052 help="Specify source file list by a file")\r
2053 Parser.add_option("-i", "--include dirs", action="store", type="string", dest="IncludeDirList",\r
2054 help="Specify include dir list by a file")\r
2055 Parser.add_option("-e", "--dec files", action="store", type="string", dest="DecFileList",\r
2056 help="Specify dec file list by a file")\r
2057 Parser.add_option("-g", "--guid list", action="store", type="string", dest="GuidList",\r
2058 help="Specify guid file list by a file")\r
2059 Parser.add_option("-l", "--log filename", action="store", type="string", dest="LogFile",\r
2060 help="Specify real execution log file")\r
2061\r
2062 Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Eot database will not be cleaned except report information if this option is specified.")\r
2063\r
2064 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
2065 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r
2066 "including library instances selected, final dependency expression, "\\r
2067 "and warning messages, etc.")\r
2068 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
2069\r
2070 (Opt, Args)=Parser.parse_args()\r
2071\r
2072 return (Opt, Args)\r
2073\r
2074##\r
2075#\r
2076# This acts like the main() function for the script, unless it is 'import'ed into another\r
2077# script.\r
2078#\r
2079if __name__ == '__main__':\r
2080 # Initialize log system\r
2081 EdkLogger.Initialize()\r
2082 EdkLogger.IsRaiseError = False\r
2083 EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
2084\r
2085 StartTime = time.clock()\r
2086 Eot = Eot()\r
2087 FinishTime = time.clock()\r
2088\r
2089 BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))\r
2090 EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))\r