\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
UINT32 TempResult;\r
UINT32 Index;\r
UINT32 IpiVector;\r
+ STATUS Status;\r
\r
TempGuid = NULL;\r
SetUtilityName (UTILITY_NAME);\r
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
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
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
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