1. Support EFI image with none zero base address.
authorlgao4 <lgao4@c2973edb-eda0-4c78-bc6a-9341b269661f>
Wed, 10 Feb 2010 11:59:18 +0000 (11:59 +0000)
committerlgao4 <lgao4@c2973edb-eda0-4c78-bc6a-9341b269661f>
Wed, 10 Feb 2010 11:59:18 +0000 (11:59 +0000)
2. Check whether the specified fixed top address is page alignment.
3. Make sure that IPF runtime EFI image at 2 page alignment address.

git-svn-id: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/trunk/BaseTools@1861 c2973edb-eda0-4c78-bc6a-9341b269661f

Source/Python/build/build.py

index 2db9dff..4385ed6 100644 (file)
@@ -653,18 +653,19 @@ class PeImageInfo():
     #\r
     # Constructor will load all required image information.\r
     #\r
-    #   @param  FileName          The full file path of image. \r
-    #   @param  Size              The required memory size of image.\r
-    #   @param  EntryPointOffset  The entry point offset to image base.\r
+    #   @param  BaseName          The full file path of image. \r
     #   @param  Guid              The GUID for image.\r
+    #   @param  Arch              Arch of this image.\r
     #   @param  OutpuDir          The output directory for image.\r
+    #   @param  ImageClass        PeImage Information\r
     #\r
-    def __init__(self, BaseName, Guid, OutpuDir, ImageClass):\r
+    def __init__(self, BaseName, Guid, Arch, OutpuDir, ImageClass):\r
         self.BaseName         = BaseName\r
         self.Guid             = Guid\r
+        self.Arch             = Arch\r
         self.OutpuDir         = OutpuDir\r
-        ImageClass.Size       = (ImageClass.Size / 0x1000 + 1) * 0x1000\r
         self.Image            = ImageClass\r
+        self.Image.Size       = (self.Image.Size / 0x1000 + 1) * 0x1000\r
 \r
 ## The class implementing the EDK2 build process\r
 #\r
@@ -876,7 +877,9 @@ class Build():
             except:
                 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (LoadFixAddressString))\r
             if self.LoadFixAddress < 0:\r
-                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to negative value %s" % (LoadFixAddressString))\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value %s" % (LoadFixAddressString))\r
+            if self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress % 0x1000 != 0:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value %s" % (LoadFixAddressString))\r
 \r
         if self.SkuId == None or self.SkuId == '':\r
             self.SkuId = self.Platform.SkuName\r
@@ -1007,14 +1010,44 @@ class Build():
                 #\r
                 LaunchCommand(["GenFw", "--address", str(BaseAddress), "-r", ModuleInfo.Image.FileName], ModuleInfo.OutpuDir)\r
             #\r
+            # Collect funtion address from Map file\r
+            #\r
+            ImageMapTable = ModuleInfo.Image.FileName.replace('.efi', '.map')\r
+            FunctionList = []\r
+            if os.path.exists(ImageMapTable):\r
+                OrigImageBaseAddress = 0\r
+                ImageMap = open (ImageMapTable, 'r')\r
+                for LinStr in ImageMap:\r
+                    if len (LinStr.strip()) == 0:\r
+                        continue\r
+                    #\r
+                    # Get the preferred address set on link time.\r
+                    #\r
+                    if LinStr.find ('Preferred load address is') != -1:\r
+                        StrList = LinStr.split()\r
+                        OrigImageBaseAddress = int (StrList[len(StrList) - 1], 16)\r
+\r
+                    StrList = LinStr.split()\r
+                    if len (StrList) > 4:\r
+                        if StrList[3] == 'f' or StrList[3] =='F':\r
+                            Name = StrList[1]\r
+                            RelativeAddress = int (StrList[2], 16) - OrigImageBaseAddress\r
+                            FunctionList.append ((Name, RelativeAddress))\r
+                            if ModuleInfo.Arch == 'IPF' and Name.endswith('_ModuleEntryPoint'):\r
+                                #\r
+                                # Get the real entry point address for IPF image.\r
+                                #\r
+                                ModuleInfo.Image.EntryPoint = RelativeAddress\r
+                ImageMap.close()\r
+            #\r
             # Add general information.\r
             #\r
             if ModeIsSmm:\r
