]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
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 "TianoCommon.h"
32 #include "GenFdImage.h"
33 #include "GenFvImage.h"
39 UINTN ValidLineNum
= 0;
42 static UINT64 LastAddress
= 0;
51 FVINFO
**OrgFvInfoPtr
;
54 // Global function declarations
57 BuildFirmwareDeviceBinaryFromFwVolumes (
58 IN UINT64 FvBaseAddress
,
71 This function is used by qsort to sort the Fv list based on FvBaseAddress
81 // GC_TODO: function comment is missing 'Routine Description:'
82 // GC_TODO: function comment is missing 'Arguments:'
83 // GC_TODO: function comment is missing 'Returns:'
84 // GC_TODO: Arg1 - add argument and description to function comment
85 // GC_TODO: Arg2 - add argument and description to function comment
87 if ((*(FVINFO
**) Arg1
)->FvBaseAddress
> (*(FVINFO
**) Arg2
)->FvBaseAddress
) {
89 } else if ((*(FVINFO
**) Arg1
)->FvBaseAddress
< (*(FVINFO
**) Arg2
)->FvBaseAddress
) {
103 This function builds the token list in an array which will be parsed later
112 // GC_TODO: function comment is missing 'Routine Description:'
113 // GC_TODO: function comment is missing 'Arguments:'
114 // GC_TODO: function comment is missing 'Returns:'
115 // GC_TODO: Token - add argument and description to function comment
118 strcpy (*TokenStr
, Token
);
129 This function cleans up the line by removing all whitespace and
139 // GC_TODO: function comment is missing 'Routine Description:'
140 // GC_TODO: function comment is missing 'Arguments:'
141 // GC_TODO: function comment is missing 'Returns:'
142 // GC_TODO: Line - add argument and description to function comment
144 CHAR8 TmpLine
[FILE_NAME_SIZE
];
151 // Change '#' to '//' for Comment style
153 // if((Ptr0=strchr(Line, '#')) != NULL) {
155 if ((Ptr0
= strstr (Line
, "//")) != NULL
) {
156 Line
[Ptr0
- Line
] = 0;
161 while ((c
= Line
[i
]) != 0) {
162 if ((c
!= ' ') && (c
!= '\t') && (c
!= '\n')) {
170 strcpy (Line
, TmpLine
);
181 This function calculated number of valid lines in a input file.
185 Fp Pointer to a file handle which has been opened.
191 // GC_TODO: function comment is missing 'Routine Description:'
192 // GC_TODO: function comment is missing 'Arguments:'
193 // GC_TODO: function comment is missing 'Returns:'
194 // GC_TODO: Fp - add argument and description to function comment
196 CHAR8 Buff
[FILE_NAME_SIZE
];
198 while (fgets (Buff
, sizeof (Buff
), Fp
)) {
216 This function parses the input file and tokenize the string
220 Fp Pointer to a file handle which has been opened.
226 // GC_TODO: function comment is missing 'Routine Description:'
227 // GC_TODO: function comment is missing 'Arguments:'
228 // GC_TODO: function comment is missing 'Returns:'
229 // GC_TODO: Fp - add argument and description to function comment
232 CHAR8 Buff
[FILE_NAME_SIZE
];
233 CHAR8 OrgLine
[FILE_NAME_SIZE
];
234 CHAR8 Str
[FILE_NAME_SIZE
];
235 CHAR8 Delimit
[] = "=";
237 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
238 strcpy (OrgLine
, Buff
);
245 Token
= strtok (Buff
, Delimit
);
247 while (Token
!= NULL
) {
249 BuildTokenList (Str
);
250 Token
= strtok (NULL
, Delimit
);
263 This function intializes the relevant global variable which is being
264 used to store the information retrieved from INF file.
274 // GC_TODO: function comment is missing 'Routine Description:'
275 // GC_TODO: function comment is missing 'Arguments:'
276 // GC_TODO: function comment is missing 'Returns:'
277 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
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_SUCCESS - add return value to function comment
284 FdInfo
= malloc (sizeof (FDINFO
));
286 if (FdInfo
== NULL
) {
287 return EFI_OUT_OF_RESOURCES
;
290 OrgFdInfoPtr
= FdInfo
;
292 FvInfo
= malloc (sizeof (int) * NumFvFiles
);
294 if (FvInfo
== NULL
) {
295 return EFI_OUT_OF_RESOURCES
;
298 OrgFvInfoPtr
= FvInfo
;
300 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
301 *FvInfo
= malloc (sizeof (FVINFO
));
303 if (*FvInfo
== NULL
) {
304 return EFI_OUT_OF_RESOURCES
;
307 memset (*FvInfo
, 0, sizeof (FVINFO
));
311 FvInfo
= OrgFvInfoPtr
;
317 InitializeInFileInfo (
324 This function intializes the relevant global variable which is being
325 used to store the information retrieved from INF file.
335 // GC_TODO: function comment is missing 'Routine Description:'
336 // GC_TODO: function comment is missing 'Arguments:'
337 // GC_TODO: function comment is missing 'Returns:'
343 TokenStr
= OrgStrTokPtr
;
345 while (*TokenStr
!= NULL
) {
346 if (stricmp (*TokenStr
, "[options]") == 0) {
351 if (stricmp (*TokenStr
, "EFI_FV_BASE_ADDRESS") == 0) {
353 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
354 printf ("\nERROR: Cannot determine the FV base address.");
357 (*FvInfo
)->FvBaseAddress
= StringValue
;
358 } else if (stricmp (*TokenStr
, "EFI_FV_FILE_NAME") == 0) {
360 strcpy ((*FvInfo
)->FvFile
, *TokenStr
);
369 GetFvRelatedInfoFromInfFile (
376 This function reads the input file, parse it and create a list of tokens
377 which is parsed and used, to intialize the data related to Firmware Volume.
381 FileName FileName which needed to be read to parse data
388 // GC_TODO: function comment is missing 'Routine Description:'
389 // GC_TODO: function comment is missing 'Arguments:'
390 // GC_TODO: function comment is missing 'Returns:'
391 // GC_TODO: FileName - add argument and description to function comment
392 // GC_TODO: EFI_ABORTED - add return value to function comment
393 // GC_TODO: EFI_ABORTED - add return value to function comment
394 // GC_TODO: EFI_SUCCESS - add return value to function comment
399 Fp
= fopen (FileName
, "r");
402 printf ("Error in opening %s file\n", FileName
);
408 if (ValidLineNum
== 0) {
409 printf ("\nFile doesn't contain any valid informations");
413 TokenStr
= (CHAR8
**) malloc (sizeof (UINTN
) * (2 * ValidLineNum
));
414 memset (TokenStr
, 0, sizeof (UINTN
) * (2 * ValidLineNum
));
415 OrgStrTokPtr
= TokenStr
;
417 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
418 *TokenStr
= (CHAR8
*) malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
419 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
424 TokenStr
= OrgStrTokPtr
;
425 fseek (Fp
, 0L, SEEK_SET
);
428 InitializeInFileInfo ();
440 IN UINT64 StartAddress
,
448 This function reads the input file, parse it and create a list of tokens
449 which is parsed and used, to intialize the data related to Firmware Volume.
453 FileName FileName which needed to be read to parse data
454 StartAddress This will set the file position.
455 Size Size in bytes needed to be written
456 Buffer Buffer needed to e written
463 // GC_TODO: function comment is missing 'Routine Description:'
464 // GC_TODO: function comment is missing 'Arguments:'
465 // GC_TODO: function comment is missing 'Returns:'
466 // GC_TODO: FileName - add argument and description to function comment
467 // GC_TODO: StartAddress - add argument and description to function comment
468 // GC_TODO: Size - add argument and description to function comment
469 // GC_TODO: Buffer - add argument and description to function comment
470 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
471 // GC_TODO: EFI_ABORTED - add return value to function comment
472 // GC_TODO: EFI_SUCCESS - add return value to function comment
477 Fp
= fopen (FileName
, "a+b");
480 printf ("\nERROR:Error in opening file %s ", FileName
);
481 return EFI_INVALID_PARAMETER
;
484 fseek (Fp
, (UINTN
) StartAddress
, SEEK_SET
);
485 NumByte
= fwrite ((VOID
*) Buffer
, sizeof (UINT8
), (UINTN
) Size
, Fp
);
488 // Check to ensure that buffer has been copied successfully
490 if (NumByte
!= Size
) {
491 printf ("\nERROR: Error in copying the buffer into file");
503 BuildFirmwareDeviceBinaryFromFwVolumes (
504 IN UINT64 FvBaseAddress
,
505 IN CHAR8
*FvFileName
,
512 This function reads the input file, parse it and create a list of tokens
513 which is parsed and used, to intialize the data related to Firmware Volume.
517 FvBaseAddress Base Address. This info is retrieved from INF file
518 FvFileName InputFileName
519 FdFileName Output File Name
526 // GC_TODO: function comment is missing 'Routine Description:'
527 // GC_TODO: function comment is missing 'Arguments:'
528 // GC_TODO: function comment is missing 'Returns:'
529 // GC_TODO: FvBaseAddress - add argument and description to function comment
530 // GC_TODO: FvFileName - add argument and description to function comment
531 // GC_TODO: FdFileName - add argument and description to function comment
532 // GC_TODO: EFI_ABORTED - add return value 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_OUT_OF_RESOURCES - add return value to function comment
536 // GC_TODO: EFI_SUCCESS - add return value to function comment
546 static UINT64 StartAddress
= 0;
548 Fp
= fopen (FvFileName
, "r+b");
551 printf ("\nERROR:Error in opening file %s", FvFileName
);
555 BaseAddress
= FdInfo
->FdBaseAddress
;
558 // Check if Base Address of Firmware Volume falls below the Base Address
559 // Firmware Device, if yes, then abort this process.
561 if (FvBaseAddress
< BaseAddress
) {
562 printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");
566 // Check if there are any hole between two Firmware Volumes. If any hole
567 // exists, fill the hole with PadByte data.
569 if (FvBaseAddress
> LastAddress
) {
570 PadByteSize
= (FvBaseAddress
- LastAddress
);
571 Buffer
= malloc ((UINTN
) PadByteSize
);
573 for (Index
= 0; Index
< PadByteSize
; Index
++) {
574 *Buffer
= FdInfo
->PadValue
;
578 Buffer
-= PadByteSize
;
579 Status
= WriteFwBinary (FdFileName
, StartAddress
, (UINT64
) PadByteSize
, Buffer
);
585 if (Status
!= EFI_SUCCESS
) {
586 printf ("\nERROR: Error in writing the binary image to file");
590 StartAddress
+= PadByteSize
;
591 LastAddress
+= PadByteSize
;
594 // Proceed with next Firmware Volume updates
596 FileSize
= _filelength (fileno (Fp
));
598 if ((FvBaseAddress
+ FileSize
) > (FdInfo
->FdBaseAddress
+ FdInfo
->FdSize
)) {
600 "\nERROR:Unable to update Firmware Device. File %s is larger than \
611 Buffer
= malloc ((UINTN
) FileSize
);
613 if (Buffer
== NULL
) {
614 printf ("Error in allocating buffer to read specific file\n");
615 return EFI_OUT_OF_RESOURCES
;
618 NumByteRead
= fread ((VOID
*) Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
620 Status
= WriteFwBinary (FdFileName
, StartAddress
, FileSize
, Buffer
);
623 free ((VOID
*) Buffer
);
630 if (Status
!= EFI_SUCCESS
) {
631 printf ("\nERROR: Error in writing the binary image to file");
635 StartAddress
+= NumByteRead
;
636 LastAddress
+= FileSize
;
649 This function cleans up any allocated buffer
659 // GC_TODO: function comment is missing 'Routine Description:'
660 // GC_TODO: function comment is missing 'Arguments:'
661 // GC_TODO: function comment is missing 'Returns:'
669 FvInfo
= OrgFvInfoPtr
;
672 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
680 FvInfo
= OrgFvInfoPtr
;
688 IN UINT64 BaseAddress
,
698 This function reads the input file, parse it and create a list of tokens
699 which is parsed and used, to intialize the data related to Firmware Volume.
703 BaseAddress Base Address for this Firmware Device
704 Size, Total Size of the Firmware Device
705 PadByte Pad byte data
706 OutFile Output File Name
707 FileList File List pointer to INF file names.
714 // GC_TODO: function comment is missing 'Routine Description:'
715 // GC_TODO: function comment is missing 'Arguments:'
716 // GC_TODO: function comment is missing 'Returns:'
717 // GC_TODO: BaseAddress - add argument and description to function comment
718 // GC_TODO: Size - add argument and description to function comment
719 // GC_TODO: PadByte - add argument and description to function comment
720 // GC_TODO: OutFile - add argument and description to function comment
721 // GC_TODO: FileList - add argument and description to function comment
722 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
723 // GC_TODO: EFI_ABORTED - add return value to function comment
724 // GC_TODO: EFI_ABORTED - add return value to function comment
725 // GC_TODO: EFI_SUCCESS - add return value to function comment
737 // Ensure, if there are any previous Firmware Device exists,
738 // If yes, make it to 0 bytes
740 if ((Fp
= fopen (OutFile
, "w")) != NULL
) {
746 while (*InFile
!= NULL
) {
754 // Restore the orginal pointers
756 FvInfo
= OrgFvInfoPtr
;
759 while (*InFile
!= NULL
) {
760 strcpy ((*FvInfo
)->FvInfoFile
, *InFile
);
761 Status
= GetFvRelatedInfoFromInfFile (*InFile
);
763 if (Status
!= EFI_SUCCESS
) {
764 printf ("\nERROR: Error occurred in processsing INF file");
773 FdInfo
->FdSize
= Size
;
774 FdInfo
->FdBaseAddress
= BaseAddress
;
775 FdInfo
->PadValue
= PadByte
;
776 FvInfo
= OrgFvInfoPtr
;
777 strcpy (FdInfo
->OutFileName
, OutFile
);
779 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
780 Status
= GenerateFvImage ((*FvInfo
)->FvInfoFile
);
782 if (Status
!= EFI_SUCCESS
) {
790 FvInfo
= OrgFvInfoPtr
;
793 // Sort the Firmware Volume informations. Firmware Volume with lower
794 // base addresses will be processed first and hiher base address one
795 // will be processed later.
797 qsort ((VOID
*) FvInfo
, NumFvFiles
, sizeof (FVINFO
*), CompareItems
);
799 LastAddress
= (*FvInfo
)->FvBaseAddress
;
801 for (Index
= 0; Index
< NumFvFiles
; Index
++) {
802 Status
= BuildFirmwareDeviceBinaryFromFwVolumes (
803 (*FvInfo
)->FvBaseAddress
,
807 if (Status
!= EFI_SUCCESS
) {
815 // Check if any space left after copying data from all Firmware Volumes
816 // If yes, then fill those location with PadValue.
818 if ((FdInfo
->FdBaseAddress
+ Size
) > LastAddress
) {
820 PadSize
= (UINTN
) ((FdInfo
->FdBaseAddress
+ FdInfo
->FdSize
) - LastAddress
);
821 Buffer
= malloc (PadSize
);
823 if (Buffer
== NULL
) {
825 return EFI_OUT_OF_RESOURCES
;
828 for (Index
= 0; Index
< PadSize
; Index
++) {
829 *Buffer
= FdInfo
->PadValue
;
835 Fp
= fopen (OutFile
, "a+b");
838 printf ("\nERROR:Opening file %s", OutFile
);
843 FileSize
= _filelength (fileno (Fp
));
844 fseek (Fp
, FileSize
, SEEK_SET
);
845 NumByte
= fwrite (Buffer
, sizeof (UINT8
), PadSize
, Fp
);
853 if (NumByte
!= (sizeof (UINT8
) * PadSize
)) {
854 printf ("\nERROR: Copying data from buffer to File %s ", OutFile
);
860 // Clean up all the memory which has been allocated so far.