]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/CCode/Source/SecApResetVectorFixup/SecApResetVectorFixup.c
06d3f3344a0110ac4c5357e40d51f9e979c87ef0
[mirror_edk2.git] / Tools / CCode / Source / SecApResetVectorFixup / SecApResetVectorFixup.c
1 /*++
2
3 Copyright (c) 2004-2007 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
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 Version (
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 ("%s v%d.%d -Tiano IA32 SEC Ap Reset Vector Fixup Utility.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
86 printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");
87 }
88
89 VOID
90 Usage (
91 VOID
92 )
93 /*++
94
95 Routine Description:
96
97 Displays the utility usage syntax to STDOUT
98
99 Arguments:
100
101 None
102
103 Returns:
104
105 None
106
107 --*/
108 {
109 Version();
110
111 printf ("\nUsage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);
112 printf (" Where:\n");
113 printf (" InputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n");
114 printf (" OutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n");
115 }
116
117
118 VOID
119 UpdatePadFileGuid (
120 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
121 IN EFI_FFS_FILE_HEADER *FileHeader,
122 IN UINT32 FileLength,
123 IN OUT EFI_GUID *Guid
124 )
125 /*++
126
127 Routine Description:
128
129 Update the Pad File Guid to change it to other guid and update
130 the checksum
131
132 Arguments:
133 FvHeader - EFI_FIRMWARE_VOLUME_HEADER
134 FileHeader - The FFS PAD file header.
135 FileLength - The FFS PAD file length.
136 Guid - The Guid to compare and if it is PAD Guid, update it to new Guid
137 Returns:
138 VOID
139 --*/
140
141 {
142 if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {
143 //
144 // Set new Pad file guid
145 //
146 memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID));
147
148
149
150 FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;
151 FileHeader->Attributes = 0;
152 //
153 // Fill in checksums and state, must be zero during checksum calculation.
154 //
155 FileHeader->IntegrityCheck.Checksum.Header = 0;
156 FileHeader->IntegrityCheck.Checksum.File = 0;
157 FileHeader->State = 0;
158 FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
159 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
160 FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength);
161 } else {
162 FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
163 }
164
165 FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
166
167 if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
168 FileHeader->State = (UINT8)~(FileHeader->State);
169 }
170 }
171
172 }
173
174
175 STATUS
176 main (
177 IN INTN argc,
178 IN CHAR8 **argv
179 )
180 /*++
181
182 Routine Description:
183
184 Main function.
185
186 Arguments:
187
188 argc - Number of command line parameters.
189 argv - Array of pointers to parameter strings.
190
191 Returns:
192 STATUS_SUCCESS - Utility exits successfully.
193 STATUS_ERROR - Some error occurred during execution.
194
195 --*/
196 {
197 FILE *FpIn;
198 FILE *FpOut;
199 UINT32 FvrecoveryFileSize;
200 UINT8 *FileBuffer;
201 UINT8 *FileBufferRaw;
202 UINT64 FvLength;
203 UINT32 Offset;
204 UINT32 FileLength;
205 UINT32 FileOccupiedSize;
206 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
207 EFI_FFS_FILE_HEADER *FileHeader;
208 EFI_GUID *TempGuid;
209 UINT8 *FixPoint;
210 UINT32 TempResult;
211 UINT32 Index;
212 UINT32 IpiVector;
213
214 TempGuid = NULL;
215 SetUtilityName (UTILITY_NAME);
216
217 if (argc == 1) {
218 Usage();
219 return STATUS_ERROR;
220 }
221
222 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||
223 (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {
224 Usage();
225 return STATUS_ERROR;
226 }
227
228 if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {
229 Version();
230 return STATUS_ERROR;
231 }
232
233 //
234 // Verify the correct number of arguments
235 //
236 if (argc != MAX_ARGS) {
237 Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
238 Usage ();
239 return STATUS_ERROR;
240 }
241 //
242 // Open the Input Fvrecovery.fv file
243 //
244 if ((FpIn = fopen (argv[1], "rb")) == NULL) {
245 Error (NULL, 0, 0, "Unable to open file", argv[1]);
246 return STATUS_ERROR;
247 }
248 //
249 // Get the Input Fvrecovery.fv file size
250 //
251 fseek (FpIn, 0, SEEK_END);
252 FvrecoveryFileSize = ftell (FpIn);
253 //
254 // Read the contents of input file to memory buffer
255 //
256 FileBuffer = NULL;
257 FileBufferRaw = NULL;
258 FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000);
259 if (NULL == FileBufferRaw) {
260 Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
261 fclose (FpIn);
262 return STATUS_ERROR;
263 }
264 TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF);
265 FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult);
266 fseek (FpIn, 0, SEEK_SET);
267 TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn);
268 if (TempResult != FvrecoveryFileSize) {
269 Error (NULL, 0, 0, "Read input file error!", NULL);
270 free ((VOID *)FileBufferRaw);
271 fclose (FpIn);
272 return STATUS_ERROR;
273 }
274 //
275 // Close the input Fvrecovery.fv file
276 //
277 fclose (FpIn);
278 //
279 // Find the pad FFS file
280 //
281 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer;
282 FvLength = FvHeader->FvLength;
283 FileHeader = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength);
284 FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
285 FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
286 Offset = (UINT32)FileHeader - (UINT32)FileBuffer;
287
288 while (Offset < FvLength) {
289 TempGuid = (EFI_GUID *)&(FileHeader->Name);
290 FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
291 FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
292 if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {
293 break;
294 }
295 FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize);
296 Offset = (UINT32)FileHeader - (UINT32)FileBuffer;
297 }
298
299 if (Offset >= FvLength) {
300 Error (NULL, 0, 0, "No pad file found!", NULL);
301 free ((VOID *)FileBufferRaw);
302 return STATUS_ERROR;
303 }
304 //
305 // Find the position to place Ap reset vector, the offset
306 // between the position and the end of Fvrecovery.fv file
307 // should not exceed 128kB to prevent Ap reset vector from
308 // outside legacy E and F segment
309 //
310 FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER));
311 TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF);
312 FixPoint +=TempResult;
313 if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) {
314 Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL);
315 free ((VOID *)FileBufferRaw);
316 return STATUS_ERROR;
317 }
318 while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) {
319 FixPoint += 0x1000;
320 }
321 FixPoint -= 0x1000;
322 if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) {
323 Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL);
324 free ((VOID *)FileBufferRaw);
325 return STATUS_ERROR;
326 }
327 //
328 // Fix up Ap reset vector and calculate the IPI vector
329 //
330 for (Index = 0; Index < 5; Index++) {
331 FixPoint[Index] = ApResetVector[Index];
332 }
333 TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);
334 TempResult >>= 12;
335 IpiVector = TempResult & 0x0FF;
336
337
338 UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);
339
340 //
341 // Open the output Fvrecovery.fv file
342 //
343 if ((FpOut = fopen (argv[2], "w+b")) == NULL) {
344 Error (NULL, 0, 0, "Unable to open file", argv[2]);
345 free ((VOID *)FileBufferRaw);
346 return STATUS_ERROR;
347 }
348 //
349 // Write the output Fvrecovery.fv file
350 //
351 if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) {
352 Error (NULL, 0, 0, "Write output file error!", NULL);
353 free ((VOID *)FileBufferRaw);
354 return STATUS_ERROR;
355 }
356 //
357 //
358 //
359 fseek (FpOut, -8, SEEK_END);
360 if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) {
361 Error (NULL, 0, 0, "Write output file error!", NULL);
362 free ((VOID *)FileBufferRaw);
363 return STATUS_ERROR;
364 }
365 //
366 // Close the output Fvrecovery.fv file
367 //
368 fclose (FpOut);
369 free ((VOID *)FileBufferRaw);
370 return STATUS_SUCCESS;
371 }
372