]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FfsInfStatement.py
License header updated to match correct format.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
index 3d16398c32ce4e5e9422b71ca43723c9dbbe4da1..cc85a32796d2e2b4e0200ada753bcf4dbfa47d83 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # process FFS generation from INF statement\r
 #\r
-#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<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
@@ -16,8 +16,7 @@
 # Import Modules\r
 #\r
 import Rule\r
-import os\r
-import shutil\r
+import Common.LongFilePathOs as os\r
 import StringIO\r
 from struct import *\r
 from GenFdsGlobalVariable import GenFdsGlobalVariable\r
@@ -31,6 +30,7 @@ from CommonDataClass.FdfClass import FfsInfStatementClassObject
 from Common.String import *\r
 from Common.Misc import PathClass\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
+from Common.Misc import ProcessDuplicatedInf\r
 from Common import EdkLogger\r
 from Common.BuildToolError import *\r
 from GuidSection import GuidSection\r
@@ -38,11 +38,15 @@ from FvImageSection import FvImageSection
 from Common.Misc import PeImageClass\r
 from AutoGen.GenDepex import DependencyExpression\r
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
+from Common.LongFilePathSupport import CopyLongFilePath\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
 \r
 ## generate FFS from INF\r
 #\r
 #\r
 class FfsInfStatement(FfsInfStatementClassObject):\r
+    ## The mapping dictionary from datum type to its maximum number.\r
+    _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}\r
     ## The constructor\r
     #\r
     #   @param  self        The object pointer\r
@@ -61,6 +65,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.CurrentLineContent = None\r
         self.FileName = None\r
         self.InfFileName = None\r
+        self.OverrideGuid = None\r
+        self.PatchedBinFile = ''\r
 \r
     ## GetFinalTargetSuffixMap() method\r
     #\r
@@ -142,7 +148,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
         GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
 \r
         self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
-        if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
+        if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':\r
+            pass\r
+        elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
             self.InfFileName = self.InfFileName[1:]\r
 \r
         if self.InfFileName.find('$') == -1:\r
@@ -161,7 +169,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
         ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
         if ErrorCode != 0:\r
             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
-        \r
+\r
+        if self.OverrideGuid:\r
+            PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
         if self.CurrentArch != None:\r
 \r
             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
@@ -196,6 +206,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
                                 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
                                 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
 \r
+        if self.OverrideGuid:\r
+            self.ModuleGuid = self.OverrideGuid\r
+\r
         if len(self.SourceFileList) != 0 and not self.InDsc:\r
             EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
 \r
@@ -204,10 +217,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \r
         if Inf._Defs != None and len(Inf._Defs) > 0:\r
             self.OptRomDefs.update(Inf._Defs)\r
+\r
         self.PatchPcds = []\r
         InfPcds = Inf.Pcds\r
         Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
         FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
+\r
+        # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
+        # But INF file path in FDF and DSC file may have real case characters.\r
+        # Try to convert the path to lower case to see if PCDs value are override by DSC.\r
         DscModules = {}\r
         for DscModule in Platform.Modules:\r
             DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]\r
@@ -217,6 +235,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 continue\r
             if Pcd.Type != 'PatchableInModule':\r
                 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
@@ -227,16 +246,22 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if PatchPcd and Pcd.Type == PatchPcd.Type:\r
                 DefaultValue = PatchPcd.DefaultValue\r
                 DscOverride = True\r
+\r
+            # Override Patchable PCD value by the value from FDF\r
             FdfOverride = False\r
             if PcdKey in FdfPcdDict:\r
                 DefaultValue = FdfPcdDict[PcdKey]\r
                 FdfOverride = True\r
+\r
             if not DscOverride and not FdfOverride:\r
                 continue\r
+            # Check value, if value are equal, no need to patch\r
             if Pcd.DatumType == "VOID*":\r
                 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
                     continue\r
+                # Get the string size from FDF or DSC\r
                 if DefaultValue[0] == 'L':\r
+                    # Remove L"", but the '\0' must be appended\r
                     MaxDatumSize = str((len(DefaultValue) - 2) * 2)\r
                 elif DefaultValue[0] == '{':\r
                     MaxDatumSize = str(len(DefaultValue.split(',')))\r
@@ -244,6 +269,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     MaxDatumSize = str(len(DefaultValue) - 1)\r
                 if DscOverride:\r
                     Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
+                # If no defined the maximum size in DSC, try to get current size from INF\r
                 if Pcd.MaxDatumSize in ['', None]:\r
                     Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))\r
             else:\r
@@ -259,6 +285,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
                         continue\r
                 except:\r
                     continue\r
+            # Check the Pcd size and data type\r
             if Pcd.DatumType == "VOID*":\r
                 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
@@ -268,8 +295,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
                                     % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
-            Pcd.DefaultValue = DefaultValue\r
-            self.PatchPcds.append(Pcd)\r
+            self.PatchPcds.append((Pcd, DefaultValue))\r
+\r
         self.InfModule = Inf\r
         self.PcdIsDriver = Inf.PcdIsDriver\r
         self.IsBinaryModule = Inf.IsBinaryModule\r
@@ -291,7 +318,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
 \r
-## PatchEfiFile\r
+    ## PatchEfiFile\r
     #\r
     #  Patch EFI file with patch PCD\r
     #\r
@@ -299,18 +326,25 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #  @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name\r
     #           If passed in file does not end with efi, return as is\r
     #\r
-    def PatchEfiFile(self, EfiFile):\r
-        if os.path.splitext(EfiFile)[1].lower() != '.efi':\r
-            return EfiFile\r
+    def PatchEfiFile(self, EfiFile, FileType):\r
         if not self.PatchPcds:\r
             return EfiFile\r
+        if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":\r
+            return EfiFile\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
         CopyLongFilePath(EfiFile, Output)\r
-        for Pcd in self.PatchPcds:\r
-            RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Pcd.DefaultValue, Pcd.MaxDatumSize)\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
         return Output\r
     ## GenFfs() method\r
     #\r
@@ -332,7 +366,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\r
         # Allow binary type module not specify override rule in FDF file.\r
         # \r
-        if len(self.BinFileList) >0 and not self.InDsc:\r
+        if len(self.BinFileList) > 0:\r
             if self.Rule == None or self.Rule == "":\r
                 self.Rule = "BINARY"\r
                 \r
@@ -551,6 +585,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
         (ModulePath, FileName) = os.path.split(self.InfFileName)\r
         Index = FileName.rfind('.')\r
         FileName = FileName[0:Index]\r
+        if self.OverrideGuid:\r
+            FileName = self.OverrideGuid\r
         Arch = "NoneArch"\r
         if self.CurrentArch != None:\r
             Arch = self.CurrentArch\r
@@ -632,8 +668,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 if not NoStrip:\r
                     FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
                     if not os.path.exists(FileBeforeStrip) or \\r
-                        (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
-                        shutil.copyfile(File, FileBeforeStrip)\r
+                           (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
+                        CopyLongFilePath(File, FileBeforeStrip)\r
                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
                                             StrippedFile,\r
@@ -671,8 +707,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if not NoStrip:\r
                 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
                 if not os.path.exists(FileBeforeStrip) or \\r
-                    (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
-                    shutil.copyfile(GenSecInputFile, FileBeforeStrip)\r
+                       (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
+                    CopyLongFilePath(GenSecInputFile, FileBeforeStrip)\r
+\r
                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
                                         StrippedFile,\r