]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
ff78aee18d433f3f2324967baf0d8d708199419a
2 Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
3 This software and associated documentation (if any) is furnished
4 under a license and may only be used or copied in accordance
5 with the terms of the license. Except as permitted by such
6 license, no part of this software or documentation may be
7 reproduced, stored in a retrieval system, or transmitted in any
8 form or by any means without the express written consent of
16 This file contains the relevant functions required to complete
17 the API to generate Firmware Device
20 // GC_TODO: fix comment to add: Abstract:
22 // This tells the compiler to export the DLL functions
24 #define GEN_FD_IMAGE_EXPORTS
31 #include "UefiBaseTypes.h"
33 #include "GenFdImage.h"
34 // #include "GenFvImage.h"
40 UINTN ValidLineNum
= 0;
43 static UINT64 LastAddress
= 0;
52 FVINFO
**OrgFvInfoPtr
;
55 // Global function declarations
58 BuildFirmwareDeviceBinaryFromFwVolumes (
59 IN UINT64 FvBaseAddress
,
72 This function is used by qsort to sort the Fv list based on FvBaseAddress
82 // GC_TODO: function comment is missing 'Routine Description:'
83 // GC_TODO: function comment is missing 'Arguments:'
84 // GC_TODO: function comment is missing 'Returns:'
85 // GC_TODO: Arg1 - add argument and description to function comment
86 // GC_TODO: Arg2 - add argument and description to function comment
88 if ((*(FVINFO
**) Arg1
)->FvBaseAddress
> (*(FVINFO
**) Arg2
)->FvBaseAddress
) {
90 } else if ((*(FVINFO
**) Arg1
)->FvBaseAddress
< (*(FVINFO
**) Arg2
)->FvBaseAddress
) {
104 This function builds the token list in an array which will be parsed later
113 // GC_TODO: function comment is missing 'Routine Description:'
114 // GC_TODO: function comment is missing 'Arguments:'
115 // GC_TODO: function comment is missing 'Returns:'
116 // GC_TODO: Token - add argument and description to function comment
119 strcpy (*TokenStr
, Token
);
130 This function cleans up the line by removing all whitespace and
140 // GC_TODO: function comment is missing 'Routine Description:'
141 // GC_TODO: function comment is missing 'Arguments:'
142 // GC_TODO: function comment is missing 'Returns:'
143 // GC_TODO: Line - add argument and description to function comment
145 CHAR8 TmpLine
[FILE_NAME_SIZE
];
152 // Change '#' to '//' for Comment style
154 // if((Ptr0=strchr(Line, '#')) != NULL) {
156 if ((Ptr0
= strstr (Line
, "//")) != NULL
) {
157 Line
[Ptr0
- Line
] = 0;
162 while ((c
= Line
[i
]) != 0) {
163 if ((c
!= ' ') && (c
!= '\t') && (c
!= '\n')) {
171 strcpy (Line
, TmpLine
);
182 This function calculated number of valid lines in a input file.
186 Fp Pointer to a file handle which has been opened.
192 // GC_TODO: function comment is missing 'Routine Description:'
193 // GC_TODO: function comment is missing 'Arguments:'
194 // GC_TODO: function comment is missing 'Returns:'
195 // GC_TODO: Fp - add argument and description to function comment
197 CHAR8 Buff
[FILE_NAME_SIZE
];
199 while (fgets (Buff
, sizeof (Buff
), Fp
)) {
217 This function parses the input file and tokenize the string
221 Fp Pointer to a file handle which has been opened.
227 // GC_TODO: function comment is missing 'Routine Description:'
228 // GC_TODO: function comment is missing 'Arguments:'
229 // GC_TODO: function comment is missing 'Returns:'
230 // GC_TODO: Fp - add argument and description to function comment
233 CHAR8 Buff
[FILE_NAME_SIZE
];
234 CHAR8 OrgLine
[FILE_NAME_SIZE
];
235 CHAR8 Str
[FILE_NAME_SIZE
];
236 CHAR8 Delimit
[] = "=";
238 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
239 strcpy (OrgLine
, Buff
);
246 Token
= strtok (Buff
, Delimit
);
248 while (Token
!= NULL
) {
250 BuildTokenList (Str
);
251 Token
= strtok (NULL
, Delimit
);
264 This function intializes the relevant global variable which is being
265 used to store the information retrieved from INF file.
275 // GC_TODO: function comment is missing 'Routine Description:'
276 // GC_TODO: function comment is missing 'Arguments:'
277 // GC_TODO: function comment is missing 'Returns:'
278 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
279 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
280 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
281 // GC_TODO: EFI_SUCCESS - add return value to function comment
285 FdInfo
= malloc (sizeof (FDINFO
));
287 if (FdInfo
== NULL
) {
288 return EFI_OUT_OF_RESOURCES
;
291 OrgFdInfoPtr
= FdInfo
;
293 FvInfo
= malloc (sizeof (int) * NumFvFiles
);
295 if (FvInfo
== NULL
) {
296 return EFI_OUT_OF_RESOURCES
;
299 OrgFvInfoPtr
= FvInfo
;
301 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
302 *FvInfo
= malloc (sizeof (FVINFO
));
304 if (*FvInfo
== NULL
) {
305 return EFI_OUT_OF_RESOURCES
;
308 memset (*FvInfo
, 0, sizeof (FVINFO
));
312 FvInfo
= OrgFvInfoPtr
;
318 InitializeInFileInfo (
325 This function intializes the relevant global variable which is being
326 used to store the information retrieved from INF file.
336 // GC_TODO: function comment is missing 'Routine Description:'
337 // GC_TODO: function comment is missing 'Arguments:'
338 // GC_TODO: function comment is missing 'Returns:'
344 TokenStr
= OrgStrTokPtr
;
346 while (*TokenStr
!= NULL
) {
347 if (stricmp (*TokenStr
, "[options]") == 0) {
352 if (stricmp (*TokenStr
, "EFI_FV_BASE_ADDRESS") == 0) {
354 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
355 printf ("\nERROR: Cannot determine the FV base address.");
358 (*FvInfo
)->FvBaseAddress
= StringValue
;
359 } else if (stricmp (*TokenStr
, "EFI_FV_FILE_NAME") == 0) {
361 strcpy ((*FvInfo
)->FvFile
, *TokenStr
);
370 GetFvRelatedInfoFromInfFile (
377 This function reads the input file, parse it and create a list of tokens
378 which is parsed and used, to intialize the data related to Firmware Volume.
382 FileName FileName which needed to be read to parse data
389 // GC_TODO: function comment is missing 'Routine Description:'
390 // GC_TODO: function comment is missing 'Arguments:'
391 // GC_TODO: function comment is missing 'Returns:'
392 // GC_TODO: FileName - add argument and description to function comment
393 // GC_TODO: EFI_ABORTED - add return value to function comment
394 // GC_TODO: EFI_ABORTED - add return value to function comment
395 // GC_TODO: EFI_SUCCESS - add return value to function comment
400 Fp
= fopen (FileName
, "r");
403 printf ("Error in opening %s file\n", FileName
);
409 if (ValidLineNum
== 0) {
410 printf ("\nFile doesn't contain any valid informations");
414 TokenStr
= (CHAR8
**) malloc (sizeof (UINTN
) * (2 * ValidLineNum
));
415 memset (TokenStr
, 0, sizeof (UINTN
) * (2 * ValidLineNum
));
416 OrgStrTokPtr
= TokenStr
;
418 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
419 *TokenStr
= (CHAR8
*) malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
420 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
425 TokenStr
= OrgStrTokPtr
;
426 fseek (Fp
, 0L, SEEK_SET
);
429 InitializeInFileInfo ();
441 IN UINT64 StartAddress
,
449 This function reads the input file, parse it and create a list of tokens
450 which is parsed and used, to intialize the data related to Firmware Volume.
454 FileName FileName which needed to be read to parse data
455 StartAddress This will set the file position.
456 Size Size in bytes needed to be written
457 Buffer Buffer needed to e written
464 // GC_TODO: function comment is missing 'Routine Description:'
465 // GC_TODO: function comment is missing 'Arguments:'
466 // GC_TODO: function comment is missing 'Returns:'
467 // GC_TODO: FileName - add argument and description to function comment
468 // GC_TODO: StartAddress - add argument and description to function comment
469 // GC_TODO: Size - add argument and description to function comment
470 // GC_TODO: Buffer - add argument and description to function comment
471 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
472 // GC_TODO: EFI_ABORTED - add return value to function comment
473 // GC_TODO: EFI_SUCCESS - add return value to function comment
478 Fp
= fopen (FileName
, "a+b");
481 printf ("\nERROR:Error in opening file %s ", FileName
);
482 return EFI_INVALID_PARAMETER
;
485 fseek (Fp
, (UINTN
) StartAddress
, SEEK_SET
);
486 NumByte
= fwrite ((VOID
*) Buffer
, sizeof (UINT8
), (UINTN
) Size
, Fp
);
489 // Check to ensure that buffer has been copied successfully
491 if (NumByte
!= Size
) {
492 printf ("\nERROR: Error in copying the buffer into file");
504 BuildFirmwareDeviceBinaryFromFwVolumes (
505 IN UINT64 FvBaseAddress
,
506 IN CHAR8
*FvFileName
,
513 This function reads the input file, parse it and create a list of tokens
514 which is parsed and used, to intialize the data related to Firmware Volume.
518 FvBaseAddress Base Address. This info is retrieved from INF file
519 FvFileName InputFileName
520 FdFileName Output File Name
527 // GC_TODO: function comment is missing 'Routine Description:'
528 // GC_TODO: function comment is missing 'Arguments:'
529 // GC_TODO: function comment is missing 'Returns:'
530 // GC_TODO: FvBaseAddress - add argument and description to function comment
531 // GC_TODO: FvFileName - add argument and description to function comment
532 // GC_TODO: FdFileName - add argument and description to function comment
533 // GC_TODO: EFI_ABORTED - add return value to function comment
534 // GC_TODO: EFI_ABORTED - add return value to function comment
535 // GC_TODO: EFI_ABORTED - add return value to function comment
536 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
537 // GC_TODO: EFI_SUCCESS - add return value to function comment
547 static UINT64 StartAddress
= 0;
549 Fp
= fopen (FvFileName
, "r+b");
552 printf ("\nERROR:Error in opening file %s", FvFileName
);
556 BaseAddress
= FdInfo
->FdBaseAddress
;
559 // Check if Base Address of Firmware Volume falls below the Base Address
560 // Firmware Device, if yes, then abort this process.
562 if (FvBaseAddress
< BaseAddress
) {
563 printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");
567 // Check if there are any hole between two Firmware Volumes. If any hole
568 // exists, fill the hole with PadByte data.
570 if (FvBaseAddress
> LastAddress
) {
571 PadByteSize
= (FvBaseAddress
- LastAddress
);
572 Buffer
= malloc ((UINTN
) PadByteSize
);
574 for (Index
= 0; Index
< PadByteSize
; Index
++) {
575 *Buffer
= FdInfo
->PadValue
;
579 Buffer
-= PadByteSize
;
580 Status
= WriteFwBinary (FdFileName
, StartAddress
, (UINT64
) PadByteSize
, Buffer
);
586 if (Status
!= EFI_SUCCESS
) {
587 printf ("\nERROR: Error in writing the binary image to file");
591 StartAddress
+= PadByteSize
;
592 LastAddress
+= PadByteSize
;
595 // Proceed with next Firmware Volume updates
597 FileSize
= _filelength (fileno (Fp
));
599 if ((FvBaseAddress
+ FileSize
) > (FdInfo
->FdBaseAddress
+ FdInfo
->FdSize
)) {
601 "\nERROR:Unable to update Firmware Device. File %s is larger than \
612 Buffer
= malloc ((UINTN
) FileSize
);
614 if (Buffer
== NULL
) {
615 printf ("Error in allocating buffer to read specific file\n");
616 return EFI_OUT_OF_RESOURCES
;
619 NumByteRead
= fread ((VOID
*) Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
621 Status
= WriteFwBinary (FdFileName
, StartAddress
, FileSize
, Buffer
);
624 free ((VOID
*) Buffer
);
631 if (Status
!= EFI_SUCCESS
) {
632 printf ("\nERROR: Error in writing the binary image to file");
636 StartAddress
+= NumByteRead
;
637 LastAddress
+= FileSize
;
650 This function cleans up any allocated buffer
660 // GC_TODO: function comment is missing 'Routine Description:'
661 // GC_TODO: function comment is missing 'Arguments:'
662 // GC_TODO: function comment is missing 'Returns:'
670 FvInfo
= OrgFvInfoPtr
;
673 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
681 FvInfo
= OrgFvInfoPtr
;
689 IN UINT64 BaseAddress
,
699 This function reads the input file, parse it and create a list of tokens
700 which is parsed and used, to intialize the data related to Firmware Volume.
704 BaseAddress Base Address for this Firmware Device
705 Size, Total Size of the Firmware Device
706 PadByte Pad byte data
707 OutFile Output File Name
708 FileList File List pointer to INF file names.
715 // GC_TODO: function comment is missing 'Routine Description:'
716 // GC_TODO: function comment is missing 'Arguments:'
717 // GC_TODO: function comment is missing 'Returns:'
718 // GC_TODO: BaseAddress - add argument and description to function comment
719 // GC_TODO: Size - add argument and description to function comment
720 // GC_TODO: PadByte - add argument and description to function comment
721 // GC_TODO: OutFile - add argument and description to function comment
722 // GC_TODO: FileList - add argument and description to function comment
723 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
724 // GC_TODO: EFI_ABORTED - add return value to function comment
725 // GC_TODO: EFI_ABORTED - add return value to function comment
726 // GC_TODO: EFI_SUCCESS - add return value to function comment
738 // Ensure, if there are any previous Firmware Device exists,
739 // If yes, make it to 0 bytes
741 if ((Fp
= fopen (OutFile
, "w")) != NULL
) {
747 while (*InFile
!= NULL
) {
755 // Restore the orginal pointers
757 FvInfo
= OrgFvInfoPtr
;
760 while (*InFile
!= NULL
) {
761 strcpy ((*FvInfo
)->FvInfoFile
, *InFile
);
762 Status
= GetFvRelatedInfoFromInfFile (*InFile
);
764 if (Status
!= EFI_SUCCESS
) {
765 printf ("\nERROR: Error occurred in processsing INF file");
774 FdInfo
->FdSize
= Size
;
775 FdInfo
->FdBaseAddress
= BaseAddress
;
776 FdInfo
->PadValue
= PadByte
;
777 FvInfo
= OrgFvInfoPtr
;
778 strcpy (FdInfo
->OutFileName
, OutFile
);
780 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
781 Status
= GenerateFvImage ((*FvInfo
)->FvInfoFile
);
783 if (Status
!= EFI_SUCCESS
) {
791 FvInfo
= OrgFvInfoPtr
;
794 // Sort the Firmware Volume informations. Firmware Volume with lower
795 // base addresses will be processed first and hiher base address one
796 // will be processed later.
798 qsort ((VOID
*) FvInfo
, NumFvFiles
, sizeof (FVINFO
*), CompareItems
);
800 LastAddress
= (*FvInfo
)->FvBaseAddress
;
802 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
803 Status
= BuildFirmwareDeviceBinaryFromFwVolumes (
804 (*FvInfo
)->FvBaseAddress
,
808 if (Status
!= EFI_SUCCESS
) {
816 // Check if any space left after copying data from all Firmware Volumes
817 // If yes, then fill those location with PadValue.
819 if ((FdInfo
->FdBaseAddress
+ Size
) > LastAddress
) {
821 PadSize
= (UINTN
) ((FdInfo
->FdBaseAddress
+ FdInfo
->FdSize
) - LastAddress
);
822 Buffer
= malloc (PadSize
);
824 if (Buffer
== NULL
) {
826 return EFI_OUT_OF_RESOURCES
;
829 for (Index
= 0; Index
< PadSize
; Index
++) {
830 *Buffer
= FdInfo
->PadValue
;
836 Fp
= fopen (OutFile
, "a+b");
839 printf ("\nERROR:Opening file %s", OutFile
);
844 FileSize
= _filelength (fileno (Fp
));
845 fseek (Fp
, FileSize
, SEEK_SET
);
846 NumByte
= fwrite (Buffer
, sizeof (UINT8
), PadSize
, Fp
);
854 if (NumByte
!= (sizeof (UINT8
) * PadSize
)) {
855 printf ("\nERROR: Copying data from buffer to File %s ", OutFile
);
861 // Clean up all the memory which has been allocated so far.