State = property(_GetState, _SetState)\r
\r
\r
- _FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"\r
-\r
- _GUID_ = struct.Struct("16x 1I2H8B")\r
- _LENGTH_ = struct.Struct("16x 16x 1Q")\r
- _SIG_ = struct.Struct("16x 16x 8x 1I")\r
- _ATTR_ = struct.Struct("16x 16x 8x 4x 1I")\r
- _HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")\r
- _CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")\r
-\r
- def __init__(self, Name=''):\r
- Image.__init__(self)\r
- self.Name = Name\r
- self.FfsDict = sdict()\r
- self.OrderedFfsDict = sdict()\r
- self.UnDispatchedFfsDict = sdict()\r
- self.ProtocolList = sdict()\r
-\r
- def CheckArchProtocol(self):\r
- for Item in EotGlobalData.gArchProtocolGuids:\r
- if Item.lower() not in EotGlobalData.gProtocolList:\r
- return False\r
- return True\r
-\r
- def ParseDepex(self, Depex, Type):\r
- List = None\r
- if Type == 'Ppi':\r
- List = EotGlobalData.gPpiList\r
- if Type == 'Protocol':\r
- List = EotGlobalData.gProtocolList\r
- DepexStack = []\r
- DepexList = []\r
- DepexString = ''\r
- FileDepex = None\r
- CouldBeLoaded = True\r
- for Index in range(0, len(Depex.Expression)):\r
- Item = Depex.Expression[Index]\r
- if Item == 0x00:\r
- Index = Index + 1\r
- Guid = gGuidStringFormat % Depex.Expression[Index]\r
- if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
- return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE'])\r
- elif Item == 0x01:\r
- Index = Index + 1\r
- Guid = gGuidStringFormat % Depex.Expression[Index]\r
- if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
- return (True, 'AFTER %s' % Guid, [Guid, 'AFTER'])\r
- elif Item == 0x02:\r
- Index = Index + 1\r
- Guid = gGuidStringFormat % Depex.Expression[Index]\r
- if Guid.lower() in List:\r
- DepexStack.append(True)\r
- DepexList.append(Guid)\r
- else:\r
- DepexStack.append(False)\r
- DepexList.append(Guid)\r
- continue\r
- elif Item == 0x03 or Item == 0x04:\r
- DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
- DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCODE_STRING_[Item].upper() + ' ' + str(DepexList.pop()))\r
- elif Item == 0x05:\r
- DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
- DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexList.pop()))\r
- elif Item == 0x06:\r
- DepexStack.append(True)\r
- DepexList.append('TRUE')\r
- DepexString = DepexString + 'TRUE' + ' '\r
- elif Item == 0x07:\r
- DepexStack.append(False)\r
- DepexList.append('False')\r
- DepexString = DepexString + 'FALSE' + ' '\r
- elif Item == 0x08:\r
- if Index != len(Depex.Expression) - 1:\r
- CouldBeLoaded = False\r
- else:\r
- CouldBeLoaded = DepexStack.pop()\r
- else:\r
- CouldBeLoaded = False\r
- if DepexList != []:\r
- DepexString = DepexList[0].strip()\r
- return (CouldBeLoaded, DepexString, FileDepex)\r
-\r
- def Dispatch(self, Db = None):\r
- if Db is None:\r
- return False\r
- self.UnDispatchedFfsDict = copy.copy(self.FfsDict)\r
- # Find PeiCore, DexCore, PeiPriori, DxePriori first\r
- FfsSecCoreGuid = None\r
- FfsPeiCoreGuid = None\r
- FfsDxeCoreGuid = None\r
- FfsPeiPrioriGuid = None\r
- FfsDxePrioriGuid = None\r
- for FfsID in self.UnDispatchedFfsDict:\r
- Ffs = self.UnDispatchedFfsDict[FfsID]\r
- if Ffs.Type == 0x03:\r
- FfsSecCoreGuid = FfsID\r
- continue\r
- if Ffs.Type == 0x04:\r
- FfsPeiCoreGuid = FfsID\r
- continue\r
- if Ffs.Type == 0x05:\r
- FfsDxeCoreGuid = FfsID\r
- continue\r
- if Ffs.Guid.lower() == PEI_APRIORI_GUID.lower():\r
- FfsPeiPrioriGuid = FfsID\r
- continue\r
- if Ffs.Guid.lower() == DXE_APRIORI_GUID.lower():\r
- FfsDxePrioriGuid = FfsID\r
- continue\r
-\r
- # Parse SEC_CORE first\r
- if FfsSecCoreGuid is not None:\r
- self.OrderedFfsDict[FfsSecCoreGuid] = self.UnDispatchedFfsDict.pop(FfsSecCoreGuid)\r
- self.LoadPpi(Db, FfsSecCoreGuid)\r
-\r
- # Parse PEI first\r
- if FfsPeiCoreGuid is not None:\r
- self.OrderedFfsDict[FfsPeiCoreGuid] = self.UnDispatchedFfsDict.pop(FfsPeiCoreGuid)\r
- self.LoadPpi(Db, FfsPeiCoreGuid)\r
- if FfsPeiPrioriGuid is not None:\r
- # Load PEIM described in priori file\r
- FfsPeiPriori = self.UnDispatchedFfsDict.pop(FfsPeiPrioriGuid)\r
- if len(FfsPeiPriori.Sections) == 1:\r
- Section = FfsPeiPriori.Sections.popitem()[1]\r
- if Section.Type == 0x19:\r
- GuidStruct = struct.Struct('1I2H8B')\r
- Start = 4\r
- while len(Section) > Start:\r
- Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
- GuidString = gGuidStringFormat % Guid\r
- Start = Start + 16\r
- if GuidString in self.UnDispatchedFfsDict:\r
- self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
- self.LoadPpi(Db, GuidString)\r
-\r
- self.DisPatchPei(Db)\r
-\r
- # Parse DXE then\r
- if FfsDxeCoreGuid is not None:\r
- self.OrderedFfsDict[FfsDxeCoreGuid] = self.UnDispatchedFfsDict.pop(FfsDxeCoreGuid)\r
- self.LoadProtocol(Db, FfsDxeCoreGuid)\r
- if FfsDxePrioriGuid is not None:\r
- # Load PEIM described in priori file\r
- FfsDxePriori = self.UnDispatchedFfsDict.pop(FfsDxePrioriGuid)\r
- if len(FfsDxePriori.Sections) == 1:\r
- Section = FfsDxePriori.Sections.popitem()[1]\r
- if Section.Type == 0x19:\r
- GuidStruct = struct.Struct('1I2H8B')\r
- Start = 4\r
- while len(Section) > Start:\r
- Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
- GuidString = gGuidStringFormat % Guid\r
- Start = Start + 16\r
- if GuidString in self.UnDispatchedFfsDict:\r
- self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
- self.LoadProtocol(Db, GuidString)\r
-\r
- self.DisPatchDxe(Db)\r
-\r
- def LoadProtocol(self, Db, ModuleGuid):\r
- SqlCommand = """select GuidValue from Report\r
- where SourceFileFullPath in\r
- (select Value1 from Inf where BelongsToFile =\r
- (select BelongsToFile from Inf\r
- where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
- and Model = %s)\r
- and ItemType = 'Protocol' and ItemMode = 'Produced'""" \\r
- % (ModuleGuid, 5001, 3007)\r
- RecordSet = Db.TblReport.Exec(SqlCommand)\r
- for Record in RecordSet:\r
- SqlCommand = """select Value2 from Inf where BelongsToFile =\r
- (select DISTINCT BelongsToFile from Inf\r
- where Value1 =\r
- (select SourceFileFullPath from Report\r
- where GuidValue like '%s' and ItemMode = 'Callback'))\r
- and Value1 = 'FILE_GUID'""" % Record[0]\r
- CallBackSet = Db.TblReport.Exec(SqlCommand)\r
- if CallBackSet != []:\r
- EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
- else:\r
- EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
-\r
- def LoadPpi(self, Db, ModuleGuid):\r
- SqlCommand = """select GuidValue from Report\r
- where SourceFileFullPath in\r
- (select Value1 from Inf where BelongsToFile =\r
- (select BelongsToFile from Inf\r
- where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
- and Model = %s)\r
- and ItemType = 'Ppi' and ItemMode = 'Produced'""" \\r
- % (ModuleGuid, 5001, 3007)\r
- RecordSet = Db.TblReport.Exec(SqlCommand)\r
- for Record in RecordSet:\r
- EotGlobalData.gPpiList[Record[0].lower()] = ModuleGuid\r
-\r
- def DisPatchDxe(self, Db):\r
- IsInstalled = False\r
- ScheduleList = sdict()\r
- for FfsID in self.UnDispatchedFfsDict:\r
- CouldBeLoaded = False\r
- DepexString = ''\r
- FileDepex = None\r
- Ffs = self.UnDispatchedFfsDict[FfsID]\r
- if Ffs.Type == 0x07:\r
- # Get Depex\r
- IsFoundDepex = False\r
- for Section in Ffs.Sections.values():\r
- # Find Depex\r
- if Section.Type == 0x13:\r
- IsFoundDepex = True\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Protocol')\r
- break\r
- if Section.Type == 0x01:\r
- CompressSections = Section._SubImages[4]\r
- for CompressSection in CompressSections.Sections:\r
- if CompressSection.Type == 0x13:\r
- IsFoundDepex = True\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Protocol')\r
- break\r
- if CompressSection.Type == 0x02:\r
- NewSections = CompressSection._SubImages[4]\r
- for NewSection in NewSections.Sections:\r
- if NewSection.Type == 0x13:\r
- IsFoundDepex = True\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Protocol')\r
- break\r
-\r
- # Not find Depex\r
- if not IsFoundDepex:\r
- CouldBeLoaded = self.CheckArchProtocol()\r
- DepexString = ''\r
- FileDepex = None\r
-\r
- # Append New Ffs\r
- if CouldBeLoaded:\r
- IsInstalled = True\r
- NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
- NewFfs.Depex = DepexString\r
- if FileDepex is not None:\r
- ScheduleList.insert(FileDepex[1], FfsID, NewFfs, FileDepex[0])\r
- else:\r
- ScheduleList[FfsID] = NewFfs\r
- else:\r
- self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
-\r
- for FfsID in ScheduleList:\r
- NewFfs = ScheduleList.pop(FfsID)\r
- FfsName = 'UnKnown'\r
- self.OrderedFfsDict[FfsID] = NewFfs\r
- self.LoadProtocol(Db, FfsID)\r
-\r
- SqlCommand = """select Value2 from Inf\r
- where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
- and Model = %s and Value1='BASE_NAME'""" % (FfsID, 5001, 5001)\r
- RecordSet = Db.TblReport.Exec(SqlCommand)\r
- if RecordSet != []:\r
- FfsName = RecordSet[0][0]\r
-\r
- if IsInstalled:\r
- self.DisPatchDxe(Db)\r
-\r
- def DisPatchPei(self, Db):\r
- IsInstalled = False\r
- for FfsID in self.UnDispatchedFfsDict:\r
- CouldBeLoaded = True\r
- DepexString = ''\r
- FileDepex = None\r
- Ffs = self.UnDispatchedFfsDict[FfsID]\r
- if Ffs.Type == 0x06 or Ffs.Type == 0x08:\r
- # Get Depex\r
- for Section in Ffs.Sections.values():\r
- if Section.Type == 0x1B:\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')\r
- break\r
- if Section.Type == 0x01:\r
- CompressSections = Section._SubImages[4]\r
- for CompressSection in CompressSections.Sections:\r
- if CompressSection.Type == 0x1B:\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Ppi')\r
- break\r
- if CompressSection.Type == 0x02:\r
- NewSections = CompressSection._SubImages[4]\r
- for NewSection in NewSections.Sections:\r
- if NewSection.Type == 0x1B:\r
- CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Ppi')\r
- break\r
-\r
- # Append New Ffs\r
- if CouldBeLoaded:\r
- IsInstalled = True\r
- NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
- NewFfs.Depex = DepexString\r
- self.OrderedFfsDict[FfsID] = NewFfs\r
- self.LoadPpi(Db, FfsID)\r
- else:\r
- self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
-\r
- if IsInstalled:\r
- self.DisPatchPei(Db)\r
-\r
-\r
- def __str__(self):\r
- global gIndention\r
- gIndention += 4\r
- FvInfo = '\n' + ' ' * gIndention\r
- FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)\r
- FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])\r
- gIndention -= 4\r
- return FvInfo + FfsInfo\r
-\r
- def _Unpack(self):\r
- Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]\r
- self.empty()\r
- self.extend(self._BUF_[self._OFF_:self._OFF_+Size])\r
-\r
- # traverse the FFS\r
- EndOfFv = Size\r
- FfsStartAddress = self.HeaderSize\r
- LastFfsObj = None\r
- while FfsStartAddress < EndOfFv:\r
- FfsObj = Ffs()\r
- FfsObj.frombuffer(self, FfsStartAddress)\r
- FfsId = repr(FfsObj)\r
- if ((self.Attributes & 0x00000800) != 0 and len(FfsObj) == 0xFFFFFF) \\r
- or ((self.Attributes & 0x00000800) == 0 and len(FfsObj) == 0):\r
- if LastFfsObj is not None:\r
- LastFfsObj.FreeSpace = EndOfFv - LastFfsObj._OFF_ - len(LastFfsObj)\r
- else:\r
- if FfsId in self.FfsDict:\r
- EdkLogger.error("FV", 0, "Duplicate GUID in FFS",\r
- ExtraData="\t%s @ %s\n\t%s @ %s" \\r
- % (FfsObj.Guid, FfsObj.Offset,\r
- self.FfsDict[FfsId].Guid, self.FfsDict[FfsId].Offset))\r
- self.FfsDict[FfsId] = FfsObj\r
- if LastFfsObj is not None:\r
- LastFfsObj.FreeSpace = FfsStartAddress - LastFfsObj._OFF_ - len(LastFfsObj)\r
-\r
- FfsStartAddress += len(FfsObj)\r
- #\r
- # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))\r
- # The next FFS must be at the latest next 8-byte aligned address\r
- #\r
- FfsStartAddress = (FfsStartAddress + 7) & (~7)\r
- LastFfsObj = FfsObj\r
-\r
- def _GetAttributes(self):\r
- return self.GetField(self._ATTR_, 0)[0]\r
-\r
- def _GetSize(self):\r
- return self.GetField(self._LENGTH_, 0)[0]\r
-\r
- def _GetChecksum(self):\r
- return self.GetField(self._CHECKSUM_, 0)[0]\r
-\r
- def _GetHeaderLength(self):\r
- return self.GetField(self._HLEN_, 0)[0]\r
-\r
- def _GetFileSystemGuid(self):\r
- return gGuidStringFormat % self.GetField(self._GUID_, 0)\r
-\r
- Attributes = property(_GetAttributes)\r
- Size = property(_GetSize)\r
- Checksum = property(_GetChecksum)\r
- HeaderSize = property(_GetHeaderLength)\r
- FileSystemGuid = property(_GetFileSystemGuid)\r
-\r
## MultipleFv() class\r
#\r
# A class for Multiple FV\r