summaryrefslogtreecommitdiff
path: root/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c')
-rw-r--r--Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c490
1 files changed, 490 insertions, 0 deletions
diff --git a/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c b/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
new file mode 100644
index 0000000000..462f97fa83
--- /dev/null
+++ b/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
@@ -0,0 +1,490 @@
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ GenBsfFixup.c
+
+Abstract:
+
+ Utility to Fixup the SEC component for IA32. This is an
+ interim tool in place of the full GenBsfImage support for
+ IA32.
+ This tool supports the Synch3 update
+
+--*/
+
+#include "BaseTypes.h"
+#include "UefiBaseTypes.h"
+#include "EfiImage.h"
+#include "FirmwareVolumeHeader.h"
+#include "FirmwareVolumeImageFormat.h"
+#include "ParseInf.h"
+#include "CommonLib.h"
+#include "FirmwareFileSystem.h"
+#include "FvLib.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+//
+// BugBug -- this port to the new FFS is really weird.
+// A lot of the file-header stuff has been ported, but
+// not the section information.
+//
+#define TOOLVERSION "0.1"
+
+UINT32 gFixup;
+
+UINT32
+GetOccupiedSize (
+ IN UINT32 ActualSize,
+ IN UINT32 Alignment
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ ActualSize - GC_TODO: add argument description
+ Alignment - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ UINT32 OccupiedSize;
+
+ OccupiedSize = ActualSize;
+ while ((OccupiedSize & (Alignment - 1)) != 0) {
+ OccupiedSize++;
+ }
+
+ return OccupiedSize;
+}
+
+int
+ReadHeader (
+ FILE *In,
+ UINT32 *FvSize
+ )
+/*++
+
+Routine Description:
+
+ Reads in Firmware Volume information from the volume header file.
+
+Arguments:
+
+ In: Firmware Volume header file to read from
+ FvSize: Size of Firmware Volume
+
+Returns:
+
+ int: Number of bytes read
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
+ EFI_FV_BLOCK_MAP_ENTRY BlockMap;
+ INT32 SigTemp[2];
+ INT32 Invert;
+ INT32 bytesread;
+ UINT32 size;
+
+ size = 0;
+ Invert = 0;
+ bytesread = 0;
+
+ if (In == NULL) {
+ printf ("Error: Input file is NULL.\n");
+ return -1;
+ }
+
+ fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);
+ bytesread = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+ SigTemp[0] = VolumeHeader.Signature;
+ SigTemp[1] = 0;
+
+ if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {
+ Invert = 1;
+ }
+
+ do {
+ fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);
+ bytesread += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+
+ if (BlockMap.NumBlocks != 0) {
+ size += BlockMap.NumBlocks * BlockMap.BlockLength;
+ }
+
+ } while (BlockMap.NumBlocks != 0);
+
+ *FvSize = size;
+ rewind (In);
+
+ if (Invert == 1) {
+ bytesread *= -1;
+ }
+
+ return bytesread;
+}
+
+UINT32
+GetSectionLength (
+ IN UINT32 *Length
+ )
+/*++
+
+Routine Description:
+
+ Converts a UINT8[3] array to a UINT32
+
+Arguments:
+
+ Length A pointer to a 3 byte array
+
+Returns:
+
+ UINT32: The length.
+
+--*/
+{
+ return *Length & 0x00FFFFFF;
+}
+
+int
+Readfile (
+ UINT8 *FvImage,
+ int bytes,
+ int Invert
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FvImage - GC_TODO: add argument description
+ bytes - GC_TODO: add argument description
+ Invert - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ UINT32 FileLength;
+ UINT32 OccupiedFileLength;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ UINT8 FileState;
+ UINT8 Checksum;
+ UINT8 *Ptr;
+ UINT32 SectionLength;
+ EFI_COMMON_SECTION_HEADER *SectionHeader;
+ EFI_IMAGE_NT_HEADERS *PeHeader;
+ UINT32 PeiCoreOffset;
+
+ Ptr = FvImage + bytes;
+
+ FileHeader = (EFI_FFS_FILE_HEADER *) Ptr;
+
+ FileState = GetFileState ((UINT8) Invert, FileHeader);
+
+ switch (FileState) {
+ case EFI_FILE_HEADER_CONSTRUCTION:
+ case EFI_FILE_HEADER_INVALID:
+ return sizeof (EFI_FFS_FILE_HEADER);
+
+ case EFI_FILE_HEADER_VALID:
+ Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
+ Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ return -1;
+ }
+ //
+ // Now do the fixup stuff - begin
+ //
+ if (FileHeader->Type == EFI_FV_FILETYPE_PEI_CORE) {
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);
+ SectionLength = GetSectionLength ((UINT32 *) &SectionHeader->Size[0]);
+
+ printf ("Section length is 0x%X\n", SectionLength);
+
+ if (SectionHeader->Type == EFI_SECTION_PE32) {
+
+ gFixup = bytes + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);
+
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) Ptr + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);
+
+ if (((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) PeHeader + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_lfanew) & 0x0ffff));
+
+ }
+
+ PeiCoreOffset = (UINTN) ((UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+
+ gFixup += PeiCoreOffset;
+ }
+ }
+
+ FileLength = GetLength (FileHeader->Size);
+ OccupiedFileLength = GetOccupiedSize (FileLength, 8);
+ return OccupiedFileLength;
+
+ case EFI_FILE_DATA_VALID:
+ //
+ // Calculate header checksum
+ //
+ Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
+ Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ return -1;
+ }
+ //
+ // Determine file length
+ //
+ FileLength = GetLength (FileHeader->Size);
+ OccupiedFileLength = GetOccupiedSize (FileLength, 8);
+
+ //
+ // Determine if file checksum is valid or fixed
+ //
+ if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
+ Checksum = CalculateSum8 (Ptr, FileLength);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ return -1;
+ }
+ } else {
+ if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
+ return -1;
+ }
+ }
+ break;
+
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ case EFI_FILE_DELETED:
+ //
+ // Calculate header checksum
+ //
+ Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
+ Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ return -1;
+ }
+ //
+ // Determine file length
+ //
+ FileLength = GetLength (FileHeader->Size);
+ OccupiedFileLength = GetOccupiedSize (FileLength, 8);
+
+ //
+ // Determine if file checksum is valid or fixed
+ //
+ if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
+ Checksum = CalculateSum8 (Ptr, FileLength);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ return -1;
+ }
+ } else {
+ if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
+ return -1;
+ }
+ }
+
+ return OccupiedFileLength;
+
+ default:
+ return sizeof (EFI_FFS_FILE_HEADER);
+ }
+
+ return OccupiedFileLength;
+}
+
+int
+main (
+ int argc,
+ char*argv[]
+ )
+/*++
+
+Routine Description:
+
+ Runs GenBsfFixup
+
+Arguments:
+
+ argc: number of command line arguments
+
+ arg[0] = This file name
+ arg[1] = Firmware Volume Name
+ arg[2] = Base Address to relocate
+ arg[3] = Relative offset of the fixup to perform
+ arg[4] = Output File Name
+
+Returns:
+
+ int: 0 code success, -1 code failure
+
+--*/
+{
+ FILE *In;
+ FILE *Out;
+ int ByteStart;
+ int Invert;
+ int Index;
+ int cnt;
+ UINT8 *FvImage;
+ int ByteRead;
+ UINT32 FvSize;
+ UINT64 delta;
+ UINT32 Idx;
+ UINT64 FvOffset;
+ EFI_STATUS Status;
+
+ Index = 0;
+ Invert = 0;
+ printf (
+ "GenBsfFixup EFI 2.0. Version %s, %s\n""Copyright (c) 2000-2001, Intel Corporation\n\n",
+ TOOLVERSION,
+ __DATE__
+ );
+
+ if (argc != 5) {
+ printf ("Usage:\n"" GenBsfFixup FvVolumeImageFile AddressOfFvInMemory OffsetOfFixup OutputFileName\n");
+ return -1;
+ }
+
+ In = fopen (argv[1], "rb");
+
+ if (In == NULL) {
+ printf ("Unable to open FV image file \"%s\"\n", argv[1]);
+ return -1;
+ }
+
+ ByteStart = ReadHeader (In, &FvSize);
+
+ if (ByteStart < 0) {
+ Invert = 1;
+ ByteStart *= -1;
+ }
+
+ FvImage = malloc (FvSize);
+ if (FvImage == NULL) {
+ printf ("Cannot allocate memory\n");
+ fclose (In);
+ return -1;
+ }
+
+ ByteRead = fread (FvImage, 1, FvSize, In);
+
+ if ((unsigned int) ByteRead != FvSize) {
+ printf ("Read File error\n");
+ fclose (In);
+ return -1;
+ }
+
+ cnt = 0;
+ while ((unsigned int) ByteStart < FvSize && cnt != -1) {
+ cnt = Readfile (FvImage, ByteStart, Invert);
+
+ if (cnt != -1) {
+ ByteStart += cnt;
+ }
+
+ if (cnt != sizeof (EFI_FFS_FILE_HEADER)) {
+ Index++;
+ }
+ }
+
+ if (cnt == -1) {
+ printf ("Firmware Volume image corrupted\n");
+ return -1;
+ }
+
+ fclose (In);
+
+ Out = fopen (argv[4], "wb");
+
+ if (Out == NULL) {
+ printf ("Unable to open FV image file \"%s\"\n", argv[4]);
+ return -1;
+ }
+
+ In = fopen (argv[1], "rb");
+
+ if (In == NULL) {
+ printf ("Unable to open FV image file \"%s\"\n", argv[1]);
+ return -1;
+ }
+
+ if (gFixup != 0) {
+
+ printf ("Fixup of 0x%X\n", gFixup);
+
+ Status = AsciiStringToUint64 (argv[2], TRUE, &FvOffset);
+
+ gFixup += (UINT32) FvOffset;
+
+ ByteStart = ReadHeader (In, &FvSize);
+
+ Readfile (FvImage, ByteStart, Invert);
+
+ cnt = 0;
+ Status = AsciiStringToUint64 (argv[3], TRUE, &delta);
+
+ fclose (In);
+ In = fopen (argv[1], "rb");
+
+ if (In == NULL) {
+ printf ("Unable to open FV image file \"%s\"\n", argv[1]);
+ return -1;
+ }
+
+ for (Idx = 0; Idx < delta - FvOffset; Idx++) {
+ fputc (fgetc (In), Out);
+ }
+
+ fwrite (&gFixup, sizeof (UINT32), 1, Out);
+ fseek (In, sizeof (UINT32), SEEK_CUR);
+
+ for (Idx = 0; Idx < FvSize - (delta - FvOffset) - sizeof (UINT32); Idx++) {
+ fputc (fgetc (In), Out);
+ }
+
+ fclose (In);
+ fclose (Out);
+ } else {
+ printf ("There was no fixup to perform\n");
+ }
+
+ free (FvImage);
+
+ return 0;
+}