]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c
Adding Additional Tools that are needed for Platform Image creation.
[mirror_edk2.git] / Tools / Source / TianoTools / SecApResetVectorFixup / SecApResetVectorFixup.c
1 /*++
2
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
10 Intel Corporation.
11
12
13 Module Name:
14
15 SecApResetVectorFixup.c
16
17 Abstract:
18
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.
22
23 PEI FV after using the tool
24
25 -------------------------
26 |zzz |
27 | |
28 | |
29 | FFS |
30 | |
31 | |
32 | |
33 |---------------------- |
34 | PAD |
35 | |
36 |.......................| ---
37 | | |
38 |xxx | | 128K
39 |---------------------- | |
40 | VTF (SEC) | |
41 ------------------------- ---
42
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
45 file area.
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
48 UpdatePadFileGuid
49
50
51
52 --*/
53
54 #include "SecApResetVectorFixup.h"
55
56
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 };
59
60 //
61 // jmp 0xf000:0xffd0 (0xFFFFFFD0)
62 //
63 UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};
64
65 VOID
66 PrintUtilityInfo (
67 VOID
68 )
69 /*++
70
71 Routine Description:
72
73 Displays the standard utility information to SDTOUT
74
75 Arguments:
76
77 None
78
79 Returns:
80
81 None
82
83 --*/
84 {
85 printf (
86 "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",
87 UTILITY_NAME,
88 UTILITY_MAJOR_VERSION,
89 UTILITY_MINOR_VERSION
90 );
91 }
92
93 VOID
94 PrintUsage (
95 VOID
96 )
97 /*++
98
99 Routine Description:
100
101 Displays the utility usage syntax to STDOUT
102
103 Arguments:
104
105 None
106
107 Returns:
108
109 None
110
111 --*/
112 {
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");
117 }
118
119
120 VOID
121 UpdatePadFileGuid (
122 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
123 IN EFI_FFS_FILE_HEADER *FileHeader,
124 IN UINT32 FileLength,
125 IN OUT EFI_GUID *Guid
126 )
127 /*++
128
129 Routine Description:
130
131 Update the Pad File Guid to change it to other guid and update
132 the checksum
133
134 Arguments:
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
139 Returns:
140 VOID
141 --*/
142
143 {
144 if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {
145 //
146 // Set new Pad file guid
147 //
148 memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID));
149
150
151
152 FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;
153 FileHeader->Attributes = 0;
154 //
155 // Fill in checksums and state, must be zero during checksum calculation.
156 //
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);
163 } else {
164 FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
165 }
166
167 FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
168
169 if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
170 FileHeader->State = (UINT8)~(FileHeader->State);
171 }
172 }
173
174 }
175
176
177 STATUS
178 main (
179 IN INTN argc,
180 IN CHAR8 **argv
181 )
182 /*++
183
184 Routine Description:
185
186 Main function.
187
188 Arguments:
189
190 argc - Number of command line parameters.
191 argv - Array of pointers to parameter strings.
192
193 Returns:
194 STATUS_SUCCESS - Utility exits successfully.
195 STATUS_ERROR - Some error occurred during execution.
196
197 --*/
198 {
199 FILE *FpIn;
200 FILE *FpOut;
201 UINT32 FvrecoveryFileSize;
202 UINT8 *FileBuffer;
203 UINT8 *FileBufferRaw;
204 UINT64 FvLength;
205 UINT32 Offset;
206 UINT32 FileLength;
207 UINT32 FileOccupiedSize;
208 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
209 EFI_FFS_FILE_HEADER *FileHeader;
210 EFI_GUID *TempGuid;
211 UINT8 *FixPoint;
212 UINT32 TempResult;
213 UINT32 Index;
214 UINT32 IpiVector;
215
216 TempGuid = NULL;
217 SetUtilityName (UTILITY_NAME);
218
219 //
220 // Display utility information
221 //
222 PrintUtilityInfo ();
223
224 //
225 // Verify the correct number of arguments
226 //
227 if (argc != MAX_ARGS) {
228 Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
229 PrintUsage ();
230 return STATUS_ERROR;
231 }
232 //
233 // Open the Input Fvrecovery.fv file
234 //
235 if ((FpIn = fopen (argv[1], "rb")) == NULL) {
236 Error (NULL, 0, 0, "Unable to open file", argv[1]);
237 return STATUS_ERROR;
238 }
239 //
240 // Get the Input Fvrecovery.fv file size
241 //
242 fseek (FpIn, 0, SEEK_END);
243 FvrecoveryFileSize = ftell (FpIn);
244 //
245 // Read the contents of input file to memory buffer
246 //
247 FileBuffer = NULL;
248 FileBufferRaw = NULL;
249 FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000);
250 if (NULL == FileBufferRaw) {
251 Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
252 fclose (FpIn);
253 return STATUS_ERROR;
254 }
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);
262 fclose (FpIn);
263 return STATUS_ERROR;
264 }
265 //
266 // Close the input Fvrecovery.fv file
267 //
268 fclose (FpIn);
269 //
270 // Find the pad FFS file
271 //
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;
278
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) {
284 break;
285 }
286 FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize);
287 Offset = (UINT32)FileHeader - (UINT32)FileBuffer;
288 }
289
290 if (Offset >= FvLength) {
291 Error (NULL, 0, 0, "No pad file found!", NULL);
292 free ((VOID *)FileBufferRaw);
293 return STATUS_ERROR;
294 }
295 //
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
300 //
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);
307 return STATUS_ERROR;
308 }
309 while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) {
310 FixPoint += 0x1000;
311 }
312 FixPoint -= 0x1000;
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);
316 return STATUS_ERROR;
317 }
318 //
319 // Fix up Ap reset vector and calculate the IPI vector
320 //
321 for (Index = 0; Index < 5; Index++) {
322 FixPoint[Index] = ApResetVector[Index];
323 }
324 TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);
325 TempResult >>= 12;
326 IpiVector = TempResult & 0x0FF;
327
328
329 UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);
330
331 //
332 // Open the output Fvrecovery.fv file
333 //
334 if ((FpOut = fopen (argv[2], "w+b")) == NULL) {
335 Error (NULL, 0, 0, "Unable to open file", argv[2]);
336 free ((VOID *)FileBufferRaw);
337 return STATUS_ERROR;
338 }
339 //
340 // Write the output Fvrecovery.fv file
341 //
342 if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) {
343 Error (NULL, 0, 0, "Write output file error!", NULL);
344 free ((VOID *)FileBufferRaw);
345 return STATUS_ERROR;
346 }
347 //
348 //
349 //
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);
354 return STATUS_ERROR;
355 }
356 //
357 // Close the output Fvrecovery.fv file
358 //
359 fclose (FpOut);
360 free ((VOID *)FileBufferRaw);
361 return STATUS_SUCCESS;
362 }
363