3 Copyright (c) 2005 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
15 SecApResetVectorFixup.c
19 This utility is part of build process for IA32 Fvrecovery.fv whose total size
20 is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset
21 vector at the zero vector of Fv header.
23 PEI FV after using the tool
25 -------------------------
33 |---------------------- |
36 |.......................| ---
39 |---------------------- | |
41 ------------------------- ---
43 1. zzz --> Zero vector, which is beyond the 128K limited address space
44 2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD
46 3. After the build process ,the PAD guid is changed to a new GUID to avoid
47 the PAD definition confusing. If there is some problem, try to disable
54 #include "SecApResetVectorFixup.h"
57 EFI_GUID DefaultFvPadFileNameGuid
= { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };
58 EFI_GUID NewFvPadFileNameGuid
= { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 };
61 // jmp 0xf000:0xffd0 (0xFFFFFFD0)
63 UINT8 ApResetVector
[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};
73 Displays the standard utility information to SDTOUT
86 "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",
88 UTILITY_MAJOR_VERSION
,
101 Displays the utility usage syntax to STDOUT
113 printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME
);
114 printf (" Where:\n");
115 printf ("\tInputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n");
116 printf ("\tOutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n");
122 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
123 IN EFI_FFS_FILE_HEADER
*FileHeader
,
124 IN UINT32 FileLength
,
125 IN OUT EFI_GUID
*Guid
131 Update the Pad File Guid to change it to other guid and update
135 FvHeader - EFI_FIRMWARE_VOLUME_HEADER
136 FileHeader - The FFS PAD file header.
137 FileLength - The FFS PAD file length.
138 Guid - The Guid to compare and if it is PAD Guid, update it to new Guid
144 if ((CompareGuid (Guid
, (EFI_GUID
*)&DefaultFvPadFileNameGuid
)) == 0) {
146 // Set new Pad file guid
148 memcpy (Guid
, &NewFvPadFileNameGuid
, sizeof (EFI_GUID
));
152 FileHeader
->Type
= EFI_FV_FILETYPE_FFS_PAD
;
153 FileHeader
->Attributes
= 0;
155 // Fill in checksums and state, must be zero during checksum calculation.
157 FileHeader
->IntegrityCheck
.Checksum
.Header
= 0;
158 FileHeader
->IntegrityCheck
.Checksum
.File
= 0;
159 FileHeader
->State
= 0;
160 FileHeader
->IntegrityCheck
.Checksum
.Header
= CalculateChecksum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
161 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
162 FileHeader
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 ((UINT8
*) FileHeader
, FileLength
);
164 FileHeader
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
167 FileHeader
->State
= EFI_FILE_HEADER_CONSTRUCTION
| EFI_FILE_HEADER_VALID
| EFI_FILE_DATA_VALID
;
169 if (FvHeader
->Attributes
& EFI_FVB_ERASE_POLARITY
) {
170 FileHeader
->State
= (UINT8
)~(FileHeader
->State
);
190 argc - Number of command line parameters.
191 argv - Array of pointers to parameter strings.
194 STATUS_SUCCESS - Utility exits successfully.
195 STATUS_ERROR - Some error occurred during execution.
201 UINT32 FvrecoveryFileSize
;
203 UINT8
*FileBufferRaw
;
207 UINT32 FileOccupiedSize
;
208 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
209 EFI_FFS_FILE_HEADER
*FileHeader
;
217 SetUtilityName (UTILITY_NAME
);
220 // Display utility information
225 // Verify the correct number of arguments
227 if (argc
!= MAX_ARGS
) {
228 Error (NULL
, 0, 0, "invalid number of input parameters specified", NULL
);
233 // Open the Input Fvrecovery.fv file
235 if ((FpIn
= fopen (argv
[1], "rb")) == NULL
) {
236 Error (NULL
, 0, 0, "Unable to open file", argv
[1]);
240 // Get the Input Fvrecovery.fv file size
242 fseek (FpIn
, 0, SEEK_END
);
243 FvrecoveryFileSize
= ftell (FpIn
);
245 // Read the contents of input file to memory buffer
248 FileBufferRaw
= NULL
;
249 FileBufferRaw
= (UINT8
*) malloc (FvrecoveryFileSize
+ 0x10000);
250 if (NULL
== FileBufferRaw
) {
251 Error (NULL
, 0, 0, "No sufficient memory to allocate!", NULL
);
255 TempResult
= 0x10000 - ((UINT32
)FileBufferRaw
& 0x0FFFF);
256 FileBuffer
= (UINT8
*)((UINT32
)FileBufferRaw
+ TempResult
);
257 fseek (FpIn
, 0, SEEK_SET
);
258 TempResult
= fread (FileBuffer
, 1, FvrecoveryFileSize
, FpIn
);
259 if (TempResult
!= FvrecoveryFileSize
) {
260 Error (NULL
, 0, 0, "Read input file error!", NULL
);
261 free ((VOID
*)FileBufferRaw
);
266 // Close the input Fvrecovery.fv file
270 // Find the pad FFS file
272 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FileBuffer
;
273 FvLength
= FvHeader
->FvLength
;
274 FileHeader
= (EFI_FFS_FILE_HEADER
*)(FileBuffer
+ FvHeader
->HeaderLength
);
275 FileLength
= (*(UINT32
*)(FileHeader
->Size
)) & 0x00FFFFFF;
276 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
277 Offset
= (UINT32
)FileHeader
- (UINT32
)FileBuffer
;
279 while (Offset
< FvLength
) {
280 TempGuid
= (EFI_GUID
*)&(FileHeader
->Name
);
281 FileLength
= (*(UINT32
*)(FileHeader
->Size
)) & 0x00FFFFFF;
282 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
283 if ((CompareGuid (TempGuid
, (EFI_GUID
*)&DefaultFvPadFileNameGuid
)) == 0) {
286 FileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT32
)FileHeader
+ FileOccupiedSize
);
287 Offset
= (UINT32
)FileHeader
- (UINT32
)FileBuffer
;
290 if (Offset
>= FvLength
) {
291 Error (NULL
, 0, 0, "No pad file found!", NULL
);
292 free ((VOID
*)FileBufferRaw
);
296 // Find the position to place Ap reset vector, the offset
297 // between the position and the end of Fvrecovery.fv file
298 // should not exceed 128kB to prevent Ap reset vector from
299 // outside legacy E and F segment
301 FixPoint
= (UINT8
*)(FileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
302 TempResult
= 0x1000 - ((UINT32
)FixPoint
& 0x0FFF);
303 FixPoint
+=TempResult
;
304 if (((UINT32
)FixPoint
- (UINT32
)FileHeader
+ 5) > FileOccupiedSize
) {
305 Error (NULL
, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL
);
306 free ((VOID
*)FileBufferRaw
);
309 while (((UINT32
)FixPoint
- (UINT32
)FileHeader
+ 5) <= FileOccupiedSize
) {
313 if ((UINT32
)FvHeader
+ FvLength
- (UINT32
)FixPoint
> 0x20000) {
314 Error (NULL
, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL
);
315 free ((VOID
*)FileBufferRaw
);
319 // Fix up Ap reset vector and calculate the IPI vector
321 for (Index
= 0; Index
< 5; Index
++) {
322 FixPoint
[Index
] = ApResetVector
[Index
];
324 TempResult
= 0x0FFFFFFFF - ((UINT32
)FvHeader
+ (UINT32
)FvLength
- 1 - (UINT32
)FixPoint
);
326 IpiVector
= TempResult
& 0x0FF;
329 UpdatePadFileGuid (FvHeader
, FileHeader
, FileLength
, TempGuid
);
332 // Open the output Fvrecovery.fv file
334 if ((FpOut
= fopen (argv
[2], "w+b")) == NULL
) {
335 Error (NULL
, 0, 0, "Unable to open file", argv
[2]);
336 free ((VOID
*)FileBufferRaw
);
340 // Write the output Fvrecovery.fv file
342 if ((fwrite (FileBuffer
, 1, FvrecoveryFileSize
, FpOut
)) != FvrecoveryFileSize
) {
343 Error (NULL
, 0, 0, "Write output file error!", NULL
);
344 free ((VOID
*)FileBufferRaw
);
350 fseek (FpOut
, -8, SEEK_END
);
351 if ((fwrite (&IpiVector
, 1, sizeof(UINT32
), FpOut
)) != sizeof(UINT32
)) {
352 Error (NULL
, 0, 0, "Write output file error!", NULL
);
353 free ((VOID
*)FileBufferRaw
);
357 // Close the output Fvrecovery.fv file
360 free ((VOID
*)FileBufferRaw
);
361 return STATUS_SUCCESS
;