]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FfsInfStatement.py
Sync BaseTool trunk (version r2610) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
index 71acd2992ca03d8ce8cd8efef9a089ec8db62628..3d16398c32ce4e5e9422b71ca43723c9dbbe4da1 100644 (file)
@@ -37,6 +37,7 @@ from GuidSection import GuidSection
 from FvImageSection import FvImageSection\r
 from Common.Misc import PeImageClass\r
 from AutoGen.GenDepex import DependencyExpression\r
+from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
 \r
 ## generate FFS from INF\r
 #\r
@@ -203,14 +204,80 @@ 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
+        DscModules = {}\r
+        for DscModule in Platform.Modules:\r
+            DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]\r
+        for PcdKey in InfPcds:\r
+            Pcd = InfPcds[PcdKey]\r
+            if not hasattr(Pcd, 'Offset'):\r
+                continue\r
+            if Pcd.Type != 'PatchableInModule':\r
+                continue\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
+                PatchPcd = Platform.Pcds[PcdKey]\r
+            DscOverride = False\r
+            if PatchPcd and Pcd.Type == PatchPcd.Type:\r
+                DefaultValue = PatchPcd.DefaultValue\r
+                DscOverride = True\r
+            FdfOverride = False\r
+            if PcdKey in FdfPcdDict:\r
+                DefaultValue = FdfPcdDict[PcdKey]\r
+                FdfOverride = True\r
+            if not DscOverride and not FdfOverride:\r
+                continue\r
+            if Pcd.DatumType == "VOID*":\r
+                if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
+                    continue\r
+                if DefaultValue[0] == 'L':\r
+                    MaxDatumSize = str((len(DefaultValue) - 2) * 2)\r
+                elif DefaultValue[0] == '{':\r
+                    MaxDatumSize = str(len(DefaultValue.split(',')))\r
+                else:\r
+                    MaxDatumSize = str(len(DefaultValue) - 1)\r
+                if DscOverride:\r
+                    Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
+                if Pcd.MaxDatumSize in ['', None]:\r
+                    Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))\r
+            else:\r
+                Base1 = Base2 = 10\r
+                if Pcd.DefaultValue.upper().startswith('0X'):\r
+                    Base1 = 16\r
+                if DefaultValue.upper().startswith('0X'):\r
+                    Base2 = 16\r
+                try:\r
+                    PcdValueInImg = int(Pcd.DefaultValue, Base1)\r
+                    PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
+                    if PcdValueInImg == PcdValueInDscOrFdf:\r
+                        continue\r
+                except:\r
+                    continue\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
+                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
+            else:\r
+                if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \\r
+                    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.InfModule = Inf\r
-            \r
-        GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)\r
-        GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)\r
-        GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)\r
-        GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)\r
-        GenFdsGlobalVariable.VerboseLogger("InfFileName :%s"  %self.InfFileName)\r
+        self.PcdIsDriver = Inf.PcdIsDriver\r
+        self.IsBinaryModule = Inf.IsBinaryModule\r
+        GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)\r
+        GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)\r
+        GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)\r
+        GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)\r
+        GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)\r
 \r
         #\r
         # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\\r
@@ -224,6 +291,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
 \r
+## PatchEfiFile\r
+    #\r
+    #  Patch EFI file with patch PCD\r
+    #\r
+    #  @param EfiFile: EFI file needs to be patched.\r
+    #  @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
+        if not self.PatchPcds:\r
+            return EfiFile\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
+            if RetVal:\r
+                EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
+        return Output\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
@@ -668,6 +756,30 @@ class FfsInfStatement(FfsInfStatementClassObject):
         SectAlignments = []\r
         Index = 1\r
         HasGneratedFlag = False\r
+        if self.PcdIsDriver == 'PEI_PCD_DRIVER':\r
+            if self.IsBinaryModule:\r
+                PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")\r
+            else:\r
+                PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")\r
+            PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")\r
+            GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
+                                                 [PcdExDbFileName],\r
+                                                 "EFI_SECTION_RAW",\r
+                                                 )\r
+            SectFiles.append(PcdExDbSecName)\r
+            SectAlignments.append(None)\r
+        elif self.PcdIsDriver == 'DXE_PCD_DRIVER':\r
+            if self.IsBinaryModule:\r
+                PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")\r
+            else:\r
+                PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")\r
+            PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")\r
+            GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
+                                                 [PcdExDbFileName],\r
+                                                 "EFI_SECTION_RAW",\r
+                                                 )\r
+            SectFiles.append(PcdExDbSecName)\r
+            SectAlignments.append(None)\r
         for Sect in Rule.SectionList:\r
             SecIndex = '%d' %Index\r
             SectList  = []\r