]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools/GenFds: register MM Modules and MM FV file types.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
index 29dc75f433f4ef51615ed32c4e02f91d06391819..c61c227c99000df9926db44ada82b2c2e401e76c 100644 (file)
@@ -1,8 +1,8 @@
 ## @file\r
 # process FFS generation from INF statement\r
 #\r
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
-#  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -28,6 +28,7 @@ import Section
 import RuleSimpleFile\r
 import RuleComplexFile\r
 from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Common.String import *\r
 from Common.Misc import PathClass\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
@@ -42,6 +43,7 @@ from AutoGen.GenDepex import DependencyExpression
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
 from Common.LongFilePathSupport import CopyLongFilePath\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
+import Common.GlobalData as GlobalData\r
 \r
 ## generate FFS from INF\r
 #\r
@@ -173,6 +175,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
         if ErrorCode != 0:\r
             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
 \r
+        #\r
+        # Cache lower case version of INF path before processing FILE_GUID override\r
+        #\r
+        InfLowerPath = str(PathClassObj).lower()\r
         if self.OverrideGuid:\r
             PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
         if self.CurrentArch != None:\r
@@ -218,6 +224,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
         if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
             EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName)      \r
 \r
+        if self.ModuleType == 'MM_CORE_STANDALONE' and int(self.PiSpecVersion, 16) < 0x00010032:\r
+            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.InfFileName)\r
+\r
         if Inf._Defs != None and len(Inf._Defs) > 0:\r
             self.OptRomDefs.update(Inf._Defs)\r
 \r
@@ -240,7 +249,6 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 continue\r
             # Override Patchable PCD value by the value from DSC\r
             PatchPcd = None\r
-            InfLowerPath = str(PathClassObj).lower()\r
             if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
                 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
             elif PcdKey in Platform.Pcds:\r
@@ -256,7 +264,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 DefaultValue = FdfPcdDict[PcdKey]\r
                 FdfOverride = True\r
 \r
-            if not DscOverride and not FdfOverride:\r
+            # Override Patchable PCD value by the value from Build Option\r
+            BuildOptionOverride = False\r
+            if GlobalData.BuildOptionPcd:\r
+                for pcd in GlobalData.BuildOptionPcd:\r
+                    if PcdKey == (pcd[1], pcd[0]):\r
+                        DefaultValue = pcd[2]\r
+                        BuildOptionOverride = True\r
+                        break\r
+\r
+            if not DscOverride and not FdfOverride and not BuildOptionOverride:\r
                 continue\r
             # Check value, if value are equal, no need to patch\r
             if Pcd.DatumType == "VOID*":\r
@@ -330,25 +347,63 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #           If passed in file does not end with efi, return as is\r
     #\r
     def PatchEfiFile(self, EfiFile, FileType):\r
+        #\r
+        # If the module does not have any patches, then return path to input file\r
+        #  \r
         if not self.PatchPcds:\r
             return EfiFile\r
+\r
+        #\r
+        # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED\r
+        #  \r
         if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":\r
             return EfiFile\r
+\r
+        #\r
+        # Generate path to patched output file\r
+        #\r
+        Basename = os.path.basename(EfiFile)\r
+        Output = os.path.normpath (os.path.join(self.OutputPath, Basename))\r
+\r
+        #\r
+        # If this file has already been patched, then return the path to the patched file\r
+        #\r
+        if self.PatchedBinFile == Output:\r
+          return Output\r
+\r
+        #\r
+        # If a different file from the same module has already been patched, then generate an error\r
+        #  \r
         if self.PatchedBinFile:\r
             EdkLogger.error("GenFds", GENFDS_ERROR,\r
                             'Only one binary file can be patched:\n'\r
                             '  a binary file has been patched: %s\n'\r
                             '  current file: %s' % (self.PatchedBinFile, EfiFile),\r
                             File=self.InfFileName)\r
-        Basename = os.path.basename(EfiFile)\r
-        Output = os.path.join(self.OutputPath, Basename)\r
+\r
+        #\r
+        # Copy unpatched file contents to output file location to perform patching\r
+        #  \r
         CopyLongFilePath(EfiFile, Output)\r
+\r
+        #\r
+        # Apply patches to patched output file\r
+        #  \r
         for Pcd, Value in self.PatchPcds:\r
             RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)\r
             if RetVal:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
-        self.PatchedBinFile = os.path.normpath(EfiFile)\r
+\r
+        #\r
+        # Save the path of the patched output file\r
+        #  \r
+        self.PatchedBinFile = Output\r
+\r
+        #\r
+        # Return path to patched output file\r
+        #  \r
         return Output\r
+\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
@@ -365,7 +420,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\r
 \r
         self.__InfParse__(Dict)\r
-        SrcFile = os.path.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\r
+        SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\r
         DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
         \r
         SrcFileDir = "."\r
@@ -511,37 +566,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #\r
     def __GetPlatformArchList__(self):\r
 \r
-        InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
+        InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
         DscArchList = []\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if  PlatformDataBase != None:\r
-            if InfFileKey in PlatformDataBase.Modules:\r
-                DscArchList.append ('IA32')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if  PlatformDataBase != None:\r
-            if InfFileKey in PlatformDataBase.Modules:\r
-                DscArchList.append ('X64')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('IPF')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('ARM')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('EBC')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'AARCH64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('AARCH64')\r
+        for Arch in GenFdsGlobalVariable.ArchList :\r
+            PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+            if  PlatformDataBase != None:\r
+                if InfFileKey in PlatformDataBase.Modules:\r
+                    DscArchList.append (Arch)\r
+                else:\r
+                    #\r
+                    # BaseTools support build same module more than once, the module path with FILE_GUID overridden has\r
+                    # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,\r
+                    # but the path (self.MetaFile.Path) is the real path\r
+                    #\r
+                    for key in PlatformDataBase.Modules.keys():\r
+                        if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path):\r
+                            DscArchList.append (Arch)\r
+                            break\r
 \r
         return DscArchList\r
 \r
@@ -878,7 +919,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             \r
             if not HasGneratedFlag:\r
                 UniVfrOffsetFileSection = ""    \r
-                ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
+                ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
                 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]\r
                 #\r
                 # Search the source list in InfData to find if there are .vfr file exist.\r
@@ -903,22 +944,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     #\r
                     # Generate the Raw data of raw section\r
                     #\r
-                    os.path.join( self.OutputPath, self.BaseName + '.offset')\r
-                    UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')\r
-                    UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
-                    \r
-                    self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
-                    \r
-                    UniVfrOffsetFileNameList = []\r
-                    UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
-                    """Call GenSection"""\r
-                    GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
-                                                         UniVfrOffsetFileNameList,\r
-                                                         "EFI_SECTION_RAW"\r
-                                                         )\r
-                    os.remove(UniVfrOffsetFileName)         \r
-                    SectList.append(UniVfrOffsetFileSection)\r
-                    HasGneratedFlag = True\r
+                    if VfrUniOffsetList:\r
+                        os.path.join( self.OutputPath, self.BaseName + '.offset')\r
+                        UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')\r
+                        UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
+\r
+                        self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
+\r
+                        UniVfrOffsetFileNameList = []\r
+                        UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
+                        """Call GenSection"""\r
+                        GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
+                                                             UniVfrOffsetFileNameList,\r
+                                                             "EFI_SECTION_RAW"\r
+                                                             )\r
+                        os.remove(UniVfrOffsetFileName)\r
+                        SectList.append(UniVfrOffsetFileSection)\r
+                        HasGneratedFlag = True\r
                 \r
             for SecName in  SectList :\r
                 SectFiles.append(SecName)\r