]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CCode/Source/SecApResetVectorFixup/SecApResetVectorFixup.c
- Fixed EDKT513 by adding existing section files into the dependency check of genffsf...
[mirror_edk2.git] / Tools / CCode / Source / SecApResetVectorFixup / SecApResetVectorFixup.c
index 442645720eed03fe56fb7ec256e77f43e59675c2..f34e2d1a631c2311f3d8bfbd80b09d40456bbce1 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c)  2004-2006 Intel Corporation. All rights reserved\r
+Copyright (c)  2004-2007 Intel Corporation. All rights reserved\r
 This program and the accompanying materials are licensed and made available \r
 under the terms and conditions of the BSD License which accompanies this \r
 distribution.  The full text of the license may be found at\r
@@ -63,7 +63,7 @@ EFI_GUID  NewFvPadFileNameGuid     = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0
 UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};\r
 \r
 VOID\r
-PrintUtilityInfo (\r
+Version (\r
   VOID\r
   )\r
 /*++\r
@@ -82,16 +82,12 @@ Returns:
 \r
 --*/\r
 {\r
-  printf (\r
-    "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",\r
-    UTILITY_NAME,\r
-    UTILITY_MAJOR_VERSION,\r
-    UTILITY_MINOR_VERSION\r
-    );\r
+  printf ("%s v%d.%d -Tiano IA32 SEC Ap Reset Vector Fixup Utility.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");\r
 }\r
 \r
 VOID\r
-PrintUsage (\r
+Usage (\r
   VOID\r
   )\r
 /*++\r
@@ -110,10 +106,12 @@ Returns:
 \r
 --*/\r
 {\r
-  printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);\r
+  Version();\r
+  \r
+  printf ("\nUsage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);\r
   printf ("  Where:\n");\r
-  printf ("\tInputFvrecoveryFile   - Name of the IA32 input Fvrecovery.fv file.\n");\r
-  printf ("\tOutputFvrecoveryFile  - Name of the IA32 output Fvrecovery.fv file.\n");\r
+  printf ("    InputFvrecoveryFile   - Name of the IA32 input Fvrecovery.fv file.\n");\r
+  printf ("    OutputFvrecoveryFile  - Name of the IA32 output Fvrecovery.fv file.\n");\r
 }\r
 \r
 \r
@@ -173,6 +171,141 @@ Returns:
   \r
 }\r
 \r
+VOID\r
+SetHeaderChecksum (\r
+  IN EFI_FFS_FILE_HEADER *FfsHeader\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Caculate the checksum for the FFS header.\r
+\r
+  Parameters:\r
+    FfsHeader     -   FFS File Header which needs to caculate the checksum\r
+\r
+  Return:\r
+    N/A\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE  State;\r
+  UINT8               HeaderChecksum;\r
+  UINT8               FileChecksum;\r
+\r
+  //\r
+  // The state and the File checksum are not included\r
+  //\r
+  State = FfsHeader->State;\r
+  FfsHeader->State = 0;\r
+\r
+  FileChecksum = FfsHeader->IntegrityCheck.Checksum.File;\r
+  FfsHeader->IntegrityCheck.Checksum.File = 0;\r
+\r
+  FfsHeader->IntegrityCheck.Checksum.Header = 0;\r
+\r
+  HeaderChecksum = CalculateChecksum8 ((UINT8 *)FfsHeader,sizeof (EFI_FFS_FILE_HEADER));\r
+\r
+  FfsHeader->IntegrityCheck.Checksum.Header = (UINT8) (~(0x100-HeaderChecksum) + 1);\r
+\r
+  FfsHeader->State                          = State;\r
+  FfsHeader->IntegrityCheck.Checksum.File   = FileChecksum;\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+SetFileChecksum (\r
+  IN EFI_FFS_FILE_HEADER *FfsHeader,\r
+  IN UINTN               ActualFileSize\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Caculate the checksum for the FFS File, usually it is caculated before\r
+    the file tail is set.\r
+\r
+  Parameters:\r
+    FfsHeader         -   FFS File Header which needs to caculate the checksum\r
+    ActualFileSize    -   The whole Ffs File Length, including the FFS Tail\r
+                          if exists, but at this time, it is 0.\r
+  Return:\r
+    N/A\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE  State;\r
+  UINT8               FileChecksum;\r
+  UINTN               ActualSize;\r
+\r
+  if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
+    //\r
+    // The file state is not included\r
+    //\r
+    State = FfsHeader->State;\r
+    FfsHeader->State = 0;\r
+\r
+    FfsHeader->IntegrityCheck.Checksum.File = 0;\r
+\r
+    if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
+      ActualSize = ActualFileSize - 2;\r
+    } else {\r
+      ActualSize = ActualFileSize;\r
+    }\r
+    //\r
+    // File checksum does not including the file tail\r
+    //\r
+    FileChecksum = CalculateChecksum8 ((UINT8 *)FfsHeader,sizeof (EFI_FFS_FILE_HEADER));\r
+\r
+    FfsHeader->IntegrityCheck.Checksum.File = (UINT8) (~(0x100-FileChecksum) + 1);\r
+\r
+    FfsHeader->State                        = State;\r
+\r
+  } else {\r
+\r
+    FfsHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
+\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+SetFileTail (\r
+  IN EFI_FFS_FILE_HEADER *FfsHeader,\r
+  IN UINTN               ActualFileSize\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set the file tail if needed\r
+\r
+  Parameters:\r
+    FfsHeader         -   FFS File Header which needs to caculate the checksum\r
+    ActualFileSize    -   The whole Ffs File Length, including the FFS Tail\r
+                          if exists.\r
+  Return:\r
+    N/A\r
+\r
+--*/\r
+{\r
+  UINT8   TailLow;\r
+  UINT8   TailHigh;\r
+  UINT16  Tail;\r
+\r
+  if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
+    //\r
+    // Insert tail here, since tail may not aligned on an even\r
+    // address, we need to do byte operation here.\r
+    //\r
+    Tail      = (UINT16)~FfsHeader->IntegrityCheck.TailReference;\r
+    TailLow   = (UINT8) Tail;\r
+    TailHigh  = (UINT8) (Tail >> 8);\r
+    *((UINT8 *) FfsHeader + ActualFileSize - 2) = TailLow;\r
+    *((UINT8 *) FfsHeader + ActualFileSize - 1) = TailHigh;\r
+  }\r
+\r
+  return ;\r
+}\r
 \r
 STATUS\r
 main (\r
@@ -212,21 +345,33 @@ Returns:
   UINT32                      TempResult;\r
   UINT32                      Index;\r
   UINT32                      IpiVector;\r
+  STATUS                      Status;\r
 \r
   TempGuid = NULL;\r
   SetUtilityName (UTILITY_NAME);\r
 \r
-  //\r
-  // Display utility information\r
-  //\r
-  PrintUtilityInfo ();\r
-\r
+  if (argc == 1) {\r
+    Usage();\r
+    return STATUS_ERROR;\r
+  }\r
+    \r
+  if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
+      (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
+    Usage();\r
+    return STATUS_ERROR;\r
+  }\r
+  \r
+  if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
+    Version();\r
+    return STATUS_ERROR;\r
+  }\r
\r
   //\r
   // Verify the correct number of arguments\r
   //\r
   if (argc != MAX_ARGS) {\r
     Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);\r
-    PrintUsage ();\r
+    Usage ();\r
     return STATUS_ERROR;\r
   }\r
   //\r
@@ -262,10 +407,17 @@ Returns:
     fclose (FpIn);\r
     return STATUS_ERROR;\r
   }\r
