]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
Clean up some data type mismatches.
[mirror_edk2.git] / Tools / Source / TianoTools / GenFdImage / GenFdImageDll.c
CommitLineData
d25c4bf0 1/*++\r
2Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved\r
3This software and associated documentation (if any) is furnished\r
4under a license and may only be used or copied in accordance\r
5with the terms of the license. Except as permitted by such\r
6license, no part of this software or documentation may be\r
7reproduced, stored in a retrieval system, or transmitted in any\r
8form or by any means without the express written consent of\r
9Intel Corporation.\r
10\r
11\r
12 Module Name: \r
13 GenFdImageDll.C\r
14\r
15 Abstarct:\r
16 This file contains the relevant functions required to complete\r
17 the API to generate Firmware Device\r
18--*/\r
19\r
20// GC_TODO: fix comment to add: Abstract:\r
21//\r
22// This tells the compiler to export the DLL functions\r
23//\r
24#define GEN_FD_IMAGE_EXPORTS\r
25\r
26#include <stdio.h>\r
27#include <stdlib.h>\r
28#include <string.h>\r
d25c4bf0 29#include <assert.h>\r
ce53a8c3 30\r
31#include <Common/UefiBaseTypes.h>\r
32\r
d25c4bf0 33#include "GenFdImage.h"\r
d25c4bf0 34#include "ParseInf.h"\r
35\r
36//\r
37// Global declaration\r
38//\r
39UINTN ValidLineNum = 0;\r
40\r
41UINTN NumFvFiles = 0;\r
42static UINT64 LastAddress = 0;\r
43\r
44CHAR8 **TokenStr;\r
45CHAR8 **OrgStrTokPtr;\r
46\r
47FDINFO *FdInfo;\r
48FDINFO *OrgFdInfoPtr;\r
49\r
50FVINFO **FvInfo;\r
51FVINFO **OrgFvInfoPtr;\r
52\r
53//\r
54// Global function declarations\r
55//\r
56EFI_STATUS\r
57BuildFirmwareDeviceBinaryFromFwVolumes (\r
58 IN UINT64 FvBaseAddress,\r
59 IN CHAR8 *FvFileName,\r
60 IN CHAR8 *FdFileName\r
61 );\r
62\r
63INTN\r
64CompareItems (\r
65 IN const VOID *Arg1,\r
66 IN const VOID *Arg2\r
67 )\r
68/*++\r
69Description:\r
70\r
71 This function is used by qsort to sort the Fv list based on FvBaseAddress\r
72\r
73Input:\r
74 Arg1\r
75 Arg2\r
76\r
77Return:\r
78\r
79 None\r
80--*/\r
81// GC_TODO: function comment is missing 'Routine Description:'\r
82// GC_TODO: function comment is missing 'Arguments:'\r
83// GC_TODO: function comment is missing 'Returns:'\r
84// GC_TODO: Arg1 - add argument and description to function comment\r
85// GC_TODO: Arg2 - add argument and description to function comment\r
86{\r
87 if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {\r
88 return 1;\r
89 } else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {\r
90 return -1;\r
91 } else {\r
92 return 0;\r
93 }\r
94}\r
95\r
96VOID\r
97BuildTokenList (\r
98 IN CHAR8 *Token\r
99 )\r
100/*++\r
101Description:\r
102\r
103 This function builds the token list in an array which will be parsed later\r
104\r
105Input:\r
106 Token String,\r
107\r
108Return:\r
109\r
110 None\r
111--*/\r
112// GC_TODO: function comment is missing 'Routine Description:'\r
113// GC_TODO: function comment is missing 'Arguments:'\r
114// GC_TODO: function comment is missing 'Returns:'\r
115// GC_TODO: Token - add argument and description to function comment\r
116{\r
117\r
118 strcpy (*TokenStr, Token);\r
119 TokenStr++;\r
120}\r
121\r
122VOID\r
123TrimLine (\r
124 IN CHAR8 *Line\r
125 )\r
126/*++\r
127Description:\r
128\r
129 This function cleans up the line by removing all whitespace and \r
130 comments\r
131\r
132Input:\r
133\r
134 Line String,\r
135\r
136Return:\r
137 None\r
138--*/\r
139// GC_TODO: function comment is missing 'Routine Description:'\r
140// GC_TODO: function comment is missing 'Arguments:'\r
141// GC_TODO: function comment is missing 'Returns:'\r
142// GC_TODO: Line - add argument and description to function comment\r
143{\r
144 CHAR8 TmpLine[FILE_NAME_SIZE];\r
145 CHAR8 c;\r
146 CHAR8 *Ptr0;\r
147 UINTN i;\r
148 UINTN j;\r
149\r
150 //\r
151 // Change '#' to '//' for Comment style\r
152 //\r
153 // if((Ptr0=strchr(Line, '#')) != NULL) {\r
154 //\r
155 if ((Ptr0 = strstr (Line, "//")) != NULL) {\r
156 Line[Ptr0 - Line] = 0;\r
157 }\r
158\r
159 i = j = 0;\r
160\r
161 while ((c = Line[i]) != 0) {\r
162 if ((c != ' ') && (c != '\t') && (c != '\n')) {\r
163 TmpLine[j++] = c;\r
164 }\r
165\r
166 i++;\r
167 }\r
168\r
169 TmpLine[j] = 0;\r
170 strcpy (Line, TmpLine);\r
171}\r
172\r
173VOID\r
174ValidLineCount (\r
175 IN FILE *Fp\r
176 )\r
177/*++\r
178\r
179Description:\r
180\r
181 This function calculated number of valid lines in a input file.\r
182 \r
183Input:\r
184\r
185 Fp Pointer to a file handle which has been opened.\r
186\r
187Return:\r
188\r
189 None\r
190--*/\r
191// GC_TODO: function comment is missing 'Routine Description:'\r
192// GC_TODO: function comment is missing 'Arguments:'\r
193// GC_TODO: function comment is missing 'Returns:'\r
194// GC_TODO: Fp - add argument and description to function comment\r
195{\r
196 CHAR8 Buff[FILE_NAME_SIZE];\r
197\r
198 while (fgets (Buff, sizeof (Buff), Fp)) {\r
199 TrimLine (Buff);\r
200 if (Buff[0] == 0) {\r
201 continue;\r
202 }\r
203\r
204 ValidLineNum++;\r
205 }\r
206}\r
207\r
208VOID\r
209ParseInputFile (\r
210 IN FILE *Fp\r
211 )\r
212/*++\r
213 \r
214Description:\r
215\r
216 This function parses the input file and tokenize the string\r
217 \r
218Input:\r
219\r
220 Fp Pointer to a file handle which has been opened.\r
221 \r
222Return:\r
223\r
224 None\r
225--*/\r
226// GC_TODO: function comment is missing 'Routine Description:'\r
227// GC_TODO: function comment is missing 'Arguments:'\r
228// GC_TODO: function comment is missing 'Returns:'\r
229// GC_TODO: Fp - add argument and description to function comment\r
230{\r
231 CHAR8 *Token;\r
232 CHAR8 Buff[FILE_NAME_SIZE];\r
233 CHAR8 OrgLine[FILE_NAME_SIZE];\r
234 CHAR8 Str[FILE_NAME_SIZE];\r
235 CHAR8 Delimit[] = "=";\r
236\r
237 while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
238 strcpy (OrgLine, Buff);\r
239 TrimLine (Buff);\r
240\r
241 if (Buff[0] == 0) {\r
242 continue;\r
243 }\r
244\r
245 Token = strtok (Buff, Delimit);\r
246\r
247 while (Token != NULL) {\r
248 strcpy (Str, Token);\r
249 BuildTokenList (Str);\r
250 Token = strtok (NULL, Delimit);\r
251 }\r
252 }\r
253}\r
254\r
255EFI_STATUS\r
256InitializeComps (\r
257 VOID\r
258 )\r
259/*++\r
260\r
261Description:\r
262\r
263 This function intializes the relevant global variable which is being\r
264 used to store the information retrieved from INF file.\r
265 \r
266Input:\r
267\r
268 None\r
269\r
270Return:\r
271\r
272 EFI_STATUS\r
273--*/\r
274// GC_TODO: function comment is missing 'Routine Description:'\r
275// GC_TODO: function comment is missing 'Arguments:'\r
276// GC_TODO: function comment is missing 'Returns:'\r
277// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
278// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
279// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
280// GC_TODO: EFI_SUCCESS - add return value to function comment\r
281{\r
282 UINTN Index;\r
283\r
284 FdInfo = malloc (sizeof (FDINFO));\r
285\r
286 if (FdInfo == NULL) {\r
287 return EFI_OUT_OF_RESOURCES;\r
288 }\r
289\r
290 OrgFdInfoPtr = FdInfo;\r
291\r
292 FvInfo = malloc (sizeof (int) * NumFvFiles);\r
293\r
294 if (FvInfo == NULL) {\r
295 return EFI_OUT_OF_RESOURCES;\r
296 }\r
297\r
298 OrgFvInfoPtr = FvInfo;\r
299\r
300 for (Index = 0; Index < NumFvFiles; Index++) {\r
301 *FvInfo = malloc (sizeof (FVINFO));\r
302\r
303 if (*FvInfo == NULL) {\r
304 return EFI_OUT_OF_RESOURCES;\r
305 }\r
306\r
307 memset (*FvInfo, 0, sizeof (FVINFO));\r
308 FvInfo++;\r
309 }\r
310\r
311 FvInfo = OrgFvInfoPtr;\r
312\r
313 return EFI_SUCCESS;\r
314}\r
315\r
316VOID\r
317InitializeInFileInfo (\r
318 VOID\r
319 )\r
320/*++\r
321\r
322Description:\r
323\r
324 This function intializes the relevant global variable which is being\r
325 used to store the information retrieved from INF file.\r
326\r
327Input:\r
328\r
329 NONE\r
330\r
331Return:\r
332\r
333 NONE\r
334--*/\r
335// GC_TODO: function comment is missing 'Routine Description:'\r
336// GC_TODO: function comment is missing 'Arguments:'\r
337// GC_TODO: function comment is missing 'Returns:'\r
338{\r
339 UINTN OptionFlag;\r
340 UINT64 StringValue;\r
341\r
342 OptionFlag = 0;\r
343 TokenStr = OrgStrTokPtr;\r
344\r
345 while (*TokenStr != NULL) {\r
346 if (stricmp (*TokenStr, "[options]") == 0) {\r
347 OptionFlag = 1;\r
348 }\r
349\r
350 if (OptionFlag) {\r
351 if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {\r
352 *TokenStr++;\r
353 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
354 printf ("\nERROR: Cannot determine the FV base address.");\r
355 return ;\r
356 }\r
357 (*FvInfo)->FvBaseAddress = StringValue;\r
358 } else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {\r
359 *TokenStr++;\r
360 strcpy ((*FvInfo)->FvFile, *TokenStr);\r
361 }\r
362 }\r
363\r
364 TokenStr++;\r
365 }\r
366}\r
367\r
368EFI_STATUS\r
369GetFvRelatedInfoFromInfFile (\r
370 IN CHAR8 *FileName\r
371 )\r
372/*++\r
373 \r
374Description:\r
375\r
376 This function reads the input file, parse it and create a list of tokens\r
377 which is parsed and used, to intialize the data related to Firmware Volume.\r
378 \r
379Input:\r
380\r
381 FileName FileName which needed to be read to parse data\r
382\r
383Return:\r
384\r
385 EFI_STATUS\r
386 \r
387--*/\r
388// GC_TODO: function comment is missing 'Routine Description:'\r
389// GC_TODO: function comment is missing 'Arguments:'\r
390// GC_TODO: function comment is missing 'Returns:'\r
391// GC_TODO: FileName - add argument and description to function comment\r
392// GC_TODO: EFI_ABORTED - add return value to function comment\r
393// GC_TODO: EFI_ABORTED - add return value to function comment\r
394// GC_TODO: EFI_SUCCESS - add return value to function comment\r
395{\r
396 FILE *Fp;\r
397 UINTN Index;\r
398\r
399 Fp = fopen (FileName, "r");\r
400\r
401 if (Fp == NULL) {\r
402 printf ("Error in opening %s file\n", FileName);\r
403 return EFI_ABORTED;\r
404 }\r
405\r
406 ValidLineCount (Fp);\r
407\r
408 if (ValidLineNum == 0) {\r
409 printf ("\nFile doesn't contain any valid informations");\r
410 return EFI_ABORTED;\r
411 }\r
412\r
413 TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));\r
414 memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));\r
415 OrgStrTokPtr = TokenStr;\r
416\r
417 for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
418 *TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
419 memset (*TokenStr, 0, FILE_NAME_SIZE);\r
420 TokenStr++;\r
421 }\r
422\r
423 *TokenStr = NULL;\r
424 TokenStr = OrgStrTokPtr;\r
425 fseek (Fp, 0L, SEEK_SET);\r
426\r
427 ParseInputFile (Fp);\r
428 InitializeInFileInfo ();\r
429\r
430 if (Fp) {\r
431 fclose (Fp);\r
432 }\r
433\r
434 return EFI_SUCCESS;\r
435}\r
436\r
437EFI_STATUS\r
438WriteFwBinary (\r
439 IN CHAR8 *FileName,\r
440 IN UINT64 StartAddress,\r
441 IN UINT64 Size,\r
442 IN UINT8 *Buffer\r
443 )\r
444/*++\r
445 \r
446Description:\r
447\r
448 This function reads the input file, parse it and create a list of tokens\r
449 which is parsed and used, to intialize the data related to Firmware Volume.\r
450 \r
451Input:\r
452\r
453 FileName FileName which needed to be read to parse data\r
454 StartAddress This will set the file position.\r
455 Size Size in bytes needed to be written\r
456 Buffer Buffer needed to e written\r
457\r
458Return:\r
459\r
460 EFI_STATUS\r
461 \r
462--*/\r
463// GC_TODO: function comment is missing 'Routine Description:'\r
464// GC_TODO: function comment is missing 'Arguments:'\r
465// GC_TODO: function comment is missing 'Returns:'\r
466// GC_TODO: FileName - add argument and description to function comment\r
467// GC_TODO: StartAddress - add argument and description to function comment\r
468// GC_TODO: Size - add argument and description to function comment\r
469// GC_TODO: Buffer - add argument and description to function comment\r
470// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
471// GC_TODO: EFI_ABORTED - add return value to function comment\r
472// GC_TODO: EFI_SUCCESS - add return value to function comment\r
473{\r
474 FILE *Fp;\r
475 UINTN NumByte;\r
476\r
477 Fp = fopen (FileName, "a+b");\r
478\r
479 if (Fp == NULL) {\r
480 printf ("\nERROR:Error in opening file %s ", FileName);\r
481 return EFI_INVALID_PARAMETER;\r
482 }\r
483\r
484 fseek (Fp, (UINTN) StartAddress, SEEK_SET);\r
485 NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);\r
486\r
487 //\r
488 // Check to ensure that buffer has been copied successfully\r
489 //\r
490 if (NumByte != Size) {\r
491 printf ("\nERROR: Error in copying the buffer into file");\r
492 return EFI_ABORTED;\r
493 }\r
494\r
495 if (Fp) {\r
496 fclose (Fp);\r
497 }\r
498\r
499 return EFI_SUCCESS;\r
500}\r
501\r
502EFI_STATUS\r
503BuildFirmwareDeviceBinaryFromFwVolumes (\r
504 IN UINT64 FvBaseAddress,\r
505 IN CHAR8 *FvFileName,\r
506 IN CHAR8 *FdFileName\r
507 )\r
508/*++\r
509 \r
510Description:\r
511\r
512 This function reads the input file, parse it and create a list of tokens\r
513 which is parsed and used, to intialize the data related to Firmware Volume.\r
514 \r
515Input:\r
516\r
517 FvBaseAddress Base Address. This info is retrieved from INF file\r
518 FvFileName InputFileName\r
519 FdFileName Output File Name\r
520\r
521Return:\r
522\r
523 EFI_STATUS\r
524 \r
525--*/\r
526// GC_TODO: function comment is missing 'Routine Description:'\r
527// GC_TODO: function comment is missing 'Arguments:'\r
528// GC_TODO: function comment is missing 'Returns:'\r
529// GC_TODO: FvBaseAddress - add argument and description to function comment\r
530// GC_TODO: FvFileName - add argument and description to function comment\r
531// GC_TODO: FdFileName - add argument and description to function comment\r
532// GC_TODO: EFI_ABORTED - add return value to function comment\r
533// GC_TODO: EFI_ABORTED - add return value to function comment\r
534// GC_TODO: EFI_ABORTED - add return value to function comment\r
535// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
536// GC_TODO: EFI_SUCCESS - add return value to function comment\r
537{\r
538 FILE *Fp;\r
539 UINT64 FileSize;\r
540 UINT64 NumByteRead;\r
541 UINT64 PadByteSize;\r
542 UINTN Index;\r
543 UINT64 BaseAddress;\r
544 UINT8 *Buffer;\r
545 EFI_STATUS Status;\r
546 static UINT64 StartAddress = 0;\r
547\r
548 Fp = fopen (FvFileName, "r+b");\r
549\r
550 if (Fp == NULL) {\r
551 printf ("\nERROR:Error in opening file %s", FvFileName);\r
552 return EFI_ABORTED;\r
553 }\r
554\r
555 BaseAddress = FdInfo->FdBaseAddress;\r
556\r
557 //\r
558 // Check if Base Address of Firmware Volume falls below the Base Address\r
559 // Firmware Device, if yes, then abort this process.\r
560 //\r
561 if (FvBaseAddress < BaseAddress) {\r
562 printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");\r
563 return EFI_ABORTED;\r
564 }\r
565 //\r
566 // Check if there are any hole between two Firmware Volumes. If any hole\r
567 // exists, fill the hole with PadByte data.\r
568 //\r
569 if (FvBaseAddress > LastAddress) {\r
570 PadByteSize = (FvBaseAddress - LastAddress);\r
571 Buffer = malloc ((UINTN) PadByteSize);\r
572\r
573 for (Index = 0; Index < PadByteSize; Index++) {\r
574 *Buffer = FdInfo->PadValue;\r
575 Buffer++;\r
576 }\r
577\r
578 Buffer -= PadByteSize;\r
579 Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);\r
580\r
581 if (Buffer) {\r
582 free (Buffer);\r
583 }\r
584\r
585 if (Status != EFI_SUCCESS) {\r
586 printf ("\nERROR: Error in writing the binary image to file");\r
587 return Status;\r
588 }\r
589\r
590 StartAddress += PadByteSize;\r
591 LastAddress += PadByteSize;\r
592 }\r
593 //\r
594 // Proceed with next Firmware Volume updates\r
595 //\r
596 FileSize = _filelength (fileno (Fp));\r
597\r
598 if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {\r
599 printf (\r
600 "\nERROR:Unable to update Firmware Device. File %s is larger than \\r
601 available space.",\r
602 FvFileName\r
603 );\r
604 if (Fp) {\r
605 fclose (Fp);\r
606 }\r
607\r
608 return EFI_ABORTED;\r
609 }\r
610\r
611 Buffer = malloc ((UINTN) FileSize);\r
612\r
613 if (Buffer == NULL) {\r
614 printf ("Error in allocating buffer to read specific file\n");\r
615 return EFI_OUT_OF_RESOURCES;\r
616 }\r
617\r
618 NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
619\r
620 Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);\r
621\r
622 if (Buffer) {\r
623 free ((VOID *) Buffer);\r
624 }\r
625\r
626 if (Fp) {\r
627 fclose (Fp);\r
628 }\r
629\r
630 if (Status != EFI_SUCCESS) {\r
631 printf ("\nERROR: Error in writing the binary image to file");\r
632 return Status;\r
633 }\r
634\r
635 StartAddress += NumByteRead;\r
636 LastAddress += FileSize;\r
637\r
638 return EFI_SUCCESS;\r
639}\r
640\r
641VOID\r
642CleanUpMemory (\r
643 VOID\r
644 )\r
645/*++\r
646\r
647Description:\r
648\r
649 This function cleans up any allocated buffer\r
650 \r
651Input:\r
652\r
653 NONE\r
654\r
655Return:\r
656 \r
657 NONE\r
658--*/\r
659// GC_TODO: function comment is missing 'Routine Description:'\r
660// GC_TODO: function comment is missing 'Arguments:'\r
661// GC_TODO: function comment is missing 'Returns:'\r
662{\r
663 UINTN Index;\r
664\r
665 if (FdInfo) {\r
666 free (FdInfo);\r
667 }\r
668\r
669 FvInfo = OrgFvInfoPtr;\r
670\r
671 if (FvInfo) {\r
672 for (Index = 0; Index < NumFvFiles; Index++) {\r
673 if (*FvInfo) {\r
674 free (*FvInfo);\r
675 }\r
676\r
677 FvInfo++;\r
678 }\r
679\r
680 FvInfo = OrgFvInfoPtr;\r
681 free (FvInfo);\r
682 }\r
683}\r
684\r
685GEN_FD_IMAGE_API\r
686EFI_STATUS\r
687GenerateFdImage (\r
688 IN UINT64 BaseAddress,\r
689 IN UINT64 Size,\r
690 IN UINT8 PadByte,\r
691 IN CHAR8 *OutFile,\r
692 IN CHAR8 **FileList\r
693 )\r
694/*++\r
695 \r
696Description:\r
697\r
698 This function reads the input file, parse it and create a list of tokens\r
699 which is parsed and used, to intialize the data related to Firmware Volume.\r
700 \r
701Input:\r
702\r
703 BaseAddress Base Address for this Firmware Device\r
704 Size, Total Size of the Firmware Device\r
705 PadByte Pad byte data\r
706 OutFile Output File Name\r
707 FileList File List pointer to INF file names.\r
708\r
709Return:\r
710\r
711 EFI_STATUS\r
712 \r
713--*/\r
714// GC_TODO: function comment is missing 'Routine Description:'\r
715// GC_TODO: function comment is missing 'Arguments:'\r
716// GC_TODO: function comment is missing 'Returns:'\r
717// GC_TODO: BaseAddress - add argument and description to function comment\r
718// GC_TODO: Size - add argument and description to function comment\r
719// GC_TODO: PadByte - add argument and description to function comment\r
720// GC_TODO: OutFile - add argument and description to function comment\r
721// GC_TODO: FileList - add argument and description to function comment\r
722// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
723// GC_TODO: EFI_ABORTED - add return value to function comment\r
724// GC_TODO: EFI_ABORTED - add return value to function comment\r
725// GC_TODO: EFI_SUCCESS - add return value to function comment\r
726{\r
727 EFI_STATUS Status;\r
728 UINTN Index;\r
729 UINTN PadSize;\r
730 UINTN FileSize;\r
731 CHAR8 **InFile;\r
732 FILE *Fp;\r
733 UINT8 *Buffer;\r
734 UINTN NumByte;\r
735\r
736 //\r
737 // Ensure, if there are any previous Firmware Device exists,\r
738 // If yes, make it to 0 bytes\r
739 //\r
740 if ((Fp = fopen (OutFile, "w")) != NULL) {\r
741 fclose (Fp);\r
742 }\r
743\r
744 InFile = FileList;\r
745\r
746 while (*InFile != NULL) {\r
747 NumFvFiles++;\r
748 InFile++;\r
749 }\r
750\r
751 InitializeComps ();\r
752\r
753 //\r
754 // Restore the orginal pointers\r
755 //\r
756 FvInfo = OrgFvInfoPtr;\r
757 InFile = FileList;\r
758\r
759 while (*InFile != NULL) {\r
760 strcpy ((*FvInfo)->FvInfoFile, *InFile);\r
761 Status = GetFvRelatedInfoFromInfFile (*InFile);\r
762\r
763 if (Status != EFI_SUCCESS) {\r
764 printf ("\nERROR: Error occurred in processsing INF file");\r
765 CleanUpMemory ();\r
766 return Status;\r
767 }\r
768\r
769 InFile++;\r
770 FvInfo++;\r
771 }\r
772\r
773 FdInfo->FdSize = Size;\r
774 FdInfo->FdBaseAddress = BaseAddress;\r
775 FdInfo->PadValue = PadByte;\r
776 FvInfo = OrgFvInfoPtr;\r
777 strcpy (FdInfo->OutFileName, OutFile);\r
778\r
779 for (Index = 0; Index < NumFvFiles; Index++) {\r
780 Status = GenerateFvImage ((*FvInfo)->FvInfoFile);\r
781\r
782 if (Status != EFI_SUCCESS) {\r
783 CleanUpMemory ();\r
784 return Status;\r
785 }\r
786\r
787 FvInfo++;\r
788 }\r
789\r
790 FvInfo = OrgFvInfoPtr;\r
791\r
792 //\r
793 // Sort the Firmware Volume informations. Firmware Volume with lower\r
794 // base addresses will be processed first and hiher base address one\r
795 // will be processed later.\r
796 //\r
797 qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);\r
798\r
799 LastAddress = (*FvInfo)->FvBaseAddress;\r
800\r
801 for (Index = 0; Index < NumFvFiles; Index++) {\r
802 Status = BuildFirmwareDeviceBinaryFromFwVolumes (\r
803 (*FvInfo)->FvBaseAddress,\r
804 (*FvInfo)->FvFile,\r
805 FdInfo->OutFileName\r
806 );\r
807 if (Status != EFI_SUCCESS) {\r
808 CleanUpMemory ();\r
809 return Status;\r
810 }\r
811\r
812 FvInfo++;\r
813 }\r
814 //\r
815 // Check if any space left after copying data from all Firmware Volumes\r
816 // If yes, then fill those location with PadValue.\r
817 //\r
818 if ((FdInfo->FdBaseAddress + Size) > LastAddress) {\r
819\r
820 PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);\r
821 Buffer = malloc (PadSize);\r
822\r
823 if (Buffer == NULL) {\r
824 CleanUpMemory ();\r
825 return EFI_OUT_OF_RESOURCES;\r
826 }\r
827\r
828 for (Index = 0; Index < PadSize; Index++) {\r
829 *Buffer = FdInfo->PadValue;\r
830 Buffer++;\r
831 }\r
832\r
833 Buffer -= PadSize;\r
834\r
835 Fp = fopen (OutFile, "a+b");\r
836\r
837 if (Fp == NULL) {\r
838 printf ("\nERROR:Opening file %s", OutFile);\r
839 CleanUpMemory ();\r
840 return EFI_ABORTED;\r
841 }\r
842\r
843 FileSize = _filelength (fileno (Fp));\r
844 fseek (Fp, FileSize, SEEK_SET);\r
845 NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);\r
846\r
847 if (Buffer) {\r
848 free (Buffer);\r
849 }\r
850\r
851 fclose (Fp);\r
852\r
853 if (NumByte != (sizeof (UINT8) * PadSize)) {\r
854 printf ("\nERROR: Copying data from buffer to File %s ", OutFile);\r
855 CleanUpMemory ();\r
856 return EFI_ABORTED;\r
857 }\r
858 }\r
859 //\r
860 // Clean up all the memory which has been allocated so far.\r
861 //\r
862 CleanUpMemory ();\r
863 return EFI_SUCCESS;\r
864}\r