]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CCode/Source/SecApResetVectorFixup/SecApResetVectorFixup.c
ReCaculate the checksum after fixing up AP section for Sec module.
[mirror_edk2.git] / Tools / CCode / Source / SecApResetVectorFixup / SecApResetVectorFixup.c
index 06d3f3344a0110ac4c5357e40d51f9e979c87ef0..f34e2d1a631c2311f3d8bfbd80b09d40456bbce1 100644 (file)
@@ -171,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
@@ -210,6 +345,7 @@ Returns:
   UINT32                      TempResult;\r
   UINT32                      Index;\r
   UINT32                      IpiVector;\r
+  STATUS                      Status;\r
 \r
   TempGuid = NULL;\r
   SetUtilityName (UTILITY_NAME);\r
@@ -271,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
@@ -323,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
@@ -333,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
@@ -353,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