+  \r
+  //\r
+  // Prepare to walk the FV image\r
+  //\r
+  InitializeFvLib (FileBuffer, FvrecoveryFileSize);\r
+  \r
   //\r
   // Close the input Fvrecovery.fv file\r
   //\r
   fclose (FpIn);\r
+  \r
   //\r
   // Find the pad FFS file\r
   //\r
@@ -314,7 +466,8 @@ Returns:
     Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL);\r
     free ((VOID *)FileBufferRaw);\r
     return STATUS_ERROR; \r
-  }    \r
+  }\r
+\r
   //\r
   // Fix up Ap reset vector and calculate the IPI vector\r
   //\r
@@ -324,10 +477,33 @@ Returns:
   TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);\r
   TempResult >>= 12;\r
   IpiVector = TempResult & 0x0FF;\r
+    \r
+  //\r
+  // Update Pad file and checksum\r
+  //\r
+  UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);\r
   \r
+  //\r
+  // Get FileHeader of SEC Ffs\r
+  //\r
+  Status     = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &FileHeader);\r
   \r
-  UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);\r
+  //\r
+  // Write IPI Vector at Offset FvrecoveryFileSize - 8\r
+  //\r
+  *(UINT32 *)((UINTN)(FileBuffer + FvrecoveryFileSize - 8)) = IpiVector;\r
 \r
+  if (Status == STATUS_SUCCESS) {\r
+    FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;\r
+    //\r
+    // Update the Checksum of SEC ffs\r
+    //\r
+    SetHeaderChecksum (FileHeader);\r
+    SetFileChecksum (FileHeader, FileLength);\r
+    SetFileTail (FileHeader, FileLength);\r
+  } else {\r
+    Error (NULL, 0, 0, "Do not get SEC FFS File Header!", NULL);\r
+  }\r
   //\r
   // Open the output Fvrecovery.fv file\r
   //\r
@@ -344,15 +520,7 @@ Returns:
     free ((VOID *)FileBufferRaw);\r
     return STATUS_ERROR;   \r
   }\r
-  //\r
-  //\r
-  //\r
-  fseek (FpOut, -8, SEEK_END);\r
-  if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) {\r
-    Error (NULL, 0, 0, "Write output file error!", NULL);\r
-    free ((VOID *)FileBufferRaw);\r
-    return STATUS_ERROR;\r
-  }  \r
+\r
   //\r
   // Close the output Fvrecovery.fv file\r
   //\r