]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFfs/GenFfs.c
License header updated to match correct format.
[mirror_edk2.git] / BaseTools / Source / C / GenFfs / GenFfs.c
index e8cd09e947600a8a7c08b0246e7f1ad5267df1e5..52092e36e74e36520a7cb792388798159a6d3712 100644 (file)
@@ -1,7 +1,8 @@
-/**\r
+/** @file\r
+This file contains functions required to generate a Firmware File System file.\r
 \r
-Copyright (c) 2004-2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
 http://opensource.org/licenses/bsd-license.php                                            \r
@@ -9,15 +10,6 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
 \r
-Module Name:\r
-\r
-  GenFfs.c\r
-\r
-Abstract:\r
-\r
-  This file contains functions required to generate a Firmware File System\r
-  file.\r
-\r
 **/\r
 \r
 #include <stdio.h>\r
@@ -87,7 +79,7 @@ Returns:
   \r
 --*/ \r
 {\r
-  fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
 \r
 STATIC\r
@@ -119,7 +111,7 @@ Returns:
   //\r
   // Copyright declaration\r
   // \r
-  fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
+  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -134,6 +126,8 @@ Returns:
                         EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\n\\r
                         EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n\\r
                         EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n\\r
+                        EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n\\r
+                        EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n\\r
                         EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n");\r
   fprintf (stdout, "  -g FileGuid, --fileguid FileGuid\n\\r
                         FileGuid is one module guid.\n\\r
@@ -282,9 +276,12 @@ Returns:
   UINT32                     Index;\r
   FILE                       *InFile;\r
   EFI_COMMON_SECTION_HEADER  *SectHeader;\r
-  EFI_COMMON_SECTION_HEADER  TempSectHeader;\r
+  EFI_COMMON_SECTION_HEADER2 TempSectHeader;\r
   EFI_TE_IMAGE_HEADER        TeHeader;\r
   UINT32                     TeOffset;\r
+  EFI_GUID_DEFINED_SECTION   GuidSectHeader;\r
+  EFI_GUID_DEFINED_SECTION2  GuidSectHeader2;\r
+  UINT32                     HeaderSize;\r
 \r
   Size          = 0;\r
   Offset        = 0;\r
@@ -312,7 +309,7 @@ Returns:
     // \r
     // Open file and read contents\r
     //\r
-    InFile = fopen (InputFileName[Index], "rb");\r
+    InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
     if (InFile == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
       return EFI_ABORTED;\r
@@ -322,13 +319,18 @@ Returns:
     FileSize = ftell (InFile);\r
     fseek (InFile, 0, SEEK_SET);\r
     DebugMsg (NULL, 0, 9, "Input section files", \r
-              "the input section name is %s and the size is %d bytes", InputFileName[Index], FileSize); \r
+              "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
 \r
     //\r
     // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
     //\r
     TeOffset = 0;\r
-    fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);\r
+    if (FileSize >= MAX_FFS_SIZE) {\r
+      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
+    } else {\r
+      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
+    }\r
+    fread (&TempSectHeader, 1, HeaderSize, InFile);\r
     if (TempSectHeader.Type == EFI_SECTION_TE) {\r
       (*PESectionNum) ++;\r
       fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
@@ -337,8 +339,21 @@ Returns:
       }\r
     } else if (TempSectHeader.Type == EFI_SECTION_PE32) {\r
       (*PESectionNum) ++;\r
+    } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {\r
+      fseek (InFile, 0, SEEK_SET);\r
+      if (FileSize >= MAX_SECTION_SIZE) {\r
+        fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);\r
+        if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+          HeaderSize = GuidSectHeader2.DataOffset;\r
+        }\r
+      } else {\r
+        fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
+        if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+          HeaderSize = GuidSectHeader.DataOffset;\r
+        }\r
+      }\r
+      (*PESectionNum) ++;\r
     } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION || \r
-               TempSectHeader.Type == EFI_SECTION_GUID_DEFINED ||\r
                TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
       //\r
       // for the encapsulated section, assume it contains Pe/Te section \r
@@ -356,17 +371,21 @@ Returns:
       TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);\r
       TeOffset = TeOffset % InputFileAlign [Index];\r
     }\r
-     \r
+\r
     //\r
     // make sure section data meet its alignment requirement by adding one raw pad section.\r
     // But the different sections have the different section header. Necessary or not?\r
     // Based on section type to adjust offset? Todo\r
     //\r
-    if ((InputFileAlign [Index] != 0) && (((Size + sizeof (EFI_COMMON_SECTION_HEADER) + TeOffset) % InputFileAlign [Index]) != 0)) {\r
-      Offset = (Size + 2 * sizeof (EFI_COMMON_SECTION_HEADER) + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
-      Offset = Offset - Size - sizeof (EFI_COMMON_SECTION_HEADER) - TeOffset;\r
+    if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
+      Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
+      Offset = Offset - Size - HeaderSize - TeOffset;\r
        \r
       if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
+        //\r
+        // The maximal alignment is 64K, the raw section size must be less than 0xffffff\r
+        //\r
+        memset (FileBuffer + Size, 0, Offset);\r
         SectHeader          = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
         SectHeader->Type    = EFI_SECTION_RAW;\r
         SectHeader->Size[0] = (UINT8) (Offset & 0xff);\r
@@ -374,7 +393,7 @@ Returns:
         SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);\r
       }\r
       DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", \r
-                "Pad Raw section size is %d", Offset);\r
+                "Pad Raw section size is %u", (unsigned) Offset);\r
 \r
       Size = Size + Offset;\r
     }\r