-                MapBuffer.write('\n\n%s (Fix SMRAM Offset,   BaseAddress=0x%010X,  EntryPoint=0x%010X)\n' % (ModuleName, BaseAddress, BaseAddress + ModuleInfo.Image.EntryPoint))\r
+                MapBuffer.write('\n\n%s (Fixed SMRAM Offset,   BaseAddress=0x%010X,  EntryPoint=0x%010X)\n' % (ModuleName, BaseAddress, BaseAddress + ModuleInfo.Image.EntryPoint))\r
             elif AddrIsOffset:\r
-                MapBuffer.write('\n\n%s (Fix Memory Offset,  BaseAddress=-0x%010X, EntryPoint=-0x%010X)\n' % (ModuleName, 0 - BaseAddress, 0 - (BaseAddress + ModuleInfo.Image.EntryPoint)))\r
+                MapBuffer.write('\n\n%s (Fixed Memory Offset,  BaseAddress=-0x%010X, EntryPoint=-0x%010X)\n' % (ModuleName, 0 - BaseAddress, 0 - (BaseAddress + ModuleInfo.Image.EntryPoint)))\r
             else:\r
-                MapBuffer.write('\n\n%s (Fix Memory Address, BaseAddress=0x%010X,  EntryPoint=0x%010X)\n' % (ModuleName, BaseAddress, BaseAddress + ModuleInfo.Image.EntryPoint))\r
+                MapBuffer.write('\n\n%s (Fixed Memory Address, BaseAddress=0x%010X,  EntryPoint=0x%010X)\n' % (ModuleName, BaseAddress, BaseAddress + ModuleInfo.Image.EntryPoint))\r
             #\r
             # Add guid and general seciton section.\r
             #\r
@@ -1023,7 +1056,7 @@ class Build():
             for SectionHeader in ModuleInfo.Image.SectionHeaderList:\r
                 if SectionHeader[0] == '.text':\r
                     TextSectionAddress = SectionHeader[1]\r
-                elif SectionHeader[1] == '.data':\r
+                elif SectionHeader[0] in ['.data', '.sdata']:\r
                     DataSectionAddress = SectionHeader[1]\r
             if AddrIsOffset:\r
                 MapBuffer.write('(GUID=%s, .textbaseaddress=-0x%010X, .databaseaddress=-0x%010X)\n\n' % (ModuleInfo.Guid, 0 - (BaseAddress + TextSectionAddress), 0 - (BaseAddress + DataSectionAddress))) \r
@@ -1032,20 +1065,11 @@ class Build():
             #\r
             # Add funtion address\r
             #\r
-            ImageMapTable = ModuleInfo.Image.FileName.replace('.efi', '.map')\r
-            if not os.path.exists(ImageMapTable):\r
-                continue\r
-            ImageMap = open (ImageMapTable, 'r')\r
-            for LinStr in ImageMap:\r
-                if len (LinStr.strip()) == 0:\r
-                    continue\r
-                StrList = LinStr.split()\r
-                if len (StrList) > 4:\r
-                    if StrList[3] == 'f' or StrList[3] =='F':\r
-                        if AddrIsOffset:\r
-                            MapBuffer.write('  -0x%010X    %s\n' % (0 - (BaseAddress + int (StrList[2], 16)), StrList[1]))\r
-                        else:\r
-                            MapBuffer.write('  0x%010X    %s\n' % (BaseAddress + int (StrList[2], 16), StrList[1]))\r
+            for Function in FunctionList:\r
+                if AddrIsOffset:\r
+                    MapBuffer.write('  -0x%010X    %s\n' % (0 - (BaseAddress + Function[1]), Function[0]))\r
+                else:\r
+                    MapBuffer.write('  0x%010X    %s\n' % (BaseAddress + Function[1], Function[0]))\r
             ImageMap.close()\r
 \r
             #\r
@@ -1087,6 +1111,9 @@ class Build():
         RtSize  = 0\r
         # reserve 4K size in SMRAM to make SMM module address not from 0.\r
         SmmSize = 0x1000\r
+        IsIpfPlatform = False\r
+        if 'IPF' in self.ArchList:\r
+            IsIpfPlatform = True\r
         for Module in ModuleList:\r
             GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (Module.MetaFile, Module.Arch, Module.ToolChain, Module.BuildTarget)\r
             \r
@@ -1100,19 +1127,22 @@ class Build():
                     ImageClass = PeImageClass (OutputImageFile)\r
                     if not ImageClass.IsValid:\r
                         EdkLogger.error("build", FILE_PARSE_FAILURE, ExtraData=ImageClass.ErrorInfo)\r
-                    ImageInfo = PeImageInfo(Module.Name, Module.Guid, Module.OutputDir, ImageClass)\r
+                    ImageInfo = PeImageInfo(Module.Name, Module.Guid, Module.Arch, Module.OutputDir, ImageClass)\r
                     if Module.ModuleType in ['PEI_CORE', 'PEIM', 'COMBINED_PEIM_DRIVER','PIC_PEIM', 'RELOCATABLE_PEIM', 'DXE_CORE']:\r
                         PeiModuleList[Module.MetaFile] = ImageInfo\r
-                        PeiSize += ImageClass.Size\r
+                        PeiSize += ImageInfo.Image.Size\r
                     elif Module.ModuleType in ['BS_DRIVER', 'DXE_DRIVER', 'UEFI_DRIVER']:\r
                         BtModuleList[Module.MetaFile] = ImageInfo\r
-                        BtSize += ImageClass.Size\r
+                        BtSize += ImageInfo.Image.Size\r
                     elif Module.ModuleType in ['DXE_RUNTIME_DRIVER', 'RT_DRIVER', 'DXE_SAL_DRIVER', 'SAL_RT_DRIVER']:\r
                         RtModuleList[Module.MetaFile] = ImageInfo\r
-                        RtSize += ImageClass.Size\r
+                        #IPF runtime driver needs to be at 2 page alignment.\r
+                        if IsIpfPlatform and ImageInfo.Image.Size % 0x2000 != 0:\r
+                            ImageInfo.Image.Size = (ImageInfo.Image.Size / 0x2000 + 1) * 0x2000\r
+                        RtSize += ImageInfo.Image.Size\r
                     elif Module.ModuleType in ['SMM_CORE', 'DXE_SMM_DRIVER']:\r
                         SmmModuleList[Module.MetaFile] = ImageInfo\r
-                        SmmSize += ImageClass.Size\r
+                        SmmSize += ImageInfo.Image.Size\r
                         if Module.ModuleType == 'DXE_SMM_DRIVER':\r
                             PiSpecVersion = 0
                             if 'PI_SPECIFICATION_VERSION' in Module.Module.Specification:
@@ -1120,7 +1150,7 @@ class Build():
                             # for PI specification < PI1.1, DXE_SMM_DRIVER also runs as BOOT time driver.\r
                             if PiSpecVersion < 0x0001000A:\r
                                 BtModuleList[Module.MetaFile] = ImageInfo\r
-                                BtSize += ImageClass.Size\r
+                                BtSize += ImageInfo.Image.Size\r
                     break\r
             #\r
             # EFI image is final target.\r
@@ -1146,6 +1176,22 @@ class Build():
                 #\r
                 PatchEfiImageList.append (OutputImageFile)\r
         \r
+        #\r
+        # Get Top Memory address\r
+        #\r
+        ReservedRuntimeMemorySize = 0\r
+        TopMemoryAddress = 0\r
+        if self.LoadFixAddress == 0xFFFFFFFFFFFFFFFF:\r
+            TopMemoryAddress = 0\r
+        else:\r
+            TopMemoryAddress = self.LoadFixAddress\r
+            if TopMemoryAddress < RtSize + BtSize + PeiSize:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is too low to load driver")\r
+            # Make IPF runtime driver at 2 page alignment.\r
+            if IsIpfPlatform:\r
+                ReservedRuntimeMemorySize = TopMemoryAddress % 0x2000\r
+                RtSize = RtSize + ReservedRuntimeMemorySize\r
+\r
         #\r
         # Patch FixAddress related PCDs into EFI image\r
         #\r
@@ -1168,29 +1214,20 @@ class Build():
                     ReturnValue, ErrorInfo = PatchBinaryFile (EfiImage, PcdInfo[1], TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE_DATA_TYPE, str (BtSize/0x1000))\r
                 elif PcdInfo[0] == TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE:\r
                     ReturnValue, ErrorInfo = PatchBinaryFile (EfiImage, PcdInfo[1], TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE_DATA_TYPE, str (RtSize/0x1000))\r
-                elif PcdInfo[0] == TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE:\r
+                elif PcdInfo[0] == TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE and len (SmmModuleList) > 0:\r
                     ReturnValue, ErrorInfo = PatchBinaryFile (EfiImage, PcdInfo[1], TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE_DATA_TYPE, str (SmmSize/0x1000))\r
                 if ReturnValue != 0:\r
                     EdkLogger.error("build", PARAMETER_INVALID, "Patch PCD value failed", ExtraData=ErrorInfo)\r
-        #\r
-        # Get Top Memory address\r
-        #\r
-        TopMemoryAddress = 0\r
-        if self.LoadFixAddress == 0xFFFFFFFFFFFFFFFF:\r
-            TopMemoryAddress = 0\r
-        else:\r
-            TopMemoryAddress = self.LoadFixAddress\r
-            if TopMemoryAddress < RtSize + BtSize + PeiSize:\r
-                EdkLogger.error("build", PARAMETER_INVALID, "TopMemoryAddress is too low to load driver")\r
         \r
         MapBuffer.write('PEI_CODE_PAGE_NUMBER      = 0x%x\n' % (PeiSize/0x1000))\r
         MapBuffer.write('BOOT_CODE_PAGE_NUMBER     = 0x%x\n' % (BtSize/0x1000))\r
         MapBuffer.write('RUNTIME_CODE_PAGE_NUMBER  = 0x%x\n' % (RtSize/0x1000))\r
-        MapBuffer.write('SMM_CODE_PAGE_NUMBER      = 0x%x\n' % (SmmSize/0x1000))\r
+        if len (SmmModuleList) > 0:\r
+            MapBuffer.write('SMM_CODE_PAGE_NUMBER      = 0x%x\n' % (SmmSize/0x1000))\r
         \r
         PeiBaseAddr = TopMemoryAddress - RtSize - BtSize\r
         BtBaseAddr  = TopMemoryAddress - RtSize\r
-        RtBaseAddr  = TopMemoryAddress\r
+        RtBaseAddr  = TopMemoryAddress - ReservedRuntimeMemorySize\r
 \r
         self._RebaseModule (MapBuffer, PeiBaseAddr, PeiModuleList, TopMemoryAddress == 0)\r
         self._RebaseModule (MapBuffer, BtBaseAddr, BtModuleList, TopMemoryAddress == 0)\r
@@ -1245,7 +1282,7 @@ class Build():
                         # Check whether the set fix address is above 4G for 32bit image.\r
                         #\r
                         if (Arch == 'IA32' or Arch == 'ARM') and self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress >= 0x100000000:\r
-                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than 4G for the platorm with IA32 arch modules")\r
+                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platorm with IA32 or ARM arch modules")\r
                     #\r
                     # Get Module List\r
                     #\r
@@ -1405,7 +1442,7 @@ class Build():
                         # Check whether the set fix address is above 4G for 32bit image.\r
                         #\r
                         if (Arch == 'IA32' or Arch == 'ARM') and self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress >= 0x100000000:\r
-                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than 4G for the platorm with IA32 arch modules")\r
+                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platorm with IA32 or ARM arch modules")\r
                     #\r
                     # Get Module List\r
                     #\r