/*++\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
UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};\r
\r
VOID\r
-PrintUtilityInfo (\r
+Version (\r
VOID\r
)\r
/*++\r
\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
\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
\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
\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
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