]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c
Applied BSD license to the source files
[mirror_edk2.git] / Tools / Source / TianoTools / SecApResetVectorFixup / SecApResetVectorFixup.c
CommitLineData
d25c4bf0 1/*++\r
2\r
ad1f8df0 3Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
4This program and the accompanying materials are licensed and made available \r
5under the terms and conditions of the BSD License which accompanies this \r
6distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
d25c4bf0 11\r
12\r
13Module Name:\r
14\r
15 SecApResetVectorFixup.c\r
16\r
17Abstract:\r
18\r
19 This utility is part of build process for IA32 Fvrecovery.fv whose total size\r
20 is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset \r
21 vector at the zero vector of Fv header.\r
22 \r
23 PEI FV after using the tool\r
24 \r
25 -------------------------\r
26 |zzz |\r
27 | |\r
28 | |\r
29 | FFS |\r
30 | |\r
31 | |\r
32 | |\r
33 |---------------------- |\r
34 | PAD |\r
35 | |\r
36 |.......................| --- \r
37 | | |\r
38 |xxx | | 128K \r
39 |---------------------- | | \r
40 | VTF (SEC) | |\r
41 ------------------------- ---\r
42 \r
43 1. zzz --> Zero vector, which is beyond the 128K limited address space\r
44 2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD\r
45 file area.\r
46 3. After the build process ,the PAD guid is changed to a new GUID to avoid \r
47 the PAD definition confusing. If there is some problem, try to disable\r
48 UpdatePadFileGuid\r
49 \r
50 \r
51 \r
52--*/\r
53\r
54#include "SecApResetVectorFixup.h"\r
55\r
56\r
57EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };\r
58EFI_GUID NewFvPadFileNameGuid = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 };\r
59\r
60//\r
61// jmp 0xf000:0xffd0 (0xFFFFFFD0)\r
62//\r
63UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};\r
64\r
65VOID\r
66PrintUtilityInfo (\r
67 VOID\r
68 )\r
69/*++\r
70\r
71Routine Description:\r
72\r
73 Displays the standard utility information to SDTOUT\r
74\r
75Arguments:\r
76\r
77 None\r
78\r
79Returns:\r
80\r
81 None\r
82\r
83--*/\r
84{\r
85 printf (\r
86 "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",\r
87 UTILITY_NAME,\r
88 UTILITY_MAJOR_VERSION,\r
89 UTILITY_MINOR_VERSION\r
90 );\r
91}\r
92\r
93VOID\r
94PrintUsage (\r
95 VOID\r
96 )\r
97/*++\r
98\r
99Routine Description:\r
100\r
101 Displays the utility usage syntax to STDOUT\r
102\r
103Arguments:\r
104\r
105 None\r
106\r
107Returns:\r
108\r
109 None\r
110\r
111--*/\r
112{\r
113 printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);\r
114 printf (" Where:\n");\r
115 printf ("\tInputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n");\r
116 printf ("\tOutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n");\r
117}\r
118\r
119\r
120VOID \r
121UpdatePadFileGuid (\r
122 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
123 IN EFI_FFS_FILE_HEADER *FileHeader,\r
124 IN UINT32 FileLength,\r
125 IN OUT EFI_GUID *Guid\r
126 )\r
127/*++\r
128\r
129Routine Description:\r
130\r
131 Update the Pad File Guid to change it to other guid and update\r
132 the checksum\r
133\r
134Arguments:\r
135 FvHeader - EFI_FIRMWARE_VOLUME_HEADER \r
136 FileHeader - The FFS PAD file header.\r
137 FileLength - The FFS PAD file length.\r
138 Guid - The Guid to compare and if it is PAD Guid, update it to new Guid\r
139Returns:\r
140 VOID\r
141--*/\r
142\r
143{\r
144 if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {\r
145 //\r
146 // Set new Pad file guid\r
147 // \r
148 memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID));\r
149\r
150\r
151\r
152 FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;\r
153 FileHeader->Attributes = 0;\r
154 //\r
155 // Fill in checksums and state, must be zero during checksum calculation.\r
156 //\r
157 FileHeader->IntegrityCheck.Checksum.Header = 0;\r
158 FileHeader->IntegrityCheck.Checksum.File = 0;\r
159 FileHeader->State = 0;\r
160 FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
161 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
162 FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength);\r
163 } else {\r
164 FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
165 }\r
166\r
167 FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
168\r
169 if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {\r
170 FileHeader->State = (UINT8)~(FileHeader->State);\r
171 } \r
172 }\r
173 \r
174}\r
175\r
176\r
177STATUS\r
178main (\r
179 IN INTN argc,\r
180 IN CHAR8 **argv\r
181 )\r
182/*++\r
183\r
184Routine Description:\r
185\r
186 Main function.\r
187\r
188Arguments:\r
189\r
190 argc - Number of command line parameters.\r
191 argv - Array of pointers to parameter strings.\r
192\r
193Returns:\r
194 STATUS_SUCCESS - Utility exits successfully.\r
195 STATUS_ERROR - Some error occurred during execution.\r
196\r
197--*/\r
198{\r
199 FILE *FpIn;\r
200 FILE *FpOut;\r
201 UINT32 FvrecoveryFileSize;\r
202 UINT8 *FileBuffer;\r
203 UINT8 *FileBufferRaw;\r
204 UINT64 FvLength;\r
205 UINT32 Offset;\r
206 UINT32 FileLength;\r
207 UINT32 FileOccupiedSize;\r
208 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
209 EFI_FFS_FILE_HEADER *FileHeader;\r
210 EFI_GUID *TempGuid;\r
211 UINT8 *FixPoint;\r
212 UINT32 TempResult;\r
213 UINT32 Index;\r
214 UINT32 IpiVector;\r
215\r
216 TempGuid = NULL;\r
217 SetUtilityName (UTILITY_NAME);\r
218\r
219 //\r
220 // Display utility information\r
221 //\r
222 PrintUtilityInfo ();\r
223\r
224 //\r
225 // Verify the correct number of arguments\r
226 //\r
227 if (argc != MAX_ARGS) {\r
228 Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);\r
229 PrintUsage ();\r
230 return STATUS_ERROR;\r
231 }\r
232 //\r
233 // Open the Input Fvrecovery.fv file\r
234 //\r
235 if ((FpIn = fopen (argv[1], "rb")) == NULL) {\r
236 Error (NULL, 0, 0, "Unable to open file", argv[1]);\r
237 return STATUS_ERROR;\r
238 }\r
239 //\r
240 // Get the Input Fvrecovery.fv file size\r
241 //\r
242 fseek (FpIn, 0, SEEK_END);\r
243 FvrecoveryFileSize = ftell (FpIn);\r
244 //\r
245 // Read the contents of input file to memory buffer\r
246 //\r
247 FileBuffer = NULL;\r
248 FileBufferRaw = NULL;\r
249 FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000);\r
250 if (NULL == FileBufferRaw) {\r
251 Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);\r
252 fclose (FpIn);\r
253 return STATUS_ERROR;\r
254 }\r
255 TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF);\r
256 FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult);\r
257 fseek (FpIn, 0, SEEK_SET);\r
258 TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn);\r
259 if (TempResult != FvrecoveryFileSize) {\r
260 Error (NULL, 0, 0, "Read input file error!", NULL);\r
261 free ((VOID *)FileBufferRaw);\r
262 fclose (FpIn);\r
263 return STATUS_ERROR;\r
264 }\r
265 //\r
266 // Close the input Fvrecovery.fv file\r
267 //\r
268 fclose (FpIn);\r
269 //\r
270 // Find the pad FFS file\r
271 //\r
272 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer;\r
273 FvLength = FvHeader->FvLength;\r
274 FileHeader = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength);\r
275 FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;\r
276 FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
277 Offset = (UINT32)FileHeader - (UINT32)FileBuffer;\r
278 \r
279 while (Offset < FvLength) {\r
280 TempGuid = (EFI_GUID *)&(FileHeader->Name);\r
281 FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;\r
282 FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
283 if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {\r
284 break;\r
285 }\r
286 FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize);\r
287 Offset = (UINT32)FileHeader - (UINT32)FileBuffer;\r
288 }\r
289\r
290 if (Offset >= FvLength) {\r
291 Error (NULL, 0, 0, "No pad file found!", NULL);\r
292 free ((VOID *)FileBufferRaw);\r
293 return STATUS_ERROR;\r
294 }\r
295 //\r
296 // Find the position to place Ap reset vector, the offset\r
297 // between the position and the end of Fvrecovery.fv file\r
298 // should not exceed 128kB to prevent Ap reset vector from\r
299 // outside legacy E and F segment\r
300 //\r
301 FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER));\r
302 TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF);\r
303 FixPoint +=TempResult;\r
304 if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) {\r
305 Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL);\r
306 free ((VOID *)FileBufferRaw);\r
307 return STATUS_ERROR; \r
308 }\r
309 while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) {\r
310 FixPoint += 0x1000;\r
311 }\r
312 FixPoint -= 0x1000;\r
313 if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) {\r
314 Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL);\r
315 free ((VOID *)FileBufferRaw);\r
316 return STATUS_ERROR; \r
ce53a8c3 317 } \r
d25c4bf0 318 //\r
319 // Fix up Ap reset vector and calculate the IPI vector\r
320 //\r
321 for (Index = 0; Index < 5; Index++) {\r
322 FixPoint[Index] = ApResetVector[Index];\r
323 } \r
324 TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);\r
325 TempResult >>= 12;\r
326 IpiVector = TempResult & 0x0FF;\r
327 \r
328 \r
329 UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);\r
330\r
331 //\r
332 // Open the output Fvrecovery.fv file\r
333 //\r
334 if ((FpOut = fopen (argv[2], "w+b")) == NULL) {\r
335 Error (NULL, 0, 0, "Unable to open file", argv[2]);\r
336 free ((VOID *)FileBufferRaw);\r
337 return STATUS_ERROR;\r
338 }\r
339 //\r
340 // Write the output Fvrecovery.fv file\r
341 //\r
342 if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) {\r
343 Error (NULL, 0, 0, "Write output file error!", NULL);\r
344 free ((VOID *)FileBufferRaw);\r
345 return STATUS_ERROR; \r
346 }\r
347 //\r
348 //\r
349 //\r
350 fseek (FpOut, -8, SEEK_END);\r
351 if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) {\r
352 Error (NULL, 0, 0, "Write output file error!", NULL);\r
353 free ((VOID *)FileBufferRaw);\r
354 return STATUS_ERROR;\r
355 } \r
356 //\r
357 // Close the output Fvrecovery.fv file\r
358 //\r
359 fclose (FpOut);\r
360 free ((VOID *)FileBufferRaw);\r
361 return STATUS_SUCCESS;\r
362}\r
363\r