import uuid\r
import copy\r
import codecs\r
+from GenFds.AprioriSection import DXE_APRIORI_GUID, PEI_APRIORI_GUID\r
\r
gGuidStringFormat = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"\r
-gPeiAprioriFileNameGuid = '1b45cc0a-156a-428a-af62-49864da0e6e6'\r
-gAprioriGuid = 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'\r
gIndention = -4\r
\r
class Image(array):\r
if Ffs.Type == 0x05:\r
FfsDxeCoreGuid = FfsID\r
continue\r
- if Ffs.Guid.lower() == gPeiAprioriFileNameGuid:\r
+ if Ffs.Guid.lower() == PEI_APRIORI_GUID.lower():\r
FfsPeiPrioriGuid = FfsID\r
continue\r
- if Ffs.Guid.lower() == gAprioriGuid:\r
+ if Ffs.Guid.lower() == DXE_APRIORI_GUID.lower():\r
FfsDxePrioriGuid = FfsID\r
continue\r
\r
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