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