@@ -409,7 +428,7 @@ Returns:
 \r
 int\r
 main (\r
-  INT32 argc,\r
+  int   argc,\r
   CHAR8 *argv[]\r
   )\r
 /*++\r
@@ -441,11 +460,12 @@ Returns:
   UINT8                   *FileBuffer;\r
   UINT32                  FileSize;\r
   UINT32                  MaxAlignment;\r
-  EFI_FFS_FILE_HEADER     FfsFileHeader;\r
+  EFI_FFS_FILE_HEADER2    FfsFileHeader;\r
   FILE                    *FfsFile;\r
   UINT32                  Index;\r
   UINT64                  LogLevel;\r
   UINT8                   PeSectionNum;\r
+  UINT32                  HeaderSize;\r
   \r
   //\r
   // Init local variables\r
@@ -679,7 +699,7 @@ Returns:
         goto Finish;\r
       }\r
       if (LogLevel > 9) {\r
-        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", LogLevel);\r
+        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
         goto Finish;\r
       }\r
       SetPrintLevel (LogLevel);\r
@@ -719,7 +739,7 @@ Returns:
   VerboseMsg ("Fv File type is %s", mFfsFileType [FfsFiletype]);\r
   VerboseMsg ("Output file name is %s", OutputFileName);\r
   VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
-                FileGuid.Data1,\r
+                (unsigned) FileGuid.Data1,\r
                 FileGuid.Data2,\r
                 FileGuid.Data3,\r
                 FileGuid.Data4[0],\r
@@ -744,7 +764,7 @@ Returns:
       //\r
       InputFileAlign[Index] = 1;\r
     }\r
-    VerboseMsg ("the %dth input section name is %s and section alignment is %d", Index, InputFileName[Index], InputFileAlign[Index]);\r
+    VerboseMsg ("the %dth input section name is %s and section alignment is %u", Index, InputFileName[Index], (unsigned) InputFileAlign[Index]);\r
   }\r
   \r
   //\r
@@ -763,7 +783,7 @@ Returns:
   if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE || \r
       FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||\r
       FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {\r
-    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %d Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);\r
+    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);\r
     goto Finish;\r
   }\r
   \r
@@ -804,13 +824,13 @@ Returns:
   //\r
   // Create Ffs file header.\r
   //\r
-  memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
+  memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER2));\r
   memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));\r
   FfsFileHeader.Type       = FfsFiletype;\r
   //\r
   // Update FFS Alignment based on the max alignment required by input section files \r
   //\r
-  VerboseMsg ("the max alignment of all input sections is %d", MaxAlignment); \r
+  VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment); \r
   for (Index = 0; Index < sizeof (mFfsValidAlign) / sizeof (UINT32) - 1; Index ++) {\r
     if ((MaxAlignment > mFfsValidAlign [Index]) && (MaxAlignment <= mFfsValidAlign [Index + 1])) {\r
       break;\r
@@ -819,17 +839,28 @@ Returns:
   if (FfsAlign < Index) {\r
     FfsAlign = Index;\r
   }\r
-  VerboseMsg ("the alignment of the genreated FFS file is %d", mFfsValidAlign [FfsAlign + 1]);  \r
-  FfsFileHeader.Attributes = FfsAttrib | (FfsAlign << 3);\r
+  VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);  \r
   \r
   //\r
   // Now FileSize includes the EFI_FFS_FILE_HEADER\r
   //\r
-  FileSize += sizeof (EFI_FFS_FILE_HEADER);\r
-  VerboseMsg ("the size of the genreated FFS file is %d bytes", FileSize);\r
-  FfsFileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);\r
-  FfsFileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);\r
-  FfsFileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);\r
+  if (FileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {\r
+    HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);\r
+    FileSize += sizeof (EFI_FFS_FILE_HEADER2);\r
+    FfsFileHeader.ExtendedSize = FileSize;\r
+    memset(FfsFileHeader.Size, 0, sizeof (UINT8) * 3);\r
+    FfsAttrib |= FFS_ATTRIB_LARGE_FILE;\r
+  } else {\r
+    HeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
+    FileSize += sizeof (EFI_FFS_FILE_HEADER);\r
+    FfsFileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);\r
+    FfsFileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);\r
+    FfsFileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);\r
+  }\r
+  VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);\r
+\r
+  FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));\r
+\r
   //\r
   // Fill in checksums and state, these must be zero for checksumming\r
   //\r
@@ -839,7 +870,7 @@ Returns:
   //\r
   FfsFileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (\r
                                                    (UINT8 *) &FfsFileHeader,\r
-                                                   sizeof (EFI_FFS_FILE_HEADER)\r
+                                                   HeaderSize\r
                                                    );\r
 \r
   if (FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {\r
@@ -848,7 +879,7 @@ Returns:
     //\r
     FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
                                                    FileBuffer, \r
-                                                   FileSize - sizeof (EFI_FFS_FILE_HEADER)\r
+                                                   FileSize - HeaderSize\r
                                                    );    \r
   } else {\r
     FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
@@ -860,7 +891,7 @@ Returns:
   // Open output file to write ffs data.\r
   //\r
   remove(OutputFileName);\r
-  FfsFile = fopen (OutputFileName, "wb");\r
+  FfsFile = fopen (LongFilePath (OutputFileName), "wb");\r
   if (FfsFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", OutputFileName);\r
     goto Finish;\r
@@ -868,11 +899,11 @@ Returns:
   //\r
   // write header\r
   //\r
-  fwrite (&FfsFileHeader, 1, sizeof (FfsFileHeader), FfsFile);\r
+  fwrite (&FfsFileHeader, 1, HeaderSize, FfsFile);\r
   //\r
   // write data\r
   //\r
-  fwrite (FileBuffer, 1, FileSize - sizeof (EFI_FFS_FILE_HEADER), FfsFile);\r
+  fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);\r
 \r
   fclose (FfsFile);\r
 \r