]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenVtf/GenVtf.c
Fix ICC build break.
[mirror_edk2.git] / BaseTools / Source / C / GenVtf / GenVtf.c
CommitLineData
30fdf114
LG
1/**\r
2\r
40d841f6 3Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>\r
a709adfa
LG
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
30fdf114
LG
11\r
12\r
13Module Name:\r
14\r
15 GenVtf.c\r
16\r
17Abstract:\r
18\r
19 This file contains functions required to generate a boot strap file (BSF)\r
20 also known as the Volume Top File (VTF)\r
21\r
22**/\r
23\r
24//\r
25//\r
26//\r
27#include <FvLib.h>\r
28#include <Common/UefiBaseTypes.h>\r
29#include "GenVtf.h"\r
30#include <Guid/PiFirmwareFileSystem.h>\r
31#include "CommonLib.h"\r
32#include "EfiUtilityMsgs.h"\r
33\r
34//\r
35// Global variables\r
36//\r
37UINTN SectionOptionFlag = 0;\r
38UINTN SectionCompFlag = 0;\r
39\r
40UINT64 DebugLevel;\r
41BOOLEAN DebugMode;\r
42\r
43BOOLEAN QuietMode = FALSE;\r
44\r
45BOOLEAN VTF_OUTPUT = FALSE;\r
46CHAR8 *OutFileName1;\r
47CHAR8 *OutFileName2;\r
48CHAR8 *SymFileName;\r
49\r
50CHAR8 **TokenStr;\r
51CHAR8 **OrgStrTokPtr;\r
52\r
53PARSED_VTF_INFO *FileListPtr;\r
54PARSED_VTF_INFO *FileListHeadPtr;\r
55\r
56VOID *Vtf1Buffer;\r
57VOID *Vtf1EndBuffer;\r
58VOID *Vtf2Buffer;\r
59VOID *Vtf2EndBuffer;\r
60\r
61UINTN ValidLineNum = 0;\r
62UINTN ValidFFDFileListNum = 0;\r
63\r
64//\r
65// Section Description and their number of occurences in *.INF file\r
66//\r
67UINTN NumFvFiles = 0;\r
68UINTN SectionOptionNum = 0;\r
69\r
70//\r
71// Global flag which will check for VTF Present, if yes then will be used\r
72// to decide about adding FFS header to pad data\r
73//\r
74BOOLEAN VTFPresent = FALSE;\r
75BOOLEAN SecondVTF = FALSE;\r
76\r
77//\r
78// Address related information\r
79//\r
80UINT64 Fv1BaseAddress = 0;\r
81UINT64 Fv2BaseAddress = 0;\r
82UINT64 Fv1EndAddress = 0;\r
83UINT64 Fv2EndAddress = 0;\r
84UINT32 Vtf1TotalSize = SIZE_TO_OFFSET_PAL_A_END;\r
85UINT64 Vtf1LastStartAddress = 0;\r
86UINT32 Vtf2TotalSize = 0;\r
87UINT64 Vtf2LastStartAddress = 0;\r
88\r
89UINT32 BufferToTop = 0;\r
90\r
91//\r
92// IA32 Reset Vector Bin name\r
93//\r
94CHAR8 IA32BinFile[FILE_NAME_SIZE];\r
95\r
96//\r
97// Function Implementations\r
98//\r
99EFI_STATUS\r
100ConvertVersionInfo (\r
101 IN CHAR8 *Str,\r
102 IN OUT UINT8 *MajorVer,\r
103 IN OUT UINT8 *MinorVer\r
104 )\r
105/*++\r
106Routine Description:\r
107\r
6780eef1 108 This function split version to major version and minor version\r
30fdf114
LG
109\r
110Arguments:\r
111\r
112 Str - String representing in form XX.XX\r
6780eef1
LG
113 MajorVer - The major version\r
114 MinorVer - The minor version\r
30fdf114
LG
115\r
116Returns:\r
117\r
6780eef1 118 EFI_SUCCESS - The function completed successfully.\r
30fdf114
LG
119\r
120--*/\r
121{\r
122 CHAR8 StrPtr[40];\r
123 CHAR8 *Token;\r
fd171542 124 unsigned Major;\r
125 unsigned Minor;\r
30fdf114
LG
126\r
127 Major = 0;\r
128 Minor = 0;\r
129 memset (StrPtr, 0, 40);\r
130 Token = strtok (Str, ".");\r
131\r
132 while (Token != NULL) {\r
133 strcat (StrPtr, Token);\r
134 Token = strtok (NULL, ".");\r
135 }\r
136\r
30fdf114
LG
137 sscanf (\r
138 StrPtr,\r
6780eef1 139 "%02d%02d",\r
30fdf114
LG
140 &Major,\r
141 &Minor\r
142 );\r
143\r
144 *MajorVer = (UINT8) Major;\r
145 *MinorVer = (UINT8) Minor;\r
146 return EFI_SUCCESS;\r
147}\r
148\r
149VOID\r
150TrimLine (\r
151 IN CHAR8 *Line\r
152 )\r
153/*++\r
154Routine Description:\r
155\r
156 This function cleans up the line by removing all whitespace and\r
157 comments\r
158\r
159Arguments:\r
160\r
161 Line - The pointer of the string\r
162\r
163Returns:\r
164\r
165 None\r
166\r
167--*/\r
168{\r
169 CHAR8 TmpLine[FILE_NAME_SIZE];\r
170 CHAR8 Char;\r
171 CHAR8 *Ptr0;\r
172 UINTN Index;\r
173 UINTN Index2;\r
174\r
175 //\r
176 // Change '#' to '//' for Comment style\r
177 //\r
178 if (((Ptr0 = strchr (Line, '#')) != NULL) || ((Ptr0 = strstr (Line, "//")) != NULL)) {\r
179 Line[Ptr0 - Line] = 0;\r
180 }\r
181\r
182 //\r
183 // Initialize counters\r
184 //\r
185 Index = 0;\r
186 Index2 = 0;\r
187\r
188 while ((Char = Line[Index]) != 0) {\r
189 if ((Char != ' ') && (Char != '\t') && (Char != '\n') && (Char != '\r')) {\r
190 TmpLine[Index2++] = Char;\r
191 }\r
192 Index++;\r
193 }\r
194\r
195 TmpLine[Index2] = 0;\r
196 strcpy (Line, TmpLine);\r
197}\r
198\r
199VOID\r
200ValidLineCount (\r
201 IN FILE *Fp\r
202 )\r
203/*++\r
204\r
205Routine Description:\r
206\r
207 This function calculated number of valid lines in a input file.\r
208\r
209Arguments:\r
210\r
211 Fp - Pointer to a file handle which has been opened.\r
212\r
213Returns:\r
214\r
215 None\r
216\r
217--*/\r
218{\r
219 CHAR8 Buff[FILE_NAME_SIZE];\r
220 while (fgets(Buff, sizeof (Buff), Fp)) {\r
221 TrimLine (Buff);\r
222 if (Buff[0] == 0) {\r
223 continue;\r
224 }\r
225 ValidLineNum++;\r
226 }\r
227}\r
228\r
229EFI_STATUS\r
230ParseInputFile (\r
231 IN FILE *Fp\r
232 )\r
233/*++\r
234\r
235Routine Description:\r
236\r
237 This function parses the input file and tokenize the string\r
238\r
239Arguments:\r
240\r
241 Fp - Pointer to a file handle which has been opened.\r
242\r
243Returns:\r
244\r
245 None\r
246\r
247--*/\r
248{\r
249 CHAR8 *Token;\r
250 CHAR8 Buff[FILE_NAME_SIZE + 1];\r
251 CHAR8 Delimit[] = "=";\r
252\r
253 Buff [FILE_NAME_SIZE] = '\0';\r
254 Token = NULL;\r
255\r
256 while (fgets (Buff, FILE_NAME_SIZE, Fp) != NULL) {\r
257 TrimLine (Buff);\r
258 if (Buff[0] == 0) {\r
259 continue;\r
260 }\r
261 Token = strtok (Buff, Delimit);\r
262 while (Token != NULL) {\r
263 strcpy (*TokenStr, Token);\r
264 TokenStr ++;\r
265 Token = strtok (NULL, Delimit);\r
266 }\r
267 }\r
268 return EFI_SUCCESS;\r
269}\r
270\r
271EFI_STATUS\r
272InitializeComps (\r
273 VOID\r
274 )\r
275/*++\r
276\r
277Routine Description:\r
278\r
fd171542 279 This function initializes the relevant global variable which is being\r
30fdf114
LG
280 used to store the information retrieved from INF file. This also initializes\r
281 the VTF symbol file.\r
282\r
283Arguments:\r
284\r
285 None\r
286\r
287Returns:\r
288\r
289 EFI_SUCCESS - The function completed successfully\r
290 EFI_OUT_OF_RESOURCES - Malloc failed.\r
291\r
292--*/\r
293{\r
294\r
295 FileListPtr = malloc (sizeof (PARSED_VTF_INFO));\r
296\r
297 if (FileListPtr == NULL) {\r
298 return EFI_OUT_OF_RESOURCES;\r
299 }\r
300\r
301 FileListHeadPtr = FileListPtr;\r
302 memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));\r
303 FileListPtr->NextVtfInfo = NULL;\r
304\r
305 remove (SymFileName);\r
306 return EFI_SUCCESS;\r
307}\r
308\r
309VOID\r
310ParseAndUpdateComponents (\r
311 IN PARSED_VTF_INFO *VtfInfo\r
312 )\r
313/*++\r
314\r
315Routine Description:\r
316\r
fd171542 317 This function initializes the relevant global variable which is being\r
30fdf114
LG
318 used to store the information retrieved from INF file.\r
319\r
320Arguments:\r
321\r
322 VtfInfo - A pointer to the VTF Info Structure\r
323\r
324\r
325Returns:\r
326\r
327 None\r
328\r
329--*/\r
330{\r
331 UINT64 StringValue;\r
332\r
333 while (*TokenStr != NULL && (strnicmp (*TokenStr, "COMP_NAME", 9) != 0)) {\r
334\r
335 if (strnicmp (*TokenStr, "COMP_LOC", 8) == 0) {\r
336 TokenStr++;\r
337 if (strnicmp (*TokenStr, "F", 1) == 0) {\r
338 VtfInfo->LocationType = FIRST_VTF;\r
339 } else if (strnicmp (*TokenStr, "S", 1) == 0) {\r
340 VtfInfo->LocationType = SECOND_VTF;\r
341 } else {\r
342 VtfInfo->LocationType = NONE;\r
30fdf114
LG
343 }\r
344 } else if (strnicmp (*TokenStr, "COMP_TYPE", 9) == 0) {\r
345 TokenStr++;\r
346 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
fd171542 347 Error (NULL, 0, 5001, "Cannot get: \"0x%s\".", *TokenStr);\r
30fdf114
LG
348 return ;\r
349 }\r
350\r
351 VtfInfo->CompType = (UINT8) StringValue;\r
352 } else if (strnicmp (*TokenStr, "COMP_VER", 8) == 0) {\r
353 TokenStr++;\r
354 if (strnicmp (*TokenStr, "-", 1) == 0) {\r
355 VtfInfo->VersionPresent = FALSE;\r
356 VtfInfo->MajorVer = 0;\r
357 VtfInfo->MinorVer = 0;\r
358 } else {\r
359 VtfInfo->VersionPresent = TRUE;\r
360 ConvertVersionInfo (*TokenStr, &VtfInfo->MajorVer, &VtfInfo->MinorVer);\r
361 }\r
362 } else if (strnicmp (*TokenStr, "COMP_BIN", 8) == 0) {\r
363 TokenStr++;\r
364 strcpy (VtfInfo->CompBinName, *TokenStr);\r
365 } else if (strnicmp (*TokenStr, "COMP_SYM", 8) == 0) {\r
366 TokenStr++;\r
367 strcpy (VtfInfo->CompSymName, *TokenStr);\r
368 } else if (strnicmp (*TokenStr, "COMP_SIZE", 9) == 0) {\r
369 TokenStr++;\r
370 if (strnicmp (*TokenStr, "-", 1) == 0) {\r
371 VtfInfo->PreferredSize = FALSE;\r
372 VtfInfo->CompSize = 0;\r
373 } else {\r
374 VtfInfo->PreferredSize = TRUE;\r
375 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
376 Error (NULL, 0, 5001, "Parse error", "Cannot get: %s.", TokenStr);\r
377 return ;\r
378 }\r
379\r
380 VtfInfo->CompSize = (UINTN) StringValue;\r
381 }\r
382\r
383 } else if (strnicmp (*TokenStr, "COMP_CS", 7) == 0) {\r
384 TokenStr++;\r
385 if (strnicmp (*TokenStr, "1", 1) == 0) {\r
386 VtfInfo->CheckSumRequired = 1;\r
387 } else if (strnicmp (*TokenStr, "0", 1) == 0) {\r
388 VtfInfo->CheckSumRequired = 0;\r
389 } else {\r
390 Error (NULL, 0, 3000, "Invaild", "Bad value in INF file required field: Checksum, the value must be '0' or '1'.");\r
391 }\r
392 }\r
393\r
394 TokenStr++;\r
395 if (*TokenStr == NULL) {\r
396 break;\r
397 }\r
398 }\r
399}\r
400\r
401VOID\r
402InitializeInFileInfo (\r
403 VOID\r
404 )\r
405/*++\r
406\r
407Routine Description:\r
408\r
409 This function intializes the relevant global variable which is being\r
410 used to store the information retrieved from INF file.\r
411\r
412Arguments:\r
413\r
414 NONE\r
415\r
416Returns:\r
417\r
418 NONE\r
419\r
420--*/\r
421{\r
422\r
423 SectionOptionFlag = 0;\r
424 SectionCompFlag = 0;\r
425 TokenStr = OrgStrTokPtr;\r
426\r
427 while (*TokenStr != NULL) {\r
428 if (strnicmp (*TokenStr, "[OPTIONS]", 9) == 0) {\r
429 SectionOptionFlag = 1;\r
430 SectionCompFlag = 0;\r
431 }\r
432\r
433 if (strnicmp (*TokenStr, "[COMPONENTS]", 12) == 0) {\r
434 if (FileListPtr == NULL) {\r
435 FileListPtr = FileListHeadPtr;\r
436 }\r
437\r
438 SectionCompFlag = 1;\r
439 SectionOptionFlag = 0;\r
440 TokenStr++;\r
441 }\r
442\r
443 if (SectionOptionFlag) {\r
444 if (stricmp (*TokenStr, "IA32_RST_BIN") == 0) {\r
445 TokenStr++;\r
446 strcpy (IA32BinFile, *TokenStr);\r
447 }\r
448 }\r
449\r
450 if (SectionCompFlag) {\r
451 if (stricmp (*TokenStr, "COMP_NAME") == 0) {\r
452 TokenStr++;\r
453 strcpy (FileListPtr->CompName, *TokenStr);\r
454 TokenStr++;\r
455 ParseAndUpdateComponents (FileListPtr);\r
456 }\r
457\r
458 if (*TokenStr != NULL) {\r
459 FileListPtr->NextVtfInfo = malloc (sizeof (PARSED_VTF_INFO));\r
460 if (FileListPtr->NextVtfInfo == NULL) {\r
461 Error (NULL, 0, 4003, "Resource", "Out of memory resources.", NULL);\r
462 break;\r
463 }\r
464 FileListPtr = FileListPtr->NextVtfInfo;\r
465 memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));\r
466 FileListPtr->NextVtfInfo = NULL;\r
467 continue;\r
468 } else {\r
469 break;\r
470 }\r
471 }\r
472\r
473 TokenStr++;\r
474 }\r
475}\r
476\r
477EFI_STATUS\r
478GetVtfRelatedInfoFromInfFile (\r
479 IN FILE *FilePointer\r
480 )\r
481/*++\r
482\r
483Routine Description:\r
484\r
485 This function reads the input file, parse it and create a list of tokens\r
486 which is parsed and used, to intialize the data related to VTF\r
487\r
488Arguments:\r
489\r
490 FileName - FileName which needed to be read to parse data\r
491\r
492Returns:\r
493\r
494 EFI_ABORTED - Error in opening file\r
495 EFI_INVALID_PARAMETER - File doesn't contain any valid information\r
496 EFI_OUT_OF_RESOURCES - Malloc Failed\r
497 EFI_SUCCESS - The function completed successfully\r
498\r
499--*/\r
500{\r
501 FILE *Fp;\r
502 UINTN Index;\r
503 UINTN Index1;\r
504 EFI_STATUS Status;\r
505\r
506 Status = EFI_SUCCESS;\r
507 Fp = FilePointer;\r
508 if (Fp == NULL) {\r
509 Error (NULL, 0, 2000, "Invalid parameter", "BSF INF file is invalid!");\r
510 return EFI_ABORTED;\r
511 }\r
512\r
513 ValidLineCount (Fp);\r
514\r
515 if (ValidLineNum == 0) {\r
516 Error (NULL, 0, 2000, "Invalid parameter", "File does not contain any valid information!");\r
517 return EFI_INVALID_PARAMETER;\r
518 }\r
519\r
520 TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum + 1));\r
521\r
522 if (TokenStr == NULL) {\r
523 return EFI_OUT_OF_RESOURCES;\r
524 }\r
525\r
526 memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1)));\r
527 OrgStrTokPtr = TokenStr;\r
528\r
529 for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
530 *TokenStr = (CHAR8*)malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
531\r
532 if (*TokenStr == NULL) {\r
533 Status = EFI_OUT_OF_RESOURCES;\r
534 goto ParseFileError;\r
535 }\r
536\r
537 memset (*TokenStr, 0, FILE_NAME_SIZE);\r
538 TokenStr++;\r
539 }\r
540\r
541 TokenStr = OrgStrTokPtr;\r
542 fseek (Fp, 0L, SEEK_SET);\r
543\r
544 Status = InitializeComps ();\r
545\r
546 if (Status != EFI_SUCCESS) {\r
547 goto ParseFileError;\r
548 }\r
549\r
550 Status = ParseInputFile (Fp);\r
551 if (Status != EFI_SUCCESS) {\r
552 goto ParseFileError;\r
553 }\r
554\r
555 InitializeInFileInfo ();\r
556\r
557ParseFileError:\r
558\r
559 for (Index1 = 0; Index1 < Index; Index1 ++) {\r
560 free (OrgStrTokPtr[Index1]);\r
561 }\r
562\r
563 free (OrgStrTokPtr);\r
564\r
565 return Status;\r
566}\r
567\r
568VOID\r
569GetRelativeAddressInVtfBuffer (\r
570 IN UINT64 Address,\r
571 IN OUT UINTN *RelativeAddress,\r
572 IN LOC_TYPE LocType\r
573 )\r
574/*++\r
575\r
576Routine Description:\r
577\r
578 This function checks for the address alignmnet for specified data boundary. In\r
579 case the address is not aligned, it returns FALSE and the amount of data in\r
580 terms of byte needed to adjust to get the boundary alignmnet. If data is\r
581 aligned, TRUE will be returned.\r
582\r
583Arguments:\r
584\r
585 Address - The address of the flash map space\r
586 RelativeAddress - The relative address of the Buffer\r
587 LocType - The type of the VTF\r
588\r
589\r
590Returns:\r
591\r
592\r
593--*/\r
594{\r
595 UINT64 TempAddress;\r
596 UINT8 *LocalBuff;\r
597\r
598 if (LocType == FIRST_VTF) {\r
599 LocalBuff = (UINT8 *) Vtf1EndBuffer;\r
600 TempAddress = Fv1EndAddress - Address;\r
601 *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;\r
602 } else {\r
603 LocalBuff = (UINT8 *) Vtf2EndBuffer;\r
604 TempAddress = Fv2EndAddress - Address;\r
605 *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;\r
606 }\r
607}\r
608\r
609EFI_STATUS\r
610GetComponentVersionInfo (\r
611 IN OUT PARSED_VTF_INFO *VtfInfo,\r
612 IN UINT8 *Buffer\r
613 )\r
614/*++\r
615Routine Description:\r
616\r
617 This function will extract the version information from File\r
618\r
619Arguments:\r
620\r
621 VtfInfo - A Pointer to the VTF Info Structure\r
622 Buffer - A Pointer to type UINT8\r
623\r
624Returns:\r
625\r
626 EFI_SUCCESS - The function completed successfully\r
627 EFI_INVALID_PARAMETER - The parameter is invalid\r
628\r
629--*/\r
630{\r
631 UINT16 VersionInfo;\r
632 EFI_STATUS Status;\r
633\r
634 switch (VtfInfo->CompType) {\r
635\r
636 case COMP_TYPE_FIT_PAL_A:\r
637 case COMP_TYPE_FIT_PAL_B:\r
638 memcpy (&VersionInfo, (Buffer + 8), sizeof (UINT16));\r
639 VtfInfo->MajorVer = (UINT8) ((VersionInfo & 0xFF00) >> 8);\r
640 VtfInfo->MinorVer = (UINT8) (VersionInfo & 0x00FF);\r
641 Status = EFI_SUCCESS;\r
642 break;\r
643\r
644 default:\r
645 Status = EFI_INVALID_PARAMETER;\r
646 break;\r
647 }\r
648\r
649 return Status;\r
650}\r
651\r
652BOOLEAN\r
653CheckAddressAlignment (\r
654 IN UINT64 Address,\r
655 IN UINT64 AlignmentData,\r
656 IN OUT UINT64 *AlignAdjustByte\r
657 )\r
658/*++\r
659\r
660Routine Description:\r
661\r
662 This function checks for the address alignmnet for specified data boundary. In\r
663 case the address is not aligned, it returns FALSE and the amount of data in\r
664 terms of byte needed to adjust to get the boundary alignmnet. If data is\r
665 aligned, TRUE will be returned.\r
666\r
667Arguments:\r
668\r
669 Address - Pointer to buffer containing byte data of component.\r
670 AlignmentData - DataSize for which address needed to be aligned\r
671 AlignAdjustByte - Number of bytes needed to adjust alignment.\r
672\r
673Returns:\r
674\r
675 TRUE - Address is aligned to specific data size boundary\r
676 FALSE - Address in not aligned to specified data size boundary\r
677 - Add/Subtract AlignAdjustByte to aling the address.\r
678\r
679--*/\r
680{\r
681 //\r
682 // Check if the assigned address is on address boundary. If not, it will\r
683 // return the remaining byte required to adjust the address for specified\r
684 // address boundary\r
685 //\r
686 *AlignAdjustByte = (Address % AlignmentData);\r
687\r
688 if (*AlignAdjustByte == 0) {\r
689 return TRUE;\r
690 } else {\r
691 return FALSE;\r
692 }\r
693}\r
694\r
695EFI_STATUS\r
696GetFitTableStartAddress (\r
697 IN OUT FIT_TABLE **FitTable\r
698 )\r
699/*++\r
700\r
701Routine Description:\r
702\r
703 Get the FIT table start address in VTF Buffer\r
704\r
705Arguments:\r
706\r
707 FitTable - Pointer to available fit table where new component can be added\r
708\r
709Returns:\r
710\r
711 EFI_SUCCESS - The function completed successfully\r
712\r
713--*/\r
714{\r
715 UINT64 FitTableAdd;\r
716 UINT64 FitTableAddOffset;\r
717 UINTN RelativeAddress;\r
718\r
719 //\r
720 // Read the Fit Table address from Itanium-based address map.\r
721 //\r
722 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
723\r
724 //\r
725 // Translate this Itanium-based address in terms of local buffer address which\r
726 // contains the image for Boot Strapped File. The relative address will be\r
727 // the address of fit table VTF buffer.\r
728 //\r
729 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
730 FitTableAdd = *(UINTN *) RelativeAddress;\r
731\r
732 //\r
733 // The FitTableAdd is the extracted Itanium based address pointing to FIT\r
734 // table. The relative address will return its actual location in VTF\r
735 // Buffer.\r
736 //\r
737 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
738\r
739 *FitTable = (FIT_TABLE *) RelativeAddress;\r
740\r
741 return EFI_SUCCESS;\r
742}\r
743\r
744EFI_STATUS\r
745GetNextAvailableFitPtr (\r
746 IN FIT_TABLE **FitPtr\r
747 )\r
748/*++\r
749\r
750Routine Description:\r
751\r
752 Get the FIT table address and locate the free space in fit where we can add\r
753 new component. In this process, this function locates the fit table using\r
754 Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)\r
755 and locate the available location in FIT table to be used by new components.\r
756 If there are any Fit table which areg not being used contains ComponentType\r
757 field as 0x7F. If needed we can change this and spec this out.\r
758\r
759Arguments:\r
760\r
761 FitPtr - Pointer to available fit table where new component can be added\r
762\r
763Returns:\r
764\r
765 EFI_SUCCESS - The function completed successfully\r
766\r
767--*/\r
768{\r
769 FIT_TABLE *TmpFitPtr;\r
770 UINT64 FitTableAdd;\r
771 UINT64 FitTableAddOffset;\r
772 UINTN Index;\r
773 UINTN NumFitComponents;\r
774 UINTN RelativeAddress;\r
775\r
776 //\r
777 // Read the Fit Table address from Itanium-based address map.\r
778 //\r
779 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
780\r
781 //\r
782 // Translate this Itanium-based address in terms of local buffer address which\r
783 // contains the image for Boot Strapped File. The relative address will be\r
784 // the address of fit table VTF buffer.\r
785 //\r
786 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
787 FitTableAdd = *(UINTN *) RelativeAddress;\r
788\r
789 //\r
790 // The FitTableAdd is the extracted Itanium based address pointing to FIT\r
791 // table. The relative address will return its actual location in VTF\r
792 // Buffer.\r
793 //\r
794 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
795\r
796 TmpFitPtr = (FIT_TABLE *) RelativeAddress;\r
797 NumFitComponents = TmpFitPtr->CompSize;\r
798\r
799 for (Index = 0; Index < NumFitComponents; Index++) {\r
800 if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) {\r
801 *FitPtr = TmpFitPtr;\r
802 break;\r
803 }\r
804\r
805 TmpFitPtr++;\r
806 }\r
807\r
808 return EFI_SUCCESS;\r
809}\r
810\r
811int\r
812CompareItems (\r
813 IN const VOID *Arg1,\r
814 IN const VOID *Arg2\r
815 )\r
816/*++\r
817\r
818Routine Description:\r
819\r
820 This function is used by qsort to sort the FIT table based upon Component\r
821 Type in their incresing order.\r
822\r
823Arguments:\r
824\r
825 Arg1 - Pointer to Arg1\r
826 Arg2 - Pointer to Arg2\r
827\r
828Returns:\r
829\r
830 None\r
831\r
832--*/\r
833{\r
834 if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) > (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {\r
835 return 1;\r
836 } else if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) < (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {\r
837 return -1;\r
838 } else {\r
839 return 0;\r
840 }\r
841}\r
842\r
843VOID\r
844SortFitTable (\r
845 IN VOID\r
846 )\r
847/*++\r
848\r
849Routine Description:\r
850\r
851 This function is used by qsort to sort the FIT table based upon Component\r
852 Type in their incresing order.\r
853\r
854Arguments:\r
855\r
856 VOID\r
857\r
858Returns:\r
859\r
860 None\r
861\r
862--*/\r
863{\r
864 FIT_TABLE *FitTable;\r
865 FIT_TABLE *TmpFitPtr;\r
866 UINTN NumFitComponents;\r
867 UINTN Index;\r
868\r
869 GetFitTableStartAddress (&FitTable);\r
870 TmpFitPtr = FitTable;\r
871 NumFitComponents = 0;\r
872 for (Index = 0; Index < FitTable->CompSize; Index++) {\r
873 if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) != COMP_TYPE_FIT_UNUSED) {\r
874 NumFitComponents += 1;\r
875 }\r
876 TmpFitPtr++;\r
877 }\r
878 qsort ((VOID *) FitTable, NumFitComponents, sizeof (FIT_TABLE), CompareItems);\r
879}\r
880\r
881VOID\r
882UpdateFitEntryForFwVolume (\r
883 IN UINT64 Size\r
884 )\r
885/*++\r
886\r
887Routine Description:\r
888\r
889 This function updates the information about Firmware Volume in FIT TABLE.\r
890 This FIT table has to be immediately below the PAL_A Start and it contains\r
891 component type and address information. Other information can't be\r
892 created this time so we would need to fix it up..\r
893\r
894\r
895Arguments:\r
896\r
897 Size - Firmware Volume Size\r
898\r
899Returns:\r
900\r
901 VOID\r
902\r
903--*/\r
904{\r
905 FIT_TABLE *CompFitPtr;\r
906 UINTN RelativeAddress;\r
907\r
908 //\r
909 // FV Fit table will be located at PAL_A Startaddress - 16 byte location\r
910 //\r
911 Vtf1LastStartAddress -= 0x10;\r
912 Vtf1TotalSize += 0x10;\r
913\r
914 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
915\r
916 CompFitPtr = (FIT_TABLE *) RelativeAddress;\r
917 CompFitPtr->CompAddress = Fv1BaseAddress;\r
918\r
919 //\r
920 // Since we don't have any information about its location in Firmware Volume,\r
921 // initialize address to 0. This will be updated once Firmware Volume is\r
922 // being build and its current address will be fixed in FIT table. Currently\r
923 // we haven't implemented it so far and working on architectural clarafication\r
924 //\r
925 //\r
926 // Firmware Volume Size in 16 byte block\r
927 //\r
928 CompFitPtr->CompSize = ((UINT32) Size) / 16;\r
929\r
930 //\r
931 // Since Firmware Volume does not exist by the time we create this FIT info\r
932 // this should be fixedup from Firmware Volume creation tool. We haven't\r
933 // worked out a method so far.\r
934 //\r
935 CompFitPtr->CompVersion = MAKE_VERSION (0, 0);\r
936\r
937 //\r
938 // Since we don't have any info about this file, we are making sure that\r
939 // checksum is not needed.\r
940 //\r
941 CompFitPtr->CvAndType = CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT);\r
942\r
943 //\r
944 // Since non VTF component will reside outside the VTF, we will not have its\r
945 // binary image while creating VTF, hence we will not perform checksum at\r
946 // this time. Once Firmware Volume is being created which will contain this\r
947 // VTF, it will fix the FIT table for all the non VTF component and hence\r
948 // checksum\r
949 //\r
950 CompFitPtr->CheckSum = 0;\r
951}\r
952\r
953EFI_STATUS\r
954UpdateFitEntryForNonVTFComp (\r
955 IN PARSED_VTF_INFO *VtfInfo\r
956 )\r
957/*++\r
958\r
959Routine Description:\r
960\r
961 This function updates the information about non VTF component in FIT TABLE.\r
962 Since non VTF componets binaries are not part of VTF binary, we would still\r
963 be required to update its location information in Firmware Volume, inside\r
964 FIT table.\r
965\r
966Arguments:\r
967\r
968 VtfInfo - Pointer to VTF Info Structure\r
969\r
970Returns:\r
971\r
972 EFI_ABORTED - The function fails to update the component in FIT\r
973 EFI_SUCCESS - The function completed successfully\r
974\r
975--*/\r
976{\r
977 FIT_TABLE *CompFitPtr;\r
978\r
979 //\r
980 // Scan the FIT table for available space\r
981 //\r
982 GetNextAvailableFitPtr (&CompFitPtr);\r
983 if (CompFitPtr == NULL) {\r
984 Error (NULL, 0, 5003, "Invalid", "Can't update this component in FIT");\r
985 return EFI_ABORTED;\r
986 }\r
987\r
988 //\r
989 // Since we don't have any information about its location in Firmware Volume,\r
990 // initialize address to 0. This will be updated once Firmware Volume is\r
991 // being build and its current address will be fixed in FIT table\r
992 //\r
993 CompFitPtr->CompAddress = 0;\r
994 CompFitPtr->CompSize = VtfInfo->CompSize;\r
995 CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);\r
996 CompFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);\r
997\r
998 //\r
999 // Since non VTF component will reside outside the VTF, we will not have its\r
1000 // binary image while creating VTF, hence we will not perform checksum at\r
1001 // this time. Once Firmware Volume is being created which will contain this\r
1002 // VTF, it will fix the FIT table for all the non VTF component and hence\r
1003 // checksum\r
1004 //\r
1005 CompFitPtr->CheckSum = 0;\r
1006\r
1007 //\r
1008 // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base\r
1009 // address of Firmware Volume in which this VTF will be attached.\r
1010 //\r
1011 if ((CompFitPtr->CvAndType & 0x7F) == COMP_TYPE_FIT_FV_BOOT) {\r
1012 CompFitPtr->CompAddress = Fv1BaseAddress;\r
1013 }\r
1014\r
1015 return EFI_SUCCESS;\r
1016}\r
1017\r
1018//\r
1019// !!!WARNING\r
1020// This function is updating the SALE_ENTRY in Itanium address space as per SAL\r
1021// spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI\r
1022// CORE moves in Firmware Volume, we would need to modify this function to be\r
1023// used with a API which will detect PEICORE component while building Firmware\r
1024// Volume and update its entry in FIT table as well as in Itanium address space\r
1025// as per Intel?Itanium(TM) SAL address space\r
1026//\r
1027EFI_STATUS\r
1028UpdateEntryPoint (\r
1029 IN PARSED_VTF_INFO *VtfInfo,\r
1030 IN UINT64 *CompStartAddress\r
1031 )\r
1032/*++\r
1033\r
1034Routine Description:\r
1035\r
1036 This function updated the architectural entry point in IPF, SALE_ENTRY.\r
1037\r
1038Arguments:\r
1039\r
1040 VtfInfo - Pointer to VTF Info Structure\r
1041 CompStartAddress - Pointer to Component Start Address\r
1042\r
1043Returns:\r
1044\r
1045 EFI_INVALID_PARAMETER - The parameter is invalid\r
1046 EFI_SUCCESS - The function completed successfully\r
1047\r
1048--*/\r
1049{\r
1050 UINTN RelativeAddress;\r
1051 UINT64 SalEntryAdd;\r
1052 FILE *Fp;\r
1053 UINTN Offset;\r
1054\r
1055 CHAR8 Buff[FILE_NAME_SIZE];\r
1056 CHAR8 Buff1[10];\r
1057 CHAR8 Buff2[10];\r
1058 CHAR8 OffsetStr[30];\r
1059 CHAR8 Buff3[10];\r
1060 CHAR8 Buff4[10];\r
1061 CHAR8 Buff5[10];\r
1062 CHAR8 Token[50];\r
1063\r
1064 Fp = fopen (VtfInfo->CompSymName, "rb");\r
1065\r
1066 if (Fp == NULL) {\r
1067 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompSymName);\r
1068 return EFI_INVALID_PARAMETER;\r
1069 }\r
1070\r
1071 while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
1072 fscanf (\r
1073 Fp,\r
1074 "%s %s %s %s %s %s %s",\r
1075 Buff1,\r
1076 Buff2,\r
1077 OffsetStr,\r
1078 Buff3,\r
1079 Buff4,\r
1080 Buff5,\r
1081 Token\r
1082 );\r
1083 if (strnicmp (Token, "SALE_ENTRY", 10) == 0) {\r
1084 break;\r
1085 }\r
1086 }\r
1087\r
1088 Offset = strtoul (OffsetStr, NULL, 16);\r
1089\r
1090 *CompStartAddress += Offset;\r
1091 SalEntryAdd = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT);\r
1092\r
1093 GetRelativeAddressInVtfBuffer (SalEntryAdd, &RelativeAddress, FIRST_VTF);\r
1094\r
1095 memcpy ((VOID *) RelativeAddress, (VOID *) CompStartAddress, sizeof (UINT64));\r
1096\r
1097 if (Fp != NULL) {\r
1098 fclose (Fp);\r
1099 }\r
1100\r
1101 return EFI_SUCCESS;\r
1102}\r
1103\r
1104EFI_STATUS\r
1105CreateAndUpdateComponent (\r
1106 IN PARSED_VTF_INFO *VtfInfo\r
1107 )\r
1108/*++\r
1109\r
1110Routine Description:\r
1111\r
1112 This function reads the binary file for each components and update them\r
1113 in VTF Buffer as well as in FIT table. If the component is located in non\r
1114 VTF area, only the FIT table address will be updated\r
1115\r
1116Arguments:\r
1117\r
1118 VtfInfo - Pointer to Parsed Info\r
1119\r
1120Returns:\r
1121\r
1122 EFI_SUCCESS - The function completed successful\r
1123 EFI_ABORTED - Aborted due to one of the many reasons like:\r
1124 (a) Component Size greater than the specified size.\r
1125 (b) Error opening files.\r
1126\r
1127 EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()\r
1128 EFI_OUT_OF_RESOURCES Memory allocation failure.\r
1129\r
1130--*/\r
1131{\r
1132 EFI_STATUS Status;\r
1133 UINT64 CompStartAddress;\r
1134 UINT64 FileSize;\r
1135 UINT64 NumByteRead;\r
1136 UINT64 NumAdjustByte;\r
1137 UINT8 *Buffer;\r
1138 FILE *Fp;\r
1139 FIT_TABLE *CompFitPtr;\r
1140 BOOLEAN Aligncheck;\r
1141\r
1142 if (VtfInfo->LocationType == NONE) {\r
1143 UpdateFitEntryForNonVTFComp (VtfInfo);\r
1144 return EFI_SUCCESS;\r
1145 }\r
1146\r
1147 Fp = fopen (VtfInfo->CompBinName, "rb");\r
1148\r
1149 if (Fp == NULL) {\r
1150 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);\r
1151 return EFI_ABORTED;\r
1152 }\r
1153\r
1154 FileSize = _filelength (fileno (Fp));\r
1155 if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {\r
1156\r
1157 //\r
1158 // BUGBUG: Satish to correct\r
1159 //\r
1160 FileSize -= SIZE_OF_PAL_HEADER;\r
1161 }\r
1162\r
1163 if (VtfInfo->PreferredSize) {\r
1164 if (FileSize > VtfInfo->CompSize) {\r
1165 Error (NULL, 0, 2000, "Invalid parameter", "The component size is more than specified size.");\r
1166 return EFI_ABORTED;\r
1167 }\r
1168\r
1169 FileSize = VtfInfo->CompSize;\r
1170 }\r
1171\r
1172 Buffer = malloc ((UINTN) FileSize);\r
1173 if (Buffer == NULL) {\r
1174 return EFI_OUT_OF_RESOURCES;\r
1175 }\r
1176 memset (Buffer, 0, (UINTN) FileSize);\r
1177\r
1178 if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {\r
1179\r
1180 //\r
1181 // Read first 64 bytes of PAL header and use it to find version info\r
1182 //\r
1183 NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
1184\r
1185 //\r
1186 // PAL header contains the version info. Currently, we will use the header\r
1187 // to read version info and then discard.\r
1188 //\r
1189 if (!VtfInfo->VersionPresent) {\r
1190 GetComponentVersionInfo (VtfInfo, Buffer);\r
1191 }\r
1192 }\r
1193\r
1194 NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
1195 fclose (Fp);\r
1196\r
1197 //\r
1198 // If it is non PAL_B component, pass the entire buffer to get the version\r
1199 // info and implement any specific case inside GetComponentVersionInfo.\r
1200 //\r
1201 if (VtfInfo->CompType != COMP_TYPE_FIT_PAL_B) {\r
1202 if (!VtfInfo->VersionPresent) {\r
1203 GetComponentVersionInfo (VtfInfo, Buffer);\r
1204 }\r
1205 }\r
1206\r
1207 if (VtfInfo->LocationType == SECOND_VTF) {\r
1208\r
1209 CompStartAddress = (Vtf2LastStartAddress - FileSize);\r
1210 } else {\r
1211 CompStartAddress = (Vtf1LastStartAddress - FileSize);\r
1212 }\r
1213\r
1214 if (VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) {\r
1215 Aligncheck = CheckAddressAlignment (CompStartAddress, 32 * 1024, &NumAdjustByte);\r
1216 } else {\r
1217 Aligncheck = CheckAddressAlignment (CompStartAddress, 8, &NumAdjustByte);\r
1218 }\r
1219\r
1220 if (!Aligncheck) {\r
1221 CompStartAddress -= NumAdjustByte;\r
1222 }\r
1223\r
1224 if (VtfInfo->LocationType == SECOND_VTF && SecondVTF == TRUE) {\r
1225 Vtf2LastStartAddress = CompStartAddress;\r
1226 Vtf2TotalSize += (UINT32) (FileSize + NumAdjustByte);\r
1227 Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, SECOND_VTF);\r
1228 } else if (VtfInfo->LocationType == FIRST_VTF) {\r
1229 Vtf1LastStartAddress = CompStartAddress;\r
1230 Vtf1TotalSize += (UINT32) (FileSize + NumAdjustByte);\r
1231 Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF);\r
1232 } else {\r
1233 Error (NULL, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");\r
1234 return EFI_INVALID_PARAMETER;\r
1235 }\r
1236\r
1237 if (EFI_ERROR (Status)) {\r
1238 return EFI_ABORTED;\r
1239 }\r
1240\r
1241 GetNextAvailableFitPtr (&CompFitPtr);\r
1242\r
1243 CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT;\r
1244 if ((FileSize % 16) != 0) {\r
1245 Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");\r
1246 return EFI_INVALID_PARAMETER;\r
1247 }\r
1248 //assert ((FileSize % 16) == 0);\r
1249 CompFitPtr->CompSize = (UINT32) (FileSize / 16);\r
1250 CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);\r
1251 CompFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);\r
1252 if (VtfInfo->CheckSumRequired) {\r
1253 CompFitPtr->CheckSum = 0;\r
1254 CompFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);\r
1255 }\r
1256\r
1257 //\r
1258 // Free the buffer\r
1259 //\r
1260 if (Buffer) {\r
1261 free (Buffer);\r
1262 }\r
1263\r
1264 //\r
1265 // Update the SYM file for this component based on it's start address.\r
1266 //\r
b303ea72 1267 Status = UpdateSymFile (CompStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);\r
30fdf114
LG
1268 if (EFI_ERROR (Status)) {\r
1269\r
1270 //\r
1271 // At this time, SYM files are not required, so continue on error.\r
1272 //\r
1273 }\r
1274\r
1275 // !!!!!!!!!!!!!!!!!!!!!\r
1276 // BUGBUG:\r
1277 // This part of the code is a temporary line since PEICORE is going to be inside\r
1278 // VTF till we work out how to determine the SALE_ENTRY through it. We will need\r
1279 // to clarify so many related questions\r
1280 // !!!!!!!!!!!!!!!!!!!!!!!\r
1281\r
1282 if (VtfInfo->CompType == COMP_TYPE_FIT_PEICORE) {\r
1283 Status = UpdateEntryPoint (VtfInfo, &CompStartAddress);\r
1284 }\r
1285\r
1286 return Status;\r
1287}\r
1288\r
1289EFI_STATUS\r
1290CreateAndUpdatePAL_A (\r
1291 IN PARSED_VTF_INFO *VtfInfo\r
1292 )\r
1293/*++\r
1294\r
1295Routine Description:\r
1296\r
1297 This function reads the binary file for each components and update them\r
1298 in VTF Buffer as well as FIT table\r
1299\r
1300Arguments:\r
1301\r
1302 VtfInfo - Pointer to Parsed Info\r
1303\r
1304Returns:\r
1305\r
1306 EFI_ABORTED - Due to one of the following reasons:\r
1307 (a)Error Opening File\r
1308 (b)The PAL_A Size is more than specified size status\r
1309 One of the values mentioned below returned from\r
1310 call to UpdateSymFile\r
1311 EFI_SUCCESS - The function completed successfully.\r
1312 EFI_INVALID_PARAMETER - One of the input parameters was invalid.\r
1313 EFI_ABORTED - An error occurred.UpdateSymFile\r
1314 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1315\r
1316--*/\r
1317{\r
1318 EFI_STATUS Status;\r
1319 UINT64 PalStartAddress;\r
1320 UINT64 AbsAddress;\r
1321 UINTN RelativeAddress;\r
1322 UINT64 FileSize;\r
1323 UINT64 NumByteRead;\r
1324 UINT8 *Buffer;\r
1325 FILE *Fp;\r
1326 FIT_TABLE *PalFitPtr;\r
1327\r
1328 Fp = fopen (VtfInfo->CompBinName, "rb");\r
1329\r
1330 if (Fp == NULL) {\r
1331 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);\r
1332 return EFI_ABORTED;\r
1333 }\r
1334\r
1335 FileSize = _filelength (fileno (Fp));\r
1336 if (FileSize < 64) {\r
1337 Error (NULL, 0, 2000, "Invalid parameter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");\r
1338 return EFI_INVALID_PARAMETER;\r
1339 }\r
1340 FileSize -= SIZE_OF_PAL_HEADER;\r
1341\r
1342\r
1343 if (VtfInfo->PreferredSize) {\r
1344 if (FileSize > VtfInfo->CompSize) {\r
1345 Error (NULL, 0, 2000, "Invalid parameter", "The PAL_A Size is more than the specified size.");\r
1346 return EFI_ABORTED;\r
1347 }\r
1348\r
1349 FileSize = VtfInfo->CompSize;\r
1350 }\r
1351\r
1352 Buffer = malloc ((UINTN) FileSize);\r
1353 if (Buffer == NULL) {\r
1354 return EFI_OUT_OF_RESOURCES;\r
1355 }\r
1356 memset (Buffer, 0, (UINTN) FileSize);\r
1357\r
1358 //\r
1359 // Read, Get version Info and discard the PAL header.\r
1360 //\r
1361 NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
1362\r
1363 //\r
1364 // Extract the version info from header of PAL_A. Once done, discrad this buffer\r
1365 //\r
1366 if (!VtfInfo->VersionPresent) {\r
1367 GetComponentVersionInfo (VtfInfo, Buffer);\r
1368 }\r
1369\r
1370 //\r
1371 // Read PAL_A file in a buffer\r
1372 //\r
1373 NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
1374 fclose (Fp);\r
1375\r
1376 PalStartAddress = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);\r
1377 Vtf1LastStartAddress = PalStartAddress;\r
1378 Vtf1TotalSize += (UINT32) FileSize;\r
1379 Status = UpdateVtfBuffer (PalStartAddress, Buffer, FileSize, FIRST_VTF);\r
1380\r
1381 AbsAddress = Fv1EndAddress - SIZE_TO_PAL_A_FIT;\r
1382 GetRelativeAddressInVtfBuffer (AbsAddress, &RelativeAddress, FIRST_VTF);\r
1383 PalFitPtr = (FIT_TABLE *) RelativeAddress;\r
1384 PalFitPtr->CompAddress = PalStartAddress | IPF_CACHE_BIT;\r
1385 //assert ((FileSize % 16) == 0);\r
1386 if ((FileSize % 16) != 0) {\r
1387 Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");\r
1388 return EFI_INVALID_PARAMETER;\r
1389 }\r
1390\r
1391 PalFitPtr->CompSize = (UINT32) (FileSize / 16);\r
1392 PalFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);\r
1393 PalFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);\r
1394 if (VtfInfo->CheckSumRequired) {\r
1395 PalFitPtr->CheckSum = 0;\r
1396 PalFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);\r
1397 }\r
1398\r
1399 if (Buffer) {\r
1400 free (Buffer);\r
1401 }\r
1402\r
1403 //\r
1404 // Update the SYM file for this component based on it's start address.\r
1405 //\r
b303ea72 1406 Status = UpdateSymFile (PalStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);\r
30fdf114
LG
1407 if (EFI_ERROR (Status)) {\r
1408\r
1409 //\r
1410 // At this time, SYM files are not required, so continue on error.\r
1411 //\r
1412 }\r
1413\r
1414 return Status;\r
1415}\r
1416\r
1417EFI_STATUS\r
1418CreateFitTableAndInitialize (\r
1419 IN PARSED_VTF_INFO *VtfInfo\r
1420 )\r
1421/*++\r
1422\r
1423Routine Description:\r
1424\r
1425 This function creates and intializes FIT table which would be used to\r
1426 add component info inside this\r
1427\r
1428Arguments:\r
1429\r
1430 VtfInfo - Pointer to Parsed Info\r
1431\r
1432Returns:\r
1433\r
1434 EFI_ABORTED - Aborted due to no size information\r
1435 EFI_SUCCESS - The function completed successfully\r
1436\r
1437--*/\r
1438{\r
1439 UINT64 PalFitTableAdd;\r
1440 UINT64 FitTableAdd;\r
1441 UINT64 FitTableAddressOffset;\r
1442 FIT_TABLE *PalFitPtr;\r
1443 FIT_TABLE *FitStartPtr;\r
1444 UINTN NumFitComp;\r
1445 UINTN RelativeAddress;\r
1446 UINTN Index;\r
1447\r
1448 if (!VtfInfo->PreferredSize) {\r
1449 Error (NULL, 0, 2000, "Invalid parameter", "FIT could not be allocated because there is no size information.");\r
1450 return EFI_ABORTED;\r
1451 }\r
1452\r
1453 if ((VtfInfo->CompSize % 16) != 0) {\r
1454 Error (NULL, 0, 2000, "Invalid parameter", "Invalid FIT Table Size, it is not a multiple of 16 bytes. Please correct the size.");\r
1455 }\r
1456\r
1457 PalFitTableAdd = Fv1EndAddress - SIZE_TO_PAL_A_FIT;\r
1458 GetRelativeAddressInVtfBuffer (PalFitTableAdd, &RelativeAddress, FIRST_VTF);\r
1459 PalFitPtr = (FIT_TABLE *) RelativeAddress;\r
1460 PalFitTableAdd = (PalFitPtr->CompAddress - VtfInfo->CompSize);\r
1461\r
1462 FitTableAdd = (PalFitPtr->CompAddress - 0x10) - VtfInfo->CompSize;\r
1463 FitTableAddressOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
1464 GetRelativeAddressInVtfBuffer (FitTableAddressOffset, &RelativeAddress, FIRST_VTF);\r
1465 *(UINT64 *) RelativeAddress = FitTableAdd;\r
1466\r
1467 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
1468\r
1469 //\r
1470 // Update Fit Table with FIT Signature and FIT info in first 16 bytes.\r
1471 //\r
1472 FitStartPtr = (FIT_TABLE *) RelativeAddress;\r
1473\r
1474 strncpy ((CHAR8 *) &FitStartPtr->CompAddress, FIT_SIGNATURE, 8); // "_FIT_ "\r
1475 assert (((VtfInfo->CompSize & 0x00FFFFFF) % 16) == 0);\r
1476 FitStartPtr->CompSize = (VtfInfo->CompSize & 0x00FFFFFF) / 16;\r
1477 FitStartPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);\r
1478\r
1479 //\r
1480 // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also\r
1481 // determine what to do for things like the FV component that aren't easily checksummed.\r
1482 // The checksum will be done once we are done with all the componet update in the FIT\r
1483 // table\r
1484 //\r
1485 FitStartPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);\r
1486\r
1487 NumFitComp = FitStartPtr->CompSize;\r
1488\r
1489 FitStartPtr++;\r
1490\r
1491 //\r
1492 // Intialize remaining FIT table space to UNUSED fit component type\r
1493 // so that when we need to create a FIT entry for a component, we can\r
1494 // locate a free one and use it.\r
1495 //\r
1496 for (Index = 0; Index < (NumFitComp - 1); Index++) {\r
1497 FitStartPtr->CvAndType = 0x7F; // Initialize all with UNUSED\r
1498 FitStartPtr++;\r
1499 }\r
1500\r
1501 Vtf1TotalSize += VtfInfo->CompSize;\r
1502 Vtf1LastStartAddress -= VtfInfo->CompSize;\r
1503\r
1504 return EFI_SUCCESS;\r
1505}\r
1506\r
1507EFI_STATUS\r
1508WriteVtfBinary (\r
1509 IN CHAR8 *FileName,\r
1510 IN UINT32 VtfSize,\r
1511 IN LOC_TYPE LocType\r
1512 )\r
1513/*++\r
1514\r
1515Routine Description:\r
1516\r
1517 Write Firmware Volume from memory to a file.\r
1518\r
1519Arguments:\r
1520\r
1521 FileName - Output File Name which needed to be created/\r
1522 VtfSize - FileSize\r
1523 LocType - The type of the VTF\r
1524\r
1525Returns:\r
1526\r
1527 EFI_ABORTED - Returned due to one of the following resons:\r
1528 (a) Error Opening File\r
1529 (b) Failing to copy buffers\r
1530 EFI_SUCCESS - The fuction completes successfully\r
1531\r
1532--*/\r
1533{\r
1534 FILE *Fp;\r
1535 UINTN NumByte;\r
1536 VOID *VtfBuffer;\r
1537 UINTN RelativeAddress;\r
1538\r
1539 if (LocType == FIRST_VTF) {\r
1540 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
1541 VtfBuffer = (VOID *) RelativeAddress;\r
1542 } else {\r
1543 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);\r
1544 VtfBuffer = (VOID *) RelativeAddress;\r
1545 }\r
1546\r
1547 Fp = fopen (FileName, "wb");\r
1548 if (Fp == NULL) {\r
1549 Error (NULL, 0, 0001, "Error opening file", FileName);\r
1550 return EFI_ABORTED;\r
1551 }\r
1552\r
1553 NumByte = fwrite (VtfBuffer, sizeof (UINT8), (UINTN) VtfSize, Fp);\r
1554\r
1555 if (Fp) {\r
1556 fclose (Fp);\r
1557 }\r
1558\r
1559 if (NumByte != (sizeof (UINT8) * VtfSize)) {\r
1560 Error (NULL, 0, 0002, "Error writing file", FileName);\r
1561 return EFI_ABORTED;\r
1562 }\r
1563\r
1564 return EFI_SUCCESS;\r
1565}\r
1566\r
1567EFI_STATUS\r
1568UpdateVtfBuffer (\r
1569 IN UINT64 StartAddress,\r
1570 IN UINT8 *Buffer,\r
1571 IN UINT64 DataSize,\r
1572 IN LOC_TYPE LocType\r
1573 )\r
1574/*++\r
1575\r
1576Routine Description:\r
1577\r
1578 Update the Firmware Volume Buffer with requested buffer data\r
1579\r
1580Arguments:\r
1581\r
1582 StartAddress - StartAddress in buffer. This number will automatically\r
1583 point to right address in buffer where data needed\r
1584 to be updated.\r
1585 Buffer - Buffer pointer from data will be copied to memory mapped buffer.\r
1586 DataSize - Size of the data needed to be copied.\r
1587 LocType - The type of the VTF: First or Second\r
1588\r
1589Returns:\r
1590\r
1591 EFI_ABORTED - The input parameter is error\r
1592 EFI_SUCCESS - The function completed successfully\r
1593\r
1594--*/\r
1595{\r
1596 UINT8 *LocalBufferPtrToWrite;\r
1597\r
1598 if (LocType == FIRST_VTF) {\r
1599 if ((StartAddress | IPF_CACHE_BIT) < (Vtf1LastStartAddress | IPF_CACHE_BIT)) {\r
1600 Error (NULL, 0, 2000, "Invalid parameter", "Start Address is less than the VTF start address.");\r
1601 return EFI_ABORTED;\r
1602 }\r
1603\r
1604 LocalBufferPtrToWrite = (UINT8 *) Vtf1EndBuffer;\r
1605\r
1606 LocalBufferPtrToWrite -= (Fv1EndAddress - StartAddress);\r
1607\r
1608 } else {\r
1609\r
1610 if ((StartAddress | IPF_CACHE_BIT) < (Vtf2LastStartAddress | IPF_CACHE_BIT)) {\r
1611 Error (NULL, 0, 2000, "Invalid parameter", "Error StartAddress");\r
1612 return EFI_ABORTED;\r
1613 }\r
1614 LocalBufferPtrToWrite = (UINT8 *) Vtf2EndBuffer;\r
1615 LocalBufferPtrToWrite -= (Fv2EndAddress - StartAddress);\r
1616 }\r
1617\r
1618 memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) DataSize);\r
1619\r
1620 return EFI_SUCCESS;\r
1621}\r
1622\r
1623EFI_STATUS\r
1624UpdateFfsHeader (\r
1625 IN UINT32 TotalVtfSize,\r
1626 IN LOC_TYPE LocType\r
1627 )\r
1628/*++\r
1629\r
1630Routine Description:\r
1631\r
1632 Update the Firmware Volume Buffer with requested buffer data\r
1633\r
1634Arguments:\r
1635\r
1636 TotalVtfSize - Size of the VTF\r
1637 Fileoffset - The start of the file relative to the start of the FV.\r
1638 LocType - The type of the VTF\r
1639\r
1640Returns:\r
1641\r
1642 EFI_SUCCESS - The function completed successfully\r
1643 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL\r
1644\r
1645--*/\r
1646{\r
1647 EFI_FFS_FILE_HEADER *FileHeader;\r
1648 UINTN RelativeAddress;\r
1649 EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;\r
1650\r
1651 //\r
1652 // Find the VTF file header location\r
1653 //\r
1654 if (LocType == FIRST_VTF) {\r
1655 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
1656 FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;\r
1657 } else {\r
1658 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);\r
1659 FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;\r
1660 }\r
1661\r
1662 if (FileHeader == NULL) {\r
1663 return EFI_INVALID_PARAMETER;\r
1664 }\r
1665\r
1666 //\r
1667 // write header\r
1668 //\r
1669 memset (FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
1670 memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID));\r
1671 FileHeader->Type = EFI_FV_FILETYPE_RAW;\r
1672 FileHeader->Attributes = FFS_ATTRIB_CHECKSUM;\r
1673\r
1674 //\r
1675 // Now FileSize includes the EFI_FFS_FILE_HEADER\r
1676 //\r
1677 FileHeader->Size[0] = (UINT8) (TotalVtfSize & 0x000000FF);\r
1678 FileHeader->Size[1] = (UINT8) ((TotalVtfSize & 0x0000FF00) >> 8);\r
1679 FileHeader->Size[2] = (UINT8) ((TotalVtfSize & 0x00FF0000) >> 16);\r
1680\r
1681 //\r
1682 // Fill in checksums and state, all three must be zero for the checksums.\r
1683 //\r
1684 FileHeader->IntegrityCheck.Checksum.Header = 0;\r
1685 FileHeader->IntegrityCheck.Checksum.File = 0;\r
1686 FileHeader->State = 0;\r
1687 FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
b303ea72 1688 FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) (FileHeader + 1), TotalVtfSize - sizeof (EFI_FFS_FILE_HEADER));\r
30fdf114
LG
1689 FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
1690\r
1691 return EFI_SUCCESS;\r
1692}\r
1693\r
1694EFI_STATUS\r
1695ValidateAddressAndSize (\r
1696 IN UINT64 BaseAddress,\r
1697 IN UINT64 FwVolSize\r
1698 )\r
1699/*++\r
1700\r
1701Routine Description:\r
1702\r
1703 Update the Firmware Volume Buffer with requested buffer data\r
1704\r
1705Arguments:\r
1706\r
1707 BaseAddress - Base address for the Fw Volume.\r
1708\r
1709 FwVolSize - Total Size of the FwVolume to which VTF will be attached..\r
1710\r
1711Returns:\r
1712\r
1713 EFI_SUCCESS - The function completed successfully\r
1714 EFI_UNSUPPORTED - The input parameter is error\r
1715\r
1716--*/\r
1717{\r
1718 if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {\r
1719 return EFI_SUCCESS;\r
1720 }\r
1721\r
1722 return EFI_UNSUPPORTED;\r
1723}\r
1724\r
1725EFI_STATUS\r
1726UpdateIA32ResetVector (\r
1727 IN CHAR8 *FileName,\r
1728 IN UINT64 FirstFwVSize\r
1729 )\r
1730/*++\r
1731\r
1732Routine Description:\r
1733\r
1734 Update the 16 byte IA32 Reset vector to maintain the compatibility\r
1735\r
1736Arguments:\r
1737\r
1738 FileName - Binary file name which contains the IA32 Reset vector info..\r
1739 FirstFwVSize - Total Size of the FwVolume to which VTF will be attached..\r
1740\r
1741Returns:\r
1742\r
1743 EFI_SUCCESS - The function completed successfully\r
1744 EFI_ABORTED - Invalid File Size\r
1745 EFI_INVALID_PARAMETER - Bad File Name\r
1746 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1747\r
1748--*/\r
1749{\r
1750 UINT8 *Buffer;\r
1751 UINT8 *LocalVtfBuffer;\r
1752 UINTN FileSize;\r
1753 UINTN NumByteRead;\r
1754 FILE *Fp;\r
1755\r
1756 if (!strcmp (FileName, "")) {\r
1757 return EFI_INVALID_PARAMETER;\r
1758 }\r
1759\r
1760 Fp = fopen (FileName, "rb");\r
1761\r
1762 if (Fp == NULL) {\r
1763 Error (NULL, 0, 0001, "Error opening file", FileName);\r
1764 return EFI_ABORTED;\r
1765 }\r
1766\r
1767 FileSize = _filelength (fileno (Fp));\r
1768\r
1769 if (FileSize > 16) {\r
1770 return EFI_ABORTED;\r
1771 }\r
1772\r
1773 Buffer = malloc (FileSize);\r
1774 if (Buffer == NULL) {\r
1775 return EFI_OUT_OF_RESOURCES;\r
1776 }\r
1777\r
1778 NumByteRead = fread (Buffer, sizeof (UINT8), FileSize, Fp);\r
1779\r
1780 LocalVtfBuffer = (UINT8 *) Vtf1EndBuffer - SIZE_IA32_RESET_VECT;\r
1781 memcpy (LocalVtfBuffer, Buffer, FileSize);\r
1782\r
1783 if (Buffer) {\r
1784 free (Buffer);\r
1785 }\r
1786\r
1787 if (Fp != NULL) {\r
1788 fclose (Fp);\r
1789 }\r
1790 return EFI_SUCCESS;\r
1791}\r
1792\r
1793VOID\r
1794CleanUpMemory (\r
1795 VOID\r
1796 )\r
1797/*++\r
1798\r
1799Routine Description:\r
1800\r
1801 This function cleans up any allocated buffer\r
1802\r
1803Arguments:\r
1804\r
1805 NONE\r
1806\r
1807Returns:\r
1808\r
1809 NONE\r
1810\r
1811--*/\r
1812{\r
1813 PARSED_VTF_INFO *TempFileListPtr;\r
1814\r
1815 if (Vtf1Buffer) {\r
1816 free (Vtf1Buffer);\r
1817 }\r
1818\r
1819 if (Vtf2Buffer) {\r
1820 free (Vtf2Buffer);\r
1821 }\r
1822\r
1823 //\r
1824 // Cleanup the buffer which was allocated to read the file names from FV.INF\r
1825 //\r
1826 FileListPtr = FileListHeadPtr;\r
1827 while (FileListPtr != NULL) {\r
1828 TempFileListPtr = FileListPtr->NextVtfInfo;\r
1829 free (FileListPtr);\r
1830 FileListPtr = TempFileListPtr;\r
1831 }\r
1832}\r
1833\r
1834EFI_STATUS\r
1835ProcessAndCreateVtf (\r
1836 IN UINT64 Size\r
1837 )\r
1838/*++\r
1839\r
1840Routine Description:\r
1841\r
1842 This function process the link list created during INF file parsing\r
1843 and create component in VTF and updates its info in FIT table\r
1844\r
1845Arguments:\r
1846\r
1847 Size - Size of the Firmware Volume of which, this VTF belongs to.\r
1848\r
1849Returns:\r
1850\r
1851 EFI_UNSUPPORTED - Unknown FIT type\r
1852 EFI_SUCCESS - The function completed successfully\r
1853\r
1854--*/\r
1855{\r
1856 EFI_STATUS Status;\r
1857 PARSED_VTF_INFO *ParsedInfoPtr;\r
1858\r
1859 Status = EFI_SUCCESS;\r
1860\r
1861 ParsedInfoPtr = FileListHeadPtr;\r
1862\r
1863 while (ParsedInfoPtr != NULL) {\r
1864\r
1865 switch (ParsedInfoPtr->CompType) {\r
1866 //\r
1867 // COMP_TYPE_FIT_HEADER is a special case, hence handle it here\r
1868 //\r
1869 case COMP_TYPE_FIT_HEADER:\r
1870 //COMP_TYPE_FIT_HEADER 0x00\r
1871 Status = CreateFitTableAndInitialize (ParsedInfoPtr);\r
1872 break;\r
1873\r
1874 //\r
1875 // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here\r
1876 //\r
1877 case COMP_TYPE_FIT_PAL_A:\r
1878 //COMP_TYPE_FIT_PAL_A 0x0F\r
1879 Status = CreateAndUpdatePAL_A (ParsedInfoPtr);\r
1880\r
1881 //\r
1882 // Based on VTF specification, once the PAL_A component has been written,\r
1883 // update the Firmware Volume info as FIT table. This will be utilized\r
1884 // to extract the Firmware Volume Start address where this VTF will be\r
1885 // of part.\r
1886 //\r
1887 if (Status == EFI_SUCCESS) {\r
1888 UpdateFitEntryForFwVolume (Size);\r
1889 }\r
1890 break;\r
1891\r
1892 case COMP_TYPE_FIT_FV_BOOT:\r
1893 //COMP_TYPE_FIT_FV_BOOT 0x7E\r
1894 //\r
1895 // Since FIT entry for Firmware Volume has been created and it is\r
1896 // located at (PAL_A start - 16 byte). So we will not process any\r
1897 // Firmware Volume related entry from INF file\r
1898 //\r
1899 Status = EFI_SUCCESS;\r
1900 break;\r
1901\r
1902 default:\r
1903 //\r
1904 // Any other component type should be handled here. This will create the\r
1905 // image in specified VTF and create appropriate entry about this\r
1906 // component in FIT Entry.\r
1907 //\r
1908 Status = CreateAndUpdateComponent (ParsedInfoPtr);\r
1909 if (EFI_ERROR (Status)) {\r
1910 Error (NULL, 0, 0002, "Error updating component", ParsedInfoPtr->CompName);\r
1911 return EFI_ABORTED;\r
1912 } else {\r
1913 break;}\r
1914 }\r
1915\r
1916 ParsedInfoPtr = ParsedInfoPtr->NextVtfInfo;\r
1917 }\r
1918 return Status;\r
1919}\r
1920\r
1921EFI_STATUS\r
1922GenerateVtfImage (\r
1923 IN UINT64 StartAddress1,\r
1924 IN UINT64 Size1,\r
1925 IN UINT64 StartAddress2,\r
1926 IN UINT64 Size2,\r
1927 IN FILE *fp\r
1928 )\r
1929/*++\r
1930\r
1931Routine Description:\r
1932\r
1933 This is the main function which will be called from application.\r
1934\r
1935Arguments:\r
1936\r
1937 StartAddress1 - The start address of the first VTF\r
1938 Size1 - The size of the first VTF\r
1939 StartAddress2 - The start address of the second VTF\r
1940 Size2 - The size of the second VTF\r
1941 fp - The pointer to BSF inf file\r
1942\r
1943Returns:\r
1944\r
1945 EFI_OUT_OF_RESOURCES - Can not allocate memory\r
1946 The return value can be any of the values\r
1947 returned by the calls to following functions:\r
1948 GetVtfRelatedInfoFromInfFile\r
1949 ProcessAndCreateVtf\r
1950 UpdateIA32ResetVector\r
1951 UpdateFfsHeader\r
1952 WriteVtfBinary\r
1953\r
1954--*/\r
1955{\r
1956 EFI_STATUS Status;\r
1957 FILE *VtfFP;\r
1958\r
1959 Status = EFI_UNSUPPORTED;\r
1960 VtfFP = fp;\r
1961\r
1962 if (StartAddress2 == 0) {\r
1963 SecondVTF = FALSE;\r
1964 } else {\r
1965 SecondVTF = TRUE;\r
1966 }\r
1967\r
1968 Fv1BaseAddress = StartAddress1;\r
1969 Fv1EndAddress = Fv1BaseAddress + Size1;\r
fd171542 1970 if (Fv1EndAddress != 0x100000000ULL || Size1 < 0x100000) {\r
30fdf114
LG
1971 Error (NULL, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");\r
1972 if (Size1 < 0x100000) {\r
1973 Error (NULL, 0, 2000, "Invalid parameter", "The FwVolumeSize must be larger than 1M!");\r
1974 } else if (SecondVTF != TRUE) {\r
1975 Error (NULL, 0, 2000, "Invalid parameter", "BaseAddress + FwVolumeSize must equal 0x100000000!");\r
1976 }\r
1977 Usage();\r
1978 return EFI_INVALID_PARAMETER;\r
1979 }\r
1980\r
1981 //\r
1982 // The image buffer for the First VTF\r
1983 //\r
1984 Vtf1Buffer = malloc ((UINTN) Size1);\r
1985 if (Vtf1Buffer == NULL) {\r
1986 Error (NULL, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");\r
1987 return EFI_OUT_OF_RESOURCES;\r
1988 }\r
1989 memset (Vtf1Buffer, 0x00, (UINTN) Size1);\r
1990 Vtf1EndBuffer = (UINT8 *) Vtf1Buffer + Size1;\r
1991 Vtf1LastStartAddress = Fv1EndAddress | IPF_CACHE_BIT;\r
1992\r
1993 if (SecondVTF) {\r
1994 Fv2BaseAddress = StartAddress2;\r
1995 Fv2EndAddress = Fv2BaseAddress + Size2;\r
1996 if (Fv2EndAddress != StartAddress1) {\r
1997 Error (NULL, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");\r
1998 if (SecondVTF == TRUE) {\r
1999 Error (NULL, 0, 2000, "Invalid parameter", "FirstBaseAddress + FirstFwVolumeSize must equal 0x100000000!");\r
2000 Error (NULL, 0, 2000, "Invalid parameter", "SecondBaseAddress + SecondFwVolumeSize must equal FirstBaseAddress!");\r
2001 }\r
2002 Usage();\r
2003 return EFI_INVALID_PARAMETER;\r
2004 }\r
2005\r
2006 //\r
2007 // The image buffer for the second VTF\r
2008 //\r
2009 Vtf2Buffer = malloc ((UINTN) Size2);\r
2010 if (Vtf2Buffer == NULL) {\r
2011 Error (NULL, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");\r
2012 return EFI_OUT_OF_RESOURCES;\r
2013 }\r
2014 memset (Vtf2Buffer, 0x00, (UINTN) Size2);\r
2015 Vtf2EndBuffer = (UINT8 *) Vtf2Buffer + Size2;\r
2016 Vtf2LastStartAddress = Fv2EndAddress | IPF_CACHE_BIT;\r
2017 }\r
2018\r
2019 Status = GetVtfRelatedInfoFromInfFile (VtfFP);\r
2020\r
2021 if (Status != EFI_SUCCESS) {\r
2022 Error (NULL, 0, 0003, "Error parsing file", "the input file.");\r
2023 CleanUpMemory ();\r
2024 return Status;\r
2025 }\r
2026\r
2027 Status = ProcessAndCreateVtf (Size1);\r
2028 if (Status != EFI_SUCCESS) {\r
2029 CleanUpMemory ();\r
2030 return Status;\r
2031 }\r
2032\r
2033 if (SectionOptionFlag) {\r
2034 Status = UpdateIA32ResetVector (IA32BinFile, Vtf1TotalSize);\r
2035 if (Status != EFI_SUCCESS) {\r
2036 CleanUpMemory ();\r
2037 return Status;\r
2038 }\r
2039 }\r
2040\r
2041 //\r
2042 // Re arrange the FIT Table for Ascending order of their FIT Type..\r
2043 //\r
2044 SortFitTable ();\r
2045\r
2046 //\r
2047 // All components have been updated in FIT table. Now perform the FIT table\r
2048 // checksum. The following function will check if Checksum is required,\r
2049 // if yes, then it will perform the checksum otherwise not.\r
2050 //\r
2051 CalculateFitTableChecksum ();\r
2052\r
2053 //\r
2054 // Write the FFS header\r
2055 //\r
2056 Vtf1TotalSize += sizeof (EFI_FFS_FILE_HEADER);\r
2057 Vtf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);\r
2058\r
2059 Status = UpdateFfsHeader (Vtf1TotalSize, FIRST_VTF);\r
2060 if (Status != EFI_SUCCESS) {\r
2061 CleanUpMemory ();\r
2062 return Status;\r
2063 }\r
2064 //\r
2065 // Update the VTF buffer into specified VTF binary file\r
2066 //\r
2067 Status = WriteVtfBinary (OutFileName1, Vtf1TotalSize, FIRST_VTF);\r
2068\r
2069 if (SecondVTF) {\r
2070 Vtf2TotalSize += sizeof (EFI_FFS_FILE_HEADER);\r
2071 Vtf2LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);\r
2072 Status = UpdateFfsHeader (Vtf2TotalSize, SECOND_VTF);\r
2073 if (Status != EFI_SUCCESS) {\r
2074 CleanUpMemory ();\r
2075 return Status;\r
2076 }\r
2077\r
2078 //\r
2079 // Update the VTF buffer into specified VTF binary file\r
2080 //\r
2081 Status = WriteVtfBinary (OutFileName2, Vtf2TotalSize, SECOND_VTF);\r
2082 }\r
2083\r
2084 CleanUpMemory ();\r
2085\r
2086 return Status;\r
2087}\r
2088\r
2089EFI_STATUS\r
2090PeimFixupInFitTable (\r
2091 IN UINT64 StartAddress\r
2092 )\r
2093/*++\r
2094\r
2095Routine Description:\r
2096\r
2097 This function is an entry point to fixup SAL-E entry point.\r
2098\r
2099Arguments:\r
2100\r
2101 StartAddress - StartAddress for PEIM.....\r
2102\r
2103Returns:\r
2104\r
2105 EFI_SUCCESS - The function completed successfully\r
2106 EFI_ABORTED - Error Opening File\r
2107 EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.\r
2108\r
2109--*/\r
2110{\r
2111 EFI_STATUS Status;\r
2112 FILE *Fp;\r
2113 UINT64 *StartAddressPtr;\r
2114 UINTN FirstFwVSize;\r
2115 UINTN NumByte;\r
2116\r
2117 StartAddressPtr = malloc (sizeof (UINT64));\r
2118 if (StartAddressPtr == NULL) {\r
2119 return EFI_OUT_OF_RESOURCES;\r
2120 }\r
2121 *StartAddressPtr = StartAddress;\r
2122\r
2123 Fp = fopen (OutFileName1, "rb");\r
2124\r
2125 if (Fp == NULL) {\r
2126 Error (NULL, 0, 0001, "Error opening file", OutFileName1);\r
2127 if (StartAddressPtr) {\r
2128 free (StartAddressPtr);\r
2129 }\r
2130 return EFI_ABORTED;\r
2131 }\r
2132\r
2133 FirstFwVSize = _filelength (fileno (Fp));\r
2134 fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);\r
2135 NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);\r
2136\r
2137 if (Fp) {\r
2138 fclose (Fp);\r
2139 }\r
2140\r
2141 if (StartAddressPtr) {\r
2142 free (StartAddressPtr);\r
2143 }\r
2144\r
2145 Status = EFI_SUCCESS;\r
2146 return Status;\r
2147}\r
2148\r
2149EFI_STATUS\r
2150UpdateSymFile (\r
2151 IN UINT64 BaseAddress,\r
2152 IN CHAR8 *DestFileName,\r
b303ea72
LG
2153 IN CHAR8 *SourceFileName,\r
2154 IN UINT64 FileSize\r
2155\r
30fdf114
LG
2156 )\r
2157/*++\r
2158\r
2159Routine Description:\r
2160\r
2161 This function adds the SYM tokens in the source file to the destination file.\r
2162 The SYM tokens are updated to reflect the base address.\r
2163\r
2164Arguments:\r
2165\r
2166 BaseAddress - The base address for the new SYM tokens.\r
2167 DestFileName - The destination file.\r
2168 SourceFileName - The source file.\r
b303ea72 2169 FileSize - Size of bin file.\r
30fdf114
LG
2170\r
2171Returns:\r
2172\r
2173 EFI_SUCCESS - The function completed successfully.\r
2174 EFI_INVALID_PARAMETER - One of the input parameters was invalid.\r
2175 EFI_ABORTED - An error occurred.\r
2176\r
2177--*/\r
2178{\r
2179 FILE *SourceFile;\r
2180 FILE *DestFile;\r
2181 CHAR8 Buffer[_MAX_PATH];\r
2182 CHAR8 Type[_MAX_PATH];\r
2183 CHAR8 Address[_MAX_PATH];\r
2184 CHAR8 Section[_MAX_PATH];\r
2185 CHAR8 Token[_MAX_PATH];\r
2186 CHAR8 BaseToken[_MAX_PATH];\r
2187 UINT64 TokenAddress;\r
b303ea72 2188 long StartLocation;\r
30fdf114
LG
2189\r
2190 //\r
2191 // Verify input parameters.\r
2192 //\r
2193 if (BaseAddress == 0 || DestFileName == NULL || SourceFileName == NULL) {\r
2194 return EFI_INVALID_PARAMETER;\r
2195 }\r
2196\r
2197 //\r
2198 // Open the source file\r
2199 //\r
2200 SourceFile = fopen (SourceFileName, "r");\r
2201 if (SourceFile == NULL) {\r
2202\r
2203 //\r
2204 // SYM files are not required.\r
2205 //\r
2206 return EFI_SUCCESS;\r
2207 }\r
2208\r
2209 //\r
2210 // Use the file name minus extension as the base for tokens\r
2211 //\r
2212 strcpy (BaseToken, SourceFileName);\r
2213 strtok (BaseToken, ". \t\n");\r
2214 strcat (BaseToken, "__");\r
2215\r
2216 //\r
2217 // Open the destination file\r
2218 //\r
2219 DestFile = fopen (DestFileName, "a+");\r
2220 if (DestFile == NULL) {\r
2221 fclose (SourceFile);\r
2222 Error (NULL, 0, 0001, "Error opening file", DestFileName);\r
2223 return EFI_ABORTED;\r
2224 }\r
2225\r
2226 //\r
2227 // If this is the beginning of the output file, write the symbol format info.\r
2228 //\r
2229 if (fseek (DestFile, 0, SEEK_END) != 0) {\r
2230 fclose (SourceFile);\r
2231 fclose (DestFile);\r
2232 Error (NULL, 0, 2000, "Invalid parameter", "not at the beginning of the output file.");\r
2233 return EFI_ABORTED;\r
2234 }\r
2235\r
2236 StartLocation = ftell (DestFile);\r
2237\r
2238 if (StartLocation == 0) {\r
2239 fprintf (DestFile, "TEXTSYM format | V1.0\n");\r
2240 } else if (StartLocation == -1) {\r
2241 fclose (SourceFile);\r
2242 fclose (DestFile);\r
2243 Error (NULL, 0, 2000, "Invalid parameter", "StartLocation error");\r
2244 return EFI_ABORTED;\r
2245 }\r
2246\r
2247 //\r
2248 // Read the first line\r
2249 //\r
2250 if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {\r
2251 Buffer[0] = 0;\r
2252 }\r
2253\r
2254 //\r
2255 // Make sure it matches the expected sym format\r
2256 //\r
2257 if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) {\r
2258 fclose (SourceFile);\r
2259 fclose (DestFile);\r
2260 Error (NULL, 0, 2000, "Invalid parameter", "The symbol file does not match the expected TEXTSYM format (V1.0.)");\r
2261 return EFI_ABORTED;\r
2262 }\r
2263\r
2264 //\r
2265 // Read in the file\r
2266 //\r
2267 while (feof (SourceFile) == 0) {\r
2268\r
2269 //\r
2270 // Read a line\r
2271 //\r
2272 if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) {\r
2273\r
2274 //\r
2275 // Get the token address\r
2276 //\r
2277 AsciiStringToUint64 (Address, TRUE, &TokenAddress);\r
b303ea72
LG
2278 if (TokenAddress > FileSize) {\r
2279 //\r
2280 // Symbol offset larger than FileSize. This Symbol can't be in Bin file. Don't print them.\r
2281 //\r
2282 break;\r
2283 }\r
30fdf114
LG
2284\r
2285 //\r
2286 // Add the base address, the size of the FFS file header and the size of the peim header.\r
2287 //\r
2288 TokenAddress += BaseAddress &~IPF_CACHE_BIT;\r
2289\r
b303ea72
LG
2290 fprintf (DestFile, "%s | %016llX | ", Type, (unsigned long long) TokenAddress);\r
2291 fprintf (DestFile, "%s | %s\n %s\n", Section, Token, BaseToken); \r
30fdf114
LG
2292 }\r
2293 }\r
2294\r
2295 fclose (SourceFile);\r
2296 fclose (DestFile);\r
2297 return EFI_SUCCESS;\r
2298}\r
2299\r
2300EFI_STATUS\r
2301CalculateFitTableChecksum (\r
2302 VOID\r
2303 )\r
2304/*++\r
2305\r
2306Routine Description:\r
2307\r
2308 This function will perform byte checksum on the FIT table, if the the checksum required\r
2309 field is set to CheckSum required. If the checksum is not required then checksum byte\r
2310 will have value as 0;.\r
2311\r
2312Arguments:\r
2313\r
2314 NONE\r
2315\r
2316Returns:\r
2317\r
2318 Status - Value returned by call to CalculateChecksum8 ()\r
2319 EFI_SUCCESS - The function completed successfully\r
2320\r
2321--*/\r
2322{\r
2323 FIT_TABLE *TmpFitPtr;\r
2324 UINT64 FitTableAdd;\r
2325 UINT64 FitTableAddOffset;\r
2326 UINTN RelativeAddress;\r
2327 UINTN Size;\r
2328\r
2329 //\r
2330 // Read the Fit Table address from Itanium-based address map.\r
2331 //\r
2332 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
2333\r
2334 //\r
2335 // Translate this Itanium-based address in terms of local buffer address which\r
2336 // contains the image for Boot Strapped File\r
2337 //\r
2338 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
2339 FitTableAdd = *(UINTN *) RelativeAddress;\r
2340\r
2341 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
2342\r
2343 TmpFitPtr = (FIT_TABLE *) RelativeAddress;\r
2344\r
2345 Size = TmpFitPtr->CompSize * 16;\r
2346\r
2347 if ((TmpFitPtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {\r
2348 TmpFitPtr->CheckSum = 0;\r
2349 TmpFitPtr->CheckSum = CalculateChecksum8 ((UINT8 *) TmpFitPtr, Size);\r
2350 } else {\r
2351 TmpFitPtr->CheckSum = 0;\r
2352 }\r
2353\r
2354 return EFI_SUCCESS;\r
2355}\r
2356\r
2357VOID\r
2358Version (\r
2359 VOID\r
2360 )\r
2361/*++\r
2362\r
2363Routine Description:\r
2364\r
2365 Displays the standard utility information to SDTOUT\r
2366\r
2367Arguments:\r
2368\r
2369 None\r
2370\r
2371Returns:\r
2372\r
2373 None\r
2374\r
2375--*/\r
2376{\r
2377 fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
2378}\r
2379\r
2380VOID\r
2381Usage (\r
2382 VOID\r
2383 )\r
2384/*++\r
2385\r
2386Routine Description:\r
2387\r
2388 Displays the utility usage syntax to STDOUT\r
2389\r
2390Arguments:\r
2391\r
2392 None\r
2393\r
2394Returns:\r
2395\r
2396 None\r
2397\r
2398--*/\r
2399{\r
2400 //\r
2401 // Summary usage\r
2402 //\r
2403 fprintf (stdout, "Usage: %s [options] <-f input_file> <-r BaseAddress> <-s FwVolumeSize>\n\n", UTILITY_NAME);\r
2404\r
2405 //\r
2406 // Copyright declaration\r
2407 //\r
52302d4d 2408 fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");\r
30fdf114
LG
2409 //\r
2410 // Details Option\r
2411 //\r
2412 fprintf (stdout, "Options:\n");\r
2413 fprintf (stdout, " -f Input_file, --filename Input_file\n\\r
2414 Input_file is name of the BS Image INF file\n");\r
2415 fprintf (stdout, " -r BaseAddress, --baseaddr BaseAddress\n\\r
2416 BaseAddress is the starting address of Firmware Volume\n\\r
2417 where Boot Strapped Image will reside.\n");\r
2418 fprintf (stdout, " -s FwVolumeSize, --size FwVolumeSize\n\\r
2419 FwVolumeSize is the size of Firmware Volume.\n");\r
2420 fprintf (stdout, " -o FileName, --output FileName\n\\r
2421 File will be created to store the ouput content.\n");\r
2422 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
2423 fprintf (stdout, " --version Show program's version number and exit.\n");\r
2424 fprintf (stdout, " -h, --help Show this help message and exit.\n");\r
2425 fprintf (stdout, " -q, --quiet Disable all messages except FATAL ERRORS.\n");\r
2426 fprintf (stdout, " -d, --debug [#, 0-9] Enable debug messages at level #.\n");\r
2427}\r
2428\r
2429int\r
2430main (\r
2431 IN int argc,\r
2432 IN char **argv\r
2433 )\r
2434/*++\r
2435\r
2436Routine Description:\r
2437\r
2438 This utility uses GenVtf.dll to build a Boot Strap File Image which will be\r
2439 part of firmware volume image.\r
2440\r
2441Arguments:\r
2442\r
2443 argc - The count of the parameters\r
2444 argv - The parameters\r
2445\r
2446\r
2447Returns:\r
2448\r
2449 0 - No error conditions detected.\r
2450 1 - One or more of the input parameters is invalid.\r
2451 2 - A resource required by the utility was unavailable.\r
2452 - Most commonly this will be memory allocation or file creation.\r
2453 3 - GenFvImage.dll could not be loaded.\r
2454 4 - Error executing the GenFvImage dll.\r
2455 5 - Now this tool does not support the IA32 platform\r
2456\r
2457--*/\r
2458{\r
2459 UINT8 Index;\r
2460 UINT64 StartAddress1;\r
2461 UINT64 StartAddress2;\r
2462 UINT64 FwVolSize1;\r
2463 UINT64 FwVolSize2;\r
2464 BOOLEAN FirstRoundO;\r
2465 BOOLEAN FirstRoundB;\r
2466 BOOLEAN FirstRoundS;\r
2467 EFI_STATUS Status;\r
2468 FILE *VtfFP;\r
2469 CHAR8 *VtfFileName;\r
2470\r
2471 SetUtilityName (UTILITY_NAME);\r
2472\r
2473 //\r
2474 // Initialize variables\r
2475 //\r
2476 StartAddress1 = 0;\r
2477 StartAddress2 = 0;\r
2478 FwVolSize1 = 0;\r
2479 FwVolSize2 = 0;\r
2480 FirstRoundB = TRUE;\r
2481 FirstRoundS = TRUE;\r
2482 FirstRoundO = TRUE;\r
2483 DebugMode = FALSE;\r
2484 OutFileName1 = NULL;\r
2485 OutFileName2 = NULL;\r
2486 VtfFP = NULL;\r
2487 DebugLevel = 0;\r
2488\r
2489 //\r
2490 // Verify the correct number of arguments\r
2491 //\r
2492 if (argc == 1) {\r
2493 Usage();\r
2494 return 0;\r
2495 }\r
2496\r
2497 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {\r
2498 Usage();\r
2499 return 0;\r
2500 }\r
2501\r
2502 if ((strcmp(argv[1], "--version") == 0)) {\r
2503 Version();\r
2504 return 0;\r
2505 }\r
2506\r
2507 //\r
2508 // Parse the command line arguments\r
2509 //\r
2510 for (Index = 1; Index < argc; Index += 2) {\r
2511 if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {\r
2512 if (argv[Index + 1] == NULL || argv[Index + 1][0] == '-') {\r
2513 Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");\r
2514 goto ERROR;\r
2515 }\r
2516 //\r
2517 // Get the output file name\r
2518 //\r
2519 VTF_OUTPUT = TRUE;\r
2520 if (FirstRoundO) {\r
2521 //\r
2522 // It's the first output file name\r
2523 //\r
2524 OutFileName1 = (CHAR8 *)argv[Index+1];\r
2525 FirstRoundO = FALSE;\r
2526 } else {\r
2527 //\r
2528 //It's the second output file name\r
2529 //\r
2530 OutFileName2 = (CHAR8 *)argv[Index+1];\r
2531 }\r
2532 continue;\r
2533 }\r
2534\r
2535 if ((stricmp (argv[Index], "-f") == 0) || (stricmp (argv[Index], "--filename") == 0)) {\r
2536 if (argv[Index + 1] == NULL || argv[Index + 1][0] == '-') {\r
2537 Error (NULL, 0, 1003, "Invalid option value", "BS Image INF file is missing for -f option");\r
2538 goto ERROR;\r
2539 }\r
2540 //\r
2541 // Get the input VTF file name\r
2542 //\r
2543 VtfFileName = argv[Index+1];\r
2544 VtfFP = fopen(VtfFileName, "rb");\r
2545 if (VtfFP == NULL) {\r
2546 Error (NULL, 0, 0001, "Error opening file", VtfFileName);\r
2547 goto ERROR;\r
2548 }\r
2549 continue;\r
2550 }\r
2551 \r
2552 if ((stricmp (argv[Index], "-r") == 0) || (stricmp (argv[Index], "--baseaddr") == 0)) {\r
2553 if (FirstRoundB) {\r
2554 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);\r
2555 FirstRoundB = FALSE;\r
2556 } else {\r
2557 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress2);\r
2558 }\r
2559 if (Status != EFI_SUCCESS) {\r
2560 Error (NULL, 0, 2000, "Invalid option value", "%s is Bad FV start address.", argv[Index + 1]);\r
2561 goto ERROR;\r
2562 } \r
2563 continue;\r
2564 }\r
2565\r
2566 if ((stricmp (argv[Index], "-s") == 0) || (stricmp (argv[Index], "--size") == 0)) {\r
2567 if (FirstRoundS) {\r
2568 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize1);\r
2569 FirstRoundS = FALSE;\r
2570 } else {\r
2571 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize2);\r
2572 SecondVTF = TRUE;\r
2573 }\r
2574\r
2575 if (Status != EFI_SUCCESS) {\r
2576 Error (NULL, 0, 2000, "Invalid option value", "%s is Bad FV size.", argv[Index + 1]);\r
2577 goto ERROR;\r
2578 }\r
2579 continue;\r
2580 }\r
2581\r
2582 if ((stricmp (argv[Index], "-v") == 0) || (stricmp (argv[Index], "--verbose") == 0)) {\r
2583 VerboseMode = TRUE;\r
2584 Index--;\r
2585 continue;\r
2586 }\r
2587\r
2588 if ((stricmp (argv[Index], "-q") == 0) || (stricmp (argv[Index], "--quiet") == 0)) {\r
2589 QuietMode = TRUE;\r
2590 Index--;\r
2591 continue;\r
2592 }\r
2593\r
2594 if ((stricmp (argv[Index], "-d") == 0) || (stricmp (argv[Index], "--debug") == 0)) {\r
2595 //\r
2596 // debug level specified\r
2597 //\r
2598 Status = AsciiStringToUint64(argv[Index + 1], FALSE, &DebugLevel);\r
2599 if (EFI_ERROR (Status)) {\r
2600 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[Index], argv[Index + 1]);\r
2601 goto ERROR;\r
2602 }\r
2603 if (DebugLevel > 9) {\r
2604 Error (NULL, 0, 2000, "Invalid option value", "Unrecognized argument %s.", argv[Index + 1]);\r
2605 goto ERROR;\r
2606 }\r
2607 if((DebugLevel <= 9) &&(DebugLevel >= 5)) {\r
2608 DebugMode = TRUE;\r
2609 } else {\r
2610 DebugMode = FALSE;\r
2611 }\r
2612 continue;\r
2613 }\r
2614\r
2615 Error (NULL, 0, 2000, "Invalid parameter", "Unrecognized argument %s.", argv[Index]);\r
2616 goto ERROR;\r
2617 }\r
2618\r
2619 if (VtfFP == NULL) {\r
2620 Error (NULL, 0, 2000, "Invalid parameter", "No BS Image INF file is specified");\r
2621 goto ERROR;\r
2622 }\r
2623\r
2624 if (FirstRoundB) {\r
2625 Error (NULL, 0, 2000, "Invalid parameter", "No FV base address is specified");\r
2626 goto ERROR;\r
2627 }\r
2628\r
2629 if (FirstRoundS) {\r
2630 Error (NULL, 0, 2000, "Invalid parameter", "No FV Size is specified");\r
2631 goto ERROR;\r
2632 }\r
2633 //\r
2634 // All Parameters has been parsed, now set the message print level\r
2635 //\r
2636 if (QuietMode) {\r
2637 SetPrintLevel(40);\r
2638 } else if (VerboseMode) {\r
2639 SetPrintLevel(15);\r
2640 } else if (DebugMode) {\r
2641 SetPrintLevel(DebugLevel);\r
2642 }\r
2643\r
2644 if (VerboseMode) {\r
2645 VerboseMsg("%s tool start.\n", UTILITY_NAME);\r
2646 }\r
2647\r
2648 if (VTF_OUTPUT == FALSE) {\r
2649 if (SecondVTF == TRUE) {\r
2650 OutFileName1 = VTF_OUTPUT_FILE1;\r
2651 OutFileName2 = VTF_OUTPUT_FILE2;\r
2652 } else {\r
2653 OutFileName1 = VTF_OUTPUT_FILE1;\r
2654 }\r
2655 SymFileName = VTF_SYM_FILE;\r
2656 } else {\r
2657 INTN OutFileNameLen = strlen(OutFileName1);\r
2658 INTN Index;\r
2659\r
2660 for (Index = OutFileNameLen; Index > 0; --Index) {\r
2661 if (OutFileName1[Index] == '/' || OutFileName1[Index] == '\\') {\r
2662 break;\r
2663 }\r
2664 }\r
2665 if (Index == 0) {\r
2666 SymFileName = VTF_SYM_FILE;\r
2667 } else {\r
2668 INTN SymFileNameLen = Index + 1 + strlen(VTF_SYM_FILE);\r
2669 SymFileName = malloc(SymFileNameLen + 1);\r
2670 memcpy(SymFileName, OutFileName1, Index + 1);\r
2671 memcpy(SymFileName + Index + 1, VTF_SYM_FILE, strlen(VTF_SYM_FILE));\r
2672 SymFileName[SymFileNameLen] = '\0';\r
2673 }\r
2674 if (DebugMode) {\r
2675 DebugMsg(UTILITY_NAME, 0, DebugLevel, SymFileName, NULL);\r
2676 }\r
2677 }\r
2678\r
2679 //\r
2680 // Call the GenVtfImage\r
2681 //\r
2682 if (DebugMode) {\r
2683 DebugMsg(UTILITY_NAME, 0, DebugLevel, "Start to generate the VTF image\n", NULL);\r
2684 }\r
2685 Status = GenerateVtfImage (StartAddress1, FwVolSize1, StartAddress2, FwVolSize2, VtfFP);\r
2686\r
2687 if (EFI_ERROR (Status)) {\r
2688 switch (Status) {\r
2689\r
2690 case EFI_INVALID_PARAMETER:\r
2691 Error (NULL, 0, 2000, "Invalid parameter", "Invalid parameter passed to GenVtf function.");\r
2692 break;\r
2693\r
2694 case EFI_ABORTED:\r
fd171542 2695 Error (NULL, 0, 3000, "Invalid", "Error detected while creating the file image.");\r
30fdf114
LG
2696 break;\r
2697\r
2698 case EFI_OUT_OF_RESOURCES:\r
2699 Error (NULL, 0, 4002, "Resource", "GenVtfImage function could not allocate required resources.");\r
2700 break;\r
2701\r
2702 case EFI_VOLUME_CORRUPTED:\r
fd171542 2703 Error (NULL, 0, 3000, "Invalid", "No base address was specified.");\r
30fdf114
LG
2704 break;\r
2705\r
2706 default:\r
fd171542 2707 Error (NULL, 0, 3000, "Invalid", "GenVtfImage function returned unknown status %x.", (int) Status );\r
30fdf114
LG
2708 break;\r
2709 }\r
2710 }\r
2711ERROR:\r
2712 if (VtfFP != NULL) {\r
2713 fclose (VtfFP);\r
2714 }\r
2715\r
2716 if (DebugMode) {\r
2717 DebugMsg(UTILITY_NAME, 0, DebugLevel, "VTF image generated successful\n", NULL);\r
2718 }\r
2719\r
2720 if (VerboseMode) {\r
2721 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());\r
2722 }\r
2723 return GetUtilityStatus();\r
2724}\r