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