Blob Blame History Raw
From d596880050a6009629af799243e09f337bcb944a Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 21 Oct 2015 11:07:05 +0200
Subject: import EfiRom from edk2 BaseTools (RHEL only)

Message-id: <1410295825-13989-2-git-send-email-lersek@redhat.com>
Patchwork-id: 60927
O-Subject: [RHEL-7.1 ipxe PATCH 1/4] import EfiRom from edk2 BaseTools (RHEL only)
Bugzilla: 1084561
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>

This patch imports the minimum set of files from edk2's BaseTools (at
commit 07da1ac8) that are necessary to build the EfiRom utility.

The top-level BaseTools license file is added as well. The ipxe RPM's
License field already states "GPLv2 and BSD". EfiRom (and the rest of
BaseTools) are 2-clause BSD.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
(cherry picked from commit 781fa846a6b51b80fb08afe8ac2b8e862006082f)
---
 EfiRom/Common/CommonLib.c                 |  711 +++++++++++++
 EfiRom/Common/CommonLib.h                 |  194 ++++
 EfiRom/Common/Compress.h                  |   88 ++
 EfiRom/Common/EfiCompress.c               | 1590 +++++++++++++++++++++++++++++
 EfiRom/Common/EfiUtilityMsgs.c            |  906 ++++++++++++++++
 EfiRom/Common/EfiUtilityMsgs.h            |  170 +++
 EfiRom/Common/MemoryFile.h                |  111 ++
 EfiRom/Common/ParseInf.c                  |  701 +++++++++++++
 EfiRom/Common/ParseInf.h                  |  226 ++++
 EfiRom/EfiRom.c                           | 1564 ++++++++++++++++++++++++++++
 EfiRom/EfiRom.h                           |  357 +++++++
 EfiRom/Include/Common/BaseTypes.h         |  286 ++++++
 EfiRom/Include/Common/BuildVersion.h      |   15 +
 EfiRom/Include/Common/UefiBaseTypes.h     |  175 ++++
 EfiRom/Include/IndustryStandard/EfiPci.h  |   57 ++
 EfiRom/Include/IndustryStandard/PeImage.h |  769 ++++++++++++++
 EfiRom/Include/IndustryStandard/pci22.h   |  542 ++++++++++
 EfiRom/Include/IndustryStandard/pci23.h   |   24 +
 EfiRom/Include/IndustryStandard/pci30.h   |   44 +
 EfiRom/Include/X64/ProcessorBind.h        |  194 ++++
 EfiRom/License.txt                        |   25 +
 21 files changed, 8749 insertions(+)
 create mode 100644 EfiRom/Common/CommonLib.c
 create mode 100644 EfiRom/Common/CommonLib.h
 create mode 100644 EfiRom/Common/Compress.h
 create mode 100644 EfiRom/Common/EfiCompress.c
 create mode 100644 EfiRom/Common/EfiUtilityMsgs.c
 create mode 100644 EfiRom/Common/EfiUtilityMsgs.h
 create mode 100644 EfiRom/Common/MemoryFile.h
 create mode 100644 EfiRom/Common/ParseInf.c
 create mode 100644 EfiRom/Common/ParseInf.h
 create mode 100644 EfiRom/EfiRom.c
 create mode 100644 EfiRom/EfiRom.h
 create mode 100644 EfiRom/Include/Common/BaseTypes.h
 create mode 100644 EfiRom/Include/Common/BuildVersion.h
 create mode 100644 EfiRom/Include/Common/UefiBaseTypes.h
 create mode 100644 EfiRom/Include/IndustryStandard/EfiPci.h
 create mode 100644 EfiRom/Include/IndustryStandard/PeImage.h
 create mode 100644 EfiRom/Include/IndustryStandard/pci22.h
 create mode 100644 EfiRom/Include/IndustryStandard/pci23.h
 create mode 100644 EfiRom/Include/IndustryStandard/pci30.h
 create mode 100644 EfiRom/Include/X64/ProcessorBind.h
 create mode 100644 EfiRom/License.txt

diff --git a/EfiRom/Common/CommonLib.c b/EfiRom/Common/CommonLib.c
new file mode 100644
index 0000000..977efa0
--- /dev/null
+++ b/EfiRom/Common/CommonLib.c
@@ -0,0 +1,711 @@
+/** @file
+Common basic Library Functions
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+VOID
+PeiZeroMem (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+  )
+/*++
+
+Routine Description:
+
+  Set Buffer to zero for Size bytes.
+
+Arguments:
+
+  Buffer  - Memory to set.
+
+  Size    - Number of bytes to set
+
+Returns:
+
+  None
+
+--*/
+{
+  INT8  *Ptr;
+
+  Ptr = Buffer;
+  while (Size--) {
+    *(Ptr++) = 0;
+  }
+}
+
+VOID
+PeiCopyMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  )
+/*++
+
+Routine Description:
+
+  Copy Length bytes from Source to Destination.
+
+Arguments:
+
+  Destination - Target of copy
+
+  Source      - Place to copy from
+
+  Length      - Number of bytes to copy
+
+Returns:
+
+  None
+
+--*/
+{
+  CHAR8 *Destination8;
+  CHAR8 *Source8;
+
+  Destination8  = Destination;
+  Source8       = Source;
+  while (Length--) {
+    *(Destination8++) = *(Source8++);
+  }
+}
+
+VOID
+ZeroMem (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+  )
+{
+  PeiZeroMem (Buffer, Size);
+}
+
+VOID
+CopyMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  )
+{
+  PeiCopyMem (Destination, Source, Length);
+}
+
+INTN
+CompareGuid (
+  IN EFI_GUID     *Guid1,
+  IN EFI_GUID     *Guid2
+  )
+/*++
+
+Routine Description:
+
+  Compares to GUIDs
+
+Arguments:
+
+  Guid1 - guid to compare
+  Guid2 - guid to compare
+
+Returns:
+  =  0  if Guid1 == Guid2
+  != 0  if Guid1 != Guid2 
+
+--*/
+{
+  INT32 *g1;
+  INT32 *g2;
+  INT32 r;
+
+  //
+  // Compare 32 bits at a time
+  //
+  g1  = (INT32 *) Guid1;
+  g2  = (INT32 *) Guid2;
+
+  r   = g1[0] - g2[0];
+  r |= g1[1] - g2[1];
+  r |= g1[2] - g2[2];
+  r |= g1[3] - g2[3];
+
+  return r;
+}
+
+
+EFI_STATUS
+GetFileImage (
+  IN CHAR8    *InputFileName,
+  OUT CHAR8   **InputFileImage,
+  OUT UINT32  *BytesRead
+  )
+/*++
+
+Routine Description:
+
+  This function opens a file and reads it into a memory buffer.  The function 
+  will allocate the memory buffer and returns the size of the buffer.
+
+Arguments:
+
+  InputFileName     The name of the file to read.
+  InputFileImage    A pointer to the memory buffer.
+  BytesRead         The size of the memory buffer.
+
+Returns:
+
+  EFI_SUCCESS              The function completed successfully.
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
+  EFI_ABORTED              An error occurred.
+  EFI_OUT_OF_RESOURCES     No resource to complete operations.
+
+--*/
+{
+  FILE    *InputFile;
+  UINT32  FileSize;
+
+  //
+  // Verify input parameters.
+  //
+  if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Open the file and copy contents into a memory buffer.
+  //
+  //
+  // Open the file
+  //
+  InputFile = fopen (LongFilePath (InputFileName), "rb");
+  if (InputFile == NULL) {
+    Error (NULL, 0, 0001, "Error opening the input file", InputFileName);
+    return EFI_ABORTED;
+  }
+  //
+  // Go to the end so that we can determine the file size
+  //
+  if (fseek (InputFile, 0, SEEK_END)) {
+    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+    fclose (InputFile);
+    return EFI_ABORTED;
+  }
+  //
+  // Get the file size
+  //
+  FileSize = ftell (InputFile);
+  if (FileSize == -1) {
+    Error (NULL, 0, 0003, "Error parsing the input file", InputFileName);
+    fclose (InputFile);
+    return EFI_ABORTED;
+  }
+  //
+  // Allocate a buffer
+  //
+  *InputFileImage = malloc (FileSize);
+  if (*InputFileImage == NULL) {
+    fclose (InputFile);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Reset to the beginning of the file
+  //
+  if (fseek (InputFile, 0, SEEK_SET)) {
+    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+    fclose (InputFile);
+    free (*InputFileImage);
+    *InputFileImage = NULL;
+    return EFI_ABORTED;
+  }
+  //
+  // Read all of the file contents.
+  //
+  *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);
+  if (*BytesRead != sizeof (UINT8) * FileSize) {
+    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+    fclose (InputFile);
+    free (*InputFileImage);
+    *InputFileImage = NULL;
+    return EFI_ABORTED;
+  }
+  //
+  // Close the file
+  //
+  fclose (InputFile);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PutFileImage (
+  IN CHAR8    *OutputFileName,
+  IN CHAR8    *OutputFileImage,
+  IN UINT32   BytesToWrite
+  )
+/*++
+
+Routine Description:
+
+  This function opens a file and writes OutputFileImage into the file.
+
+Arguments:
+
+  OutputFileName     The name of the file to write.
+  OutputFileImage    A pointer to the memory buffer.
+  BytesToWrite       The size of the memory buffer.
+
+Returns:
+
+  EFI_SUCCESS              The function completed successfully.
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
+  EFI_ABORTED              An error occurred.
+  EFI_OUT_OF_RESOURCES     No resource to complete operations.
+
+--*/
+{
+  FILE    *OutputFile;
+  UINT32  BytesWrote;
+
+  //
+  // Verify input parameters.
+  //
+  if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Open the file and copy contents into a memory buffer.
+  //
+  //
+  // Open the file
+  //
+  OutputFile = fopen (LongFilePath (OutputFileName), "wb");
+  if (OutputFile == NULL) {
+    Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);
+    return EFI_ABORTED;
+  }
+
+  //
+  // Write all of the file contents.
+  //
+  BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile);
+  if (BytesWrote != sizeof (UINT8) * BytesToWrite) {
+    Error (NULL, 0, 0002, "Error writing the output file", OutputFileName);
+    fclose (OutputFile);
+    return EFI_ABORTED;
+  }
+  //
+  // Close the file
+  //
+  fclose (OutputFile);
+
+  return EFI_SUCCESS;
+}
+
+UINT8
+CalculateChecksum8 (
+  IN UINT8        *Buffer,
+  IN UINTN        Size
+  )
+/*++
+  
+Routine Description:
+
+  This function calculates the value needed for a valid UINT8 checksum
+
+Arguments:
+
+  Buffer      Pointer to buffer containing byte data of component.
+  Size        Size of the buffer
+
+Returns:
+
+  The 8 bit checksum value needed.
+
+--*/
+{
+  return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));
+}
+
+UINT8
+CalculateSum8 (
+  IN UINT8  *Buffer,
+  IN UINTN  Size
+  )
+/*++
+  
+Routine Description::
+
+  This function calculates the UINT8 sum for the requested region.
+
+Arguments:
+
+  Buffer      Pointer to buffer containing byte data of component.
+  Size        Size of the buffer
+
+Returns:
+
+  The 8 bit checksum value needed.
+
+--*/
+{
+  UINTN Index;
+  UINT8 Sum;
+
+  Sum = 0;
+
+  //
+  // Perform the byte sum for buffer
+  //
+  for (Index = 0; Index < Size; Index++) {
+    Sum = (UINT8) (Sum + Buffer[Index]);
+  }
+
+  return Sum;
+}
+
+UINT16
+CalculateChecksum16 (
+  IN UINT16       *Buffer,
+  IN UINTN        Size
+  )
+/*++
+  
+Routine Description::
+
+  This function calculates the value needed for a valid UINT16 checksum
+
+Arguments:
+
+  Buffer      Pointer to buffer containing byte data of component.
+  Size        Size of the buffer
+
+Returns:
+
+  The 16 bit checksum value needed.
+
+--*/
+{
+  return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));
+}
+
+UINT16
+CalculateSum16 (
+  IN UINT16       *Buffer,
+  IN UINTN        Size
+  )
+/*++
+  
+Routine Description:
+
+  This function calculates the UINT16 sum for the requested region.
+
+Arguments:
+
+  Buffer      Pointer to buffer containing byte data of component.
+  Size        Size of the buffer
+
+Returns:
+
+  The 16 bit checksum
+
+--*/
+{
+  UINTN   Index;
+  UINT16  Sum;
+
+  Sum = 0;
+
+  //
+  // Perform the word sum for buffer
+  //
+  for (Index = 0; Index < Size; Index++) {
+    Sum = (UINT16) (Sum + Buffer[Index]);
+  }
+
+  return (UINT16) Sum;
+}
+
+EFI_STATUS
+PrintGuid (
+  IN EFI_GUID *Guid
+  )
+/*++
+
+Routine Description:
+
+  This function prints a GUID to STDOUT.
+
+Arguments:
+
+  Guid    Pointer to a GUID to print.
+
+Returns:
+
+  EFI_SUCCESS             The GUID was printed.
+  EFI_INVALID_PARAMETER   The input was NULL.
+
+--*/
+{
+  if (Guid == NULL) {
+    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
+    return EFI_INVALID_PARAMETER;
+  }
+
+  printf (
+    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+    (unsigned) Guid->Data1,
+    Guid->Data2,
+    Guid->Data3,
+    Guid->Data4[0],
+    Guid->Data4[1],
+    Guid->Data4[2],
+    Guid->Data4[3],
+    Guid->Data4[4],
+    Guid->Data4[5],
+    Guid->Data4[6],
+    Guid->Data4[7]
+    );
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PrintGuidToBuffer (
+  IN EFI_GUID     *Guid,
+  IN OUT UINT8    *Buffer,
+  IN UINT32       BufferLen,
+  IN BOOLEAN      Uppercase
+  )
+/*++
+
+Routine Description:
+
+  This function prints a GUID to a buffer
+
+Arguments:
+
+  Guid      - Pointer to a GUID to print.
+  Buffer    - Pointer to a user-provided buffer to print to
+  BufferLen - Size of the Buffer
+  Uppercase - If use upper case.
+
+Returns:
+
+  EFI_SUCCESS             The GUID was printed.
+  EFI_INVALID_PARAMETER   The input was NULL.
+  EFI_BUFFER_TOO_SMALL    The input buffer was not big enough
+  
+--*/
+{
+  if (Guid == NULL) {
+    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {
+    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  if (Uppercase) {
+    sprintf (
+      (CHAR8 *)Buffer,
+      "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+      (unsigned) Guid->Data1,
+      Guid->Data2,
+      Guid->Data3,
+      Guid->Data4[0],
+      Guid->Data4[1],
+      Guid->Data4[2],
+      Guid->Data4[3],
+      Guid->Data4[4],
+      Guid->Data4[5],
+      Guid->Data4[6],
+      Guid->Data4[7]
+      );
+  } else {
+    sprintf (
+      (CHAR8 *)Buffer,
+      "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+      (unsigned) Guid->Data1,
+      Guid->Data2,
+      Guid->Data3,
+      Guid->Data4[0],
+      Guid->Data4[1],
+      Guid->Data4[2],
+      Guid->Data4[3],
+      Guid->Data4[4],
+      Guid->Data4[5],
+      Guid->Data4[6],
+      Guid->Data4[7]
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+#ifdef __GNUC__
+
+size_t _filelength(int fd)
+{
+  struct stat stat_buf;
+  fstat(fd, &stat_buf);
+  return stat_buf.st_size;
+}
+
+#ifndef __CYGWIN__
+char *strlwr(char *s)
+{
+  char *p = s;
+  for(;*s;s++) {
+    *s = tolower(*s);
+  }
+  return p;
+}
+#endif
+#endif
+
+#define WINDOWS_EXTENSION_PATH "\\\\?\\"
+#define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
+
+//
+// Global data to store full file path. It is not required to be free. 
+//
+CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];
+
+CHAR8 *
+LongFilePath (
+ IN CHAR8 *FileName
+ )
+/*++
+
+Routine Description:
+  Convert FileName to the long file path, which can support larger than 260 length. 
+
+Arguments:
+  FileName         - FileName. 
+
+Returns:
+  LongFilePath      A pointer to the converted long file path.
+  
+--*/
+{
+#ifdef __GNUC__
+  //
+  // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here. 
+  // unix has no limitation on file path. Just return FileName. 
+  //
+  return FileName;
+#else
+  CHAR8 *RootPath;
+  CHAR8 *PathPointer;
+  CHAR8 *NextPointer;
+  
+  PathPointer = (CHAR8 *) FileName;
+  
+  if (FileName != NULL) {
+    //
+    // Add the extension string first to support long file path. 
+    //
+    mCommonLibFullPath[0] = 0;
+    strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);
+
+    if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {
+      //
+      // network path like \\server\share to \\?\UNC\server\share
+      //
+      strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);
+      FileName ++;
+    } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {
+      //
+      // Relative file path. Convert it to absolute path. 
+      //
+      RootPath = getcwd (NULL, 0);
+      if (RootPath != NULL) {
+        strcat (mCommonLibFullPath, RootPath);
+        if (FileName[0] != '\\' && FileName[0] != '/') {
+          //
+          // Attach directory separator
+          //
+          strcat (mCommonLibFullPath, "\\");
+        }
+        free (RootPath);
+      }
+    }
+
+    //
+    // Construct the full file path
+    //
+    strcat (mCommonLibFullPath, FileName);
+    
+    //
+    // Convert directory separator '/' to '\\'
+    //
+    PathPointer = (CHAR8 *) mCommonLibFullPath;
+    do {
+      if (*PathPointer == '/') {
+        *PathPointer = '\\';
+      }
+    } while (*PathPointer ++ != '\0');
+    
+    //
+    // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
+    //
+    if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {
+      *(PathPointer + 2) = '\0';
+      strcat (mCommonLibFullPath, PathPointer + 3);
+    }
+        
+    //
+    // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
+    //
+    while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {
+      *PathPointer = '\0';
+      strcat (mCommonLibFullPath, PathPointer + 2);
+    }
+    
+    //
+    // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
+    //
+    while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {
+      NextPointer = PathPointer + 3;
+      do {
+        PathPointer --;
+      } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');
+
+      if (*PathPointer == '\\') {
+        //
+        // Skip one directory
+        //
+        *PathPointer = '\0';
+        strcat (mCommonLibFullPath, NextPointer);
+      } else {
+        //
+        // No directory is found. Just break.
+        //
+        break;
+      }
+    }
+    
+    PathPointer = mCommonLibFullPath;
+  }
+  
+  return PathPointer;
+#endif
+}
diff --git a/EfiRom/Common/CommonLib.h b/EfiRom/Common/CommonLib.h
new file mode 100644
index 0000000..ab1b89b
--- /dev/null
+++ b/EfiRom/Common/CommonLib.h
@@ -0,0 +1,194 @@
+/** @file
+Common library assistance routines.
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_COMMON_LIB_H
+#define _EFI_COMMON_LIB_H
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/BuildVersion.h>
+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination
+
+#define MAX_LONG_FILE_PATH 500
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// Function declarations
+//
+VOID
+PeiZeroMem (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+  )
+;
+
+VOID
+PeiCopyMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  )
+;
+
+VOID
+ZeroMem (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+  )
+;
+
+VOID
+CopyMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  )
+;
+
+INTN
+CompareGuid (
+  IN EFI_GUID     *Guid1,
+  IN EFI_GUID     *Guid2
+  )
+;
+
+EFI_STATUS
+GetFileImage (
+  IN CHAR8    *InputFileName,
+  OUT CHAR8   **InputFileImage,
+  OUT UINT32  *BytesRead
+  )
+;
+
+EFI_STATUS
+PutFileImage (
+  IN CHAR8    *OutputFileName,
+  IN CHAR8    *OutputFileImage,
+  IN UINT32   BytesToWrite
+  )
+;
+/*++
+
+Routine Description:
+
+  This function opens a file and writes OutputFileImage into the file.
+
+Arguments:
+
+  OutputFileName     The name of the file to write.
+  OutputFileImage    A pointer to the memory buffer.
+  BytesToWrite       The size of the memory buffer.
+
+Returns:
+
+  EFI_SUCCESS              The function completed successfully.
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
+  EFI_ABORTED              An error occurred.
+  EFI_OUT_OF_RESOURCES     No resource to complete operations.
+
+**/
+
+UINT8
+CalculateChecksum8 (
+  IN UINT8        *Buffer,
+  IN UINTN        Size
+  )
+;
+
+UINT8
+CalculateSum8 (
+  IN UINT8        *Buffer,
+  IN UINTN        Size
+  )
+;
+
+UINT16
+CalculateChecksum16 (
+  IN UINT16       *Buffer,
+  IN UINTN        Size
+  )
+;
+
+UINT16
+CalculateSum16 (
+  IN UINT16       *Buffer,
+  IN UINTN        Size
+  )
+;
+
+EFI_STATUS
+PrintGuid (
+  IN EFI_GUID                     *Guid
+  )
+;
+
+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination
+EFI_STATUS
+PrintGuidToBuffer (
+  IN EFI_GUID     *Guid,
+  IN OUT UINT8    *Buffer,
+  IN UINT32       BufferLen,
+  IN BOOLEAN      Uppercase
+  )
+;
+
+CHAR8 *
+LongFilePath (
+ IN CHAR8 *FileName
+);
+/*++
+
+Routine Description:
+  Convert FileName to the long file path, which can support larger than 260 length. 
+
+Arguments:
+  FileName         - FileName. 
+
+Returns:
+  LongFilePath      A pointer to the converted long file path.
+  
+--*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#define ASSERT(x) assert(x)
+
+#ifdef __GNUC__
+#include <stdio.h>
+#include <sys/stat.h>
+#define stricmp strcasecmp
+#define _stricmp strcasecmp
+#define strnicmp strncasecmp
+#define strcmpi strcasecmp
+size_t _filelength(int fd);
+#ifndef __CYGWIN__
+char *strlwr(char *s);
+#endif
+#endif
+
+//
+// On windows, mkdir only has one parameter.
+// On unix, it has two parameters
+//
+#if defined(__GNUC__)
+#define mkdir(dir, perm) mkdir(dir, perm)
+#else
+#define mkdir(dir, perm) mkdir(dir)
+#endif
+
+#endif
diff --git a/EfiRom/Common/Compress.h b/EfiRom/Common/Compress.h
new file mode 100644
index 0000000..09d8b8d
--- /dev/null
+++ b/EfiRom/Common/Compress.h
@@ -0,0 +1,88 @@
+/** @file
+Header file for compression routine.
+Providing both EFI and Tiano Compress algorithms.
+  
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+  
+**/
+
+#ifndef _COMPRESS_H_
+#define _COMPRESS_H_
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "CommonLib.h"
+#include <Common/UefiBaseTypes.h>
+/*++
+
+Routine Description:
+
+  Tiano compression routine.
+
+--*/
+EFI_STATUS
+TianoCompress (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  )
+;
+
+/*++
+
+Routine Description:
+
+  Efi compression routine.
+
+--*/
+EFI_STATUS
+EfiCompress (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  )
+;
+
+/*++
+
+Routine Description:
+
+  The compression routine.
+
+Arguments:
+
+  SrcBuffer   - The buffer storing the source data
+  SrcSize     - The size of source data
+  DstBuffer   - The buffer to store the compressed data
+  DstSize     - On input, the size of DstBuffer; On output,
+                the size of the actual compressed data.
+
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,
+                DstSize contains the size needed.
+  EFI_SUCCESS           - Compression is successful.
+  EFI_OUT_OF_RESOURCES  - No resource to complete function.
+  EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+--*/
+typedef
+EFI_STATUS
+(*COMPRESS_FUNCTION) (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  );
+
+#endif
diff --git a/EfiRom/Common/EfiCompress.c b/EfiRom/Common/EfiCompress.c
new file mode 100644
index 0000000..71c6f3b
--- /dev/null
+++ b/EfiRom/Common/EfiCompress.c
@@ -0,0 +1,1590 @@
+/** @file
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman 
+coding. LZ77 transforms the source data into a sequence of Original Characters 
+and Pointers to repeated strings. This sequence is further divided into Blocks 
+and Huffman codings are applied to each Block.
+  
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#include "Compress.h"
+
+
+//
+// Macro Definitions
+//
+
+#undef UINT8_MAX
+typedef INT16             NODE;
+#define UINT8_MAX         0xff
+#define UINT8_BIT         8
+#define THRESHOLD         3
+#define INIT_CRC          0
+#define WNDBIT            13
+#define WNDSIZ            (1U << WNDBIT)
+#define MAXMATCH          256
+#define PERC_FLAG         0x8000U
+#define CODE_BIT          16
+#define NIL               0
+#define MAX_HASH_VAL      (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c)        ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY           0xA001
+#define UPDATE_CRC(c)     mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+
+//
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set
+//
+
+#define NC                (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT              9
+#define NP                (WNDBIT + 1)
+#define PBIT              4
+#define NT                (CODE_BIT + 3)
+#define TBIT              5
+#if NT > NP
+  #define                 NPT NT
+#else
+  #define                 NPT NP
+#endif
+
+//
+// Function Prototypes
+//
+
+STATIC
+VOID 
+PutDword(
+  IN UINT32 Data
+  );
+
+STATIC
+EFI_STATUS 
+AllocateMemory (
+  );
+
+STATIC
+VOID
+FreeMemory (
+  );
+
+STATIC 
+VOID 
+InitSlide (
+  );
+
+STATIC 
+NODE 
+Child (
+  IN NODE q, 
+  IN UINT8 c
+  );
+
+STATIC 
+VOID 
+MakeChild (
+  IN NODE q, 
+  IN UINT8 c, 
+  IN NODE r
+  );
+  
+STATIC 
+VOID 
+Split (
+  IN NODE Old
+  );
+
+STATIC 
+VOID 
+InsertNode (
+  );
+  
+STATIC 
+VOID 
+DeleteNode (
+  );
+
+STATIC 
+VOID 
+GetNextMatch (
+  );
+  
+STATIC 
+EFI_STATUS 
+Encode (
+  );
+
+STATIC 
+VOID 
+CountTFreq (
+  );
+
+STATIC 
+VOID 
+WritePTLen (
+  IN INT32 n, 
+  IN INT32 nbit, 
+  IN INT32 Special
+  );
+
+STATIC 
+VOID 
+WriteCLen (
+  );
+  
+STATIC 
+VOID 
+EncodeC (
+  IN INT32 c
+  );
+
+STATIC 
+VOID 
+EncodeP (
+  IN UINT32 p
+  );
+
+STATIC 
+VOID 
+SendBlock (
+  );
+  
+STATIC 
+VOID 
+Output (
+  IN UINT32 c, 
+  IN UINT32 p
+  );
+
+STATIC 
+VOID 
+HufEncodeStart (
+  );
+  
+STATIC 
+VOID 
+HufEncodeEnd (
+  );
+  
+STATIC 
+VOID 
+MakeCrcTable (
+  );
+  
+STATIC 
+VOID 
+PutBits (
+  IN INT32 n, 
+  IN UINT32 x
+  );
+  
+STATIC 
+INT32 
+FreadCrc (
+  OUT UINT8 *p, 
+  IN  INT32 n
+  );
+  
+STATIC 
+VOID 
+InitPutBits (
+  );
+  
+STATIC 
+VOID 
+CountLen (
+  IN INT32 i
+  );
+
+STATIC 
+VOID 
+MakeLen (
+  IN INT32 Root
+  );
+  
+STATIC 
+VOID 
+DownHeap (
+  IN INT32 i
+  );
+
+STATIC 
+VOID 
+MakeCode (
+  IN  INT32 n, 
+  IN  UINT8 Len[], 
+  OUT UINT16 Code[]
+  );
+  
+STATIC 
+INT32 
+MakeTree (
+  IN  INT32   NParm, 
+  IN  UINT16  FreqParm[], 
+  OUT UINT8   LenParm[], 
+  OUT UINT16  CodeParm[]
+  );
+
+
+//
+//  Global Variables
+//
+
+STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
+
+STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
+STATIC INT16  mHeap[NC + 1];
+STATIC INT32  mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
+
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1],
+              mCrcTable[UINT8_MAX + 1], mCFreq[2 * NC - 1],mCCode[NC],
+              mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
+
+STATIC NODE   mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
+
+
+//
+// functions
+//
+
+EFI_STATUS
+EfiCompress (
+  IN      UINT8   *SrcBuffer,
+  IN      UINT32  SrcSize,
+  IN      UINT8   *DstBuffer,
+  IN OUT  UINT32  *DstSize
+  )
+/*++
+
+Routine Description:
+
+  The main compression routine.
+
+Arguments:
+
+  SrcBuffer   - The buffer storing the source data
+  SrcSize     - The size of source data
+  DstBuffer   - The buffer to store the compressed data
+  DstSize     - On input, the size of DstBuffer; On output,
+                the size of the actual compressed data.
+
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,
+                DstSize contains the size needed.
+  EFI_SUCCESS           - Compression is successful.
+
+--*/
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  
+  //
+  // Initializations
+  //
+  mBufSiz = 0;
+  mBuf = NULL;
+  mText       = NULL;
+  mLevel      = NULL;
+  mChildCount = NULL;
+  mPosition   = NULL;
+  mParent     = NULL;
+  mPrev       = NULL;
+  mNext       = NULL;
+
+  
+  mSrc = SrcBuffer;
+  mSrcUpperLimit = mSrc + SrcSize;
+  mDst = DstBuffer;
+  mDstUpperLimit = mDst + *DstSize;
+
+  PutDword(0L);
+  PutDword(0L);
+  
+  MakeCrcTable ();
+
+  mOrigSize = mCompSize = 0;
+  mCrc = INIT_CRC;
+  
+  //
+  // Compress it
+  //
+  
+  Status = Encode();
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  
+  //
+  // Null terminate the compressed data
+  //
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = 0;
+  }
+  
+  //
+  // Fill in compressed size and original size
+  //
+  mDst = DstBuffer;
+  PutDword(mCompSize+1);
+  PutDword(mOrigSize);
+
+  //
+  // Return
+  //
+  
+  if (mCompSize + 1 + 8 > *DstSize) {
+    *DstSize = mCompSize + 1 + 8;
+    return EFI_BUFFER_TOO_SMALL;
+  } else {
+    *DstSize = mCompSize + 1 + 8;
+    return EFI_SUCCESS;
+  }
+
+}
+
+STATIC 
+VOID 
+PutDword(
+  IN UINT32 Data
+  )
+/*++
+
+Routine Description:
+
+  Put a dword to output stream
+  
+Arguments:
+
+  Data    - the dword to put
+  
+Returns: (VOID)
+  
+--*/
+{
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8)(((UINT8)(Data        )) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x08)) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x10)) & 0xff);
+  }
+
+  if (mDst < mDstUpperLimit) {
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x18)) & 0xff);
+  }
+}
+
+STATIC
+EFI_STATUS
+AllocateMemory ()
+/*++
+
+Routine Description:
+
+  Allocate memory spaces for data structures used in compression process
+  
+Argements: (VOID)
+
+Returns:
+
+  EFI_SUCCESS           - Memory is allocated successfully
+  EFI_OUT_OF_RESOURCES  - Allocation fails
+
+--*/
+{
+  UINT32      i;
+  
+  mText       = malloc (WNDSIZ * 2 + MAXMATCH);
+  for (i = 0 ; i < WNDSIZ * 2 + MAXMATCH; i ++) {
+    mText[i] = 0;
+  }
+
+  mLevel      = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
+  mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
+  mPosition   = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
+  mParent     = malloc (WNDSIZ * 2 * sizeof(*mParent));
+  mPrev       = malloc (WNDSIZ * 2 * sizeof(*mPrev));
+  mNext       = malloc ((MAX_HASH_VAL + 1) * sizeof(*mNext));
+  
+  mBufSiz = 16 * 1024U;
+  while ((mBuf = malloc(mBufSiz)) == NULL) {
+    mBufSiz = (mBufSiz / 10U) * 9U;
+    if (mBufSiz < 4 * 1024U) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  }
+  mBuf[0] = 0;
+  
+  return EFI_SUCCESS;
+}
+
+VOID
+FreeMemory ()
+/*++
+
+Routine Description:
+
+  Called when compression is completed to free memory previously allocated.
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  if (mText) {
+    free (mText);
+  }
+  
+  if (mLevel) {
+    free (mLevel);
+  }
+  
+  if (mChildCount) {
+    free (mChildCount);
+  }
+  
+  if (mPosition) {
+    free (mPosition);
+  }
+  
+  if (mParent) {
+    free (mParent);
+  }
+  
+  if (mPrev) {
+    free (mPrev);
+  }
+  
+  if (mNext) {
+    free (mNext);
+  }
+  
+  if (mBuf) {
+    free (mBuf);
+  }  
+
+  return;
+}
+
+
+STATIC 
+VOID 
+InitSlide ()
+/*++
+
+Routine Description:
+
+  Initialize String Info Log data structures
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE i;
+
+  for (i = WNDSIZ; i <= WNDSIZ + UINT8_MAX; i++) {
+    mLevel[i] = 1;
+    mPosition[i] = NIL;  /* sentinel */
+  }
+  for (i = WNDSIZ; i < WNDSIZ * 2; i++) {
+    mParent[i] = NIL;
+  }  
+  mAvail = 1;
+  for (i = 1; i < WNDSIZ - 1; i++) {
+    mNext[i] = (NODE)(i + 1);
+  }
+  
+  mNext[WNDSIZ - 1] = NIL;
+  for (i = WNDSIZ * 2; i <= MAX_HASH_VAL; i++) {
+    mNext[i] = NIL;
+  }  
+}
+
+
+STATIC 
+NODE 
+Child (
+  IN NODE q, 
+  IN UINT8 c
+  )
+/*++
+
+Routine Description:
+
+  Find child node given the parent node and the edge character
+  
+Arguments:
+
+  q       - the parent node
+  c       - the edge character
+  
+Returns:
+
+  The child node (NIL if not found)  
+  
+--*/
+{
+  NODE r;
+  
+  r = mNext[HASH(q, c)];
+  mParent[NIL] = q;  /* sentinel */
+  while (mParent[r] != q) {
+    r = mNext[r];
+  }
+  
+  return r;
+}
+
+STATIC 
+VOID 
+MakeChild (
+  IN NODE q, 
+  IN UINT8 c, 
+  IN NODE r
+  )
+/*++
+
+Routine Description:
+
+  Create a new child for a given parent node.
+  
+Arguments:
+
+  q       - the parent node
+  c       - the edge character
+  r       - the child node
+  
+Returns: (VOID)
+
+--*/
+{
+  NODE h, t;
+  
+  h = (NODE)HASH(q, c);
+  t = mNext[h];
+  mNext[h] = r;
+  mNext[r] = t;
+  mPrev[t] = r;
+  mPrev[r] = h;
+  mParent[r] = q;
+  mChildCount[q]++;
+}
+
+STATIC 
+VOID 
+Split (
+  NODE Old
+  )
+/*++
+
+Routine Description:
+
+  Split a node.
+  
+Arguments:
+
+  Old     - the node to split
+  
+Returns: (VOID)
+
+--*/
+{
+  NODE New, t;
+
+  New = mAvail;
+  mAvail = mNext[New];
+  mChildCount[New] = 0;
+  t = mPrev[Old];
+  mPrev[New] = t;
+  mNext[t] = New;
+  t = mNext[Old];
+  mNext[New] = t;
+  mPrev[t] = New;
+  mParent[New] = mParent[Old];
+  mLevel[New] = (UINT8)mMatchLen;
+  mPosition[New] = mPos;
+  MakeChild(New, mText[mMatchPos + mMatchLen], Old);
+  MakeChild(New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC 
+VOID 
+InsertNode ()
+/*++
+
+Routine Description:
+
+  Insert string info for current position into the String Info Log
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE q, r, j, t;
+  UINT8 c, *t1, *t2;
+
+  if (mMatchLen >= 4) {
+    
+    //
+    // We have just got a long match, the target tree
+    // can be located by MatchPos + 1. Travese the tree
+    // from bottom up to get to a proper starting point.
+    // The usage of PERC_FLAG ensures proper node deletion
+    // in DeleteNode() later.
+    //
+    
+    mMatchLen--;
+    r = (INT16)((mMatchPos + 1) | WNDSIZ);
+    while ((q = mParent[r]) == NIL) {
+      r = mNext[r];
+    }
+    while (mLevel[q] >= mMatchLen) {
+      r = q;  q = mParent[q];
+    }
+    t = q;
+    while (mPosition[t] < 0) {
+      mPosition[t] = mPos;
+      t = mParent[t];
+    }
+    if (t < WNDSIZ) {
+      mPosition[t] = (NODE)(mPos | PERC_FLAG);
+    }    
+  } else {
+    
+    //
+    // Locate the target tree
+    //
+    
+    q = (INT16)(mText[mPos] + WNDSIZ);
+    c = mText[mPos + 1];
+    if ((r = Child(q, c)) == NIL) {
+      MakeChild(q, c, mPos);
+      mMatchLen = 1;
+      return;
+    }
+    mMatchLen = 2;
+  }
+  
+  //
+  // Traverse down the tree to find a match.
+  // Update Position value along the route.
+  // Node split or creation is involved.
+  //
+  
+  for ( ; ; ) {
+    if (r >= WNDSIZ) {
+      j = MAXMATCH;
+      mMatchPos = r;
+    } else {
+      j = mLevel[r];
+      mMatchPos = (NODE)(mPosition[r] & ~PERC_FLAG);
+    }
+    if (mMatchPos >= mPos) {
+      mMatchPos -= WNDSIZ;
+    }    
+    t1 = &mText[mPos + mMatchLen];
+    t2 = &mText[mMatchPos + mMatchLen];
+    while (mMatchLen < j) {
+      if (*t1 != *t2) {
+        Split(r);
+        return;
+      }
+      mMatchLen++;
+      t1++;
+      t2++;
+    }
+    if (mMatchLen >= MAXMATCH) {
+      break;
+    }
+    mPosition[r] = mPos;
+    q = r;
+    if ((r = Child(q, *t1)) == NIL) {
+      MakeChild(q, *t1, mPos);
+      return;
+    }
+    mMatchLen++;
+  }
+  t = mPrev[r];
+  mPrev[mPos] = t;
+  mNext[t] = mPos;
+  t = mNext[r];
+  mNext[mPos] = t;
+  mPrev[t] = mPos;
+  mParent[mPos] = q;
+  mParent[r] = NIL;
+  
+  //
+  // Special usage of 'next'
+  //
+  mNext[r] = mPos;
+  
+}
+
+STATIC 
+VOID 
+DeleteNode ()
+/*++
+
+Routine Description:
+
+  Delete outdated string info. (The Usage of PERC_FLAG
+  ensures a clean deletion)
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  NODE q, r, s, t, u;
+
+  if (mParent[mPos] == NIL) {
+    return;
+  }
+  
+  r = mPrev[mPos];
+  s = mNext[mPos];
+  mNext[r] = s;
+  mPrev[s] = r;
+  r = mParent[mPos];
+  mParent[mPos] = NIL;
+  if (r >= WNDSIZ || --mChildCount[r] > 1) {
+    return;
+  }
+  t = (NODE)(mPosition[r] & ~PERC_FLAG);
+  if (t >= mPos) {
+    t -= WNDSIZ;
+  }
+  s = t;
+  q = mParent[r];
+  while ((u = mPosition[q]) & PERC_FLAG) {
+    u &= ~PERC_FLAG;
+    if (u >= mPos) {
+      u -= WNDSIZ;
+    }
+    if (u > s) {
+      s = u;
+    }
+    mPosition[q] = (INT16)(s | WNDSIZ);
+    q = mParent[q];
+  }
+  if (q < WNDSIZ) {
+    if (u >= mPos) {
+      u -= WNDSIZ;
+    }
+    if (u > s) {
+      s = u;
+    }
+    mPosition[q] = (INT16)(s | WNDSIZ | PERC_FLAG);
+  }
+  s = Child(r, mText[t + mLevel[r]]);
+  t = mPrev[s];
+  u = mNext[s];
+  mNext[t] = u;
+  mPrev[u] = t;
+  t = mPrev[r];
+  mNext[t] = s;
+  mPrev[s] = t;
+  t = mNext[r];
+  mPrev[t] = s;
+  mNext[s] = t;
+  mParent[s] = mParent[r];
+  mParent[r] = NIL;
+  mNext[r] = mAvail;
+  mAvail = r;
+}
+
+STATIC 
+VOID 
+GetNextMatch ()
+/*++
+
+Routine Description:
+
+  Advance the current position (read in new data if needed).
+  Delete outdated string info. Find a match string for current position.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 n;
+
+  mRemainder--;
+  if (++mPos == WNDSIZ * 2) {
+    memmove(&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+    n = FreadCrc(&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+    mRemainder += n;
+    mPos = WNDSIZ;
+  }
+  DeleteNode();
+  InsertNode();
+}
+
+STATIC
+EFI_STATUS
+Encode ()
+/*++
+
+Routine Description:
+
+  The main controlling routine for compression process.
+
+Arguments: (VOID)
+
+Returns:
+  
+  EFI_SUCCESS           - The compression is successful
+  EFI_OUT_0F_RESOURCES  - Not enough memory for compression process
+
+--*/
+{
+  EFI_STATUS  Status;
+  INT32       LastMatchLen;
+  NODE        LastMatchPos;
+
+  Status = AllocateMemory();
+  if (EFI_ERROR(Status)) {
+    FreeMemory();
+    return Status;
+  }
+
+  InitSlide();
+  
+  HufEncodeStart();
+
+  mRemainder = FreadCrc(&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+  
+  mMatchLen = 0;
+  mPos = WNDSIZ;
+  InsertNode();
+  if (mMatchLen > mRemainder) {
+    mMatchLen = mRemainder;
+  }
+  while (mRemainder > 0) {
+    LastMatchLen = mMatchLen;
+    LastMatchPos = mMatchPos;
+    GetNextMatch();
+    if (mMatchLen > mRemainder) {
+      mMatchLen = mRemainder;
+    }
+    
+    if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+      
+      //
+      // Not enough benefits are gained by outputting a pointer,
+      // so just output the original character
+      //
+      
+      Output(mText[mPos - 1], 0);
+    } else {
+      
+      //
+      // Outputting a pointer is beneficial enough, do it.
+      //
+      
+      Output(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+             (mPos - LastMatchPos - 2) & (WNDSIZ - 1));
+      while (--LastMatchLen > 0) {
+        GetNextMatch();
+      }
+      if (mMatchLen > mRemainder) {
+        mMatchLen = mRemainder;
+      }
+    }
+  }
+  
+  HufEncodeEnd();
+  FreeMemory();
+  return EFI_SUCCESS;
+}
+
+STATIC 
+VOID 
+CountTFreq ()
+/*++
+
+Routine Description:
+
+  Count the frequencies for the Extra Set
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 i, k, n, Count;
+
+  for (i = 0; i < NT; i++) {
+    mTFreq[i] = 0;
+  }
+  n = NC;
+  while (n > 0 && mCLen[n - 1] == 0) {
+    n--;
+  }
+  i = 0;
+  while (i < n) {
+    k = mCLen[i++];
+    if (k == 0) {
+      Count = 1;
+      while (i < n && mCLen[i] == 0) {
+        i++;
+        Count++;
+      }
+      if (Count <= 2) {
+        mTFreq[0] = (UINT16)(mTFreq[0] + Count);
+      } else if (Count <= 18) {
+        mTFreq[1]++;
+      } else if (Count == 19) {
+        mTFreq[0]++;
+        mTFreq[1]++;
+      } else {
+        mTFreq[2]++;
+      }
+    } else {
+      mTFreq[k + 2]++;
+    }
+  }
+}
+
+STATIC 
+VOID 
+WritePTLen (
+  IN INT32 n, 
+  IN INT32 nbit, 
+  IN INT32 Special
+  )
+/*++
+
+Routine Description:
+
+  Outputs the code length array for the Extra Set or the Position Set.
+  
+Arguments:
+
+  n       - the number of symbols
+  nbit    - the number of bits needed to represent 'n'
+  Special - the special symbol that needs to be take care of
+  
+Returns: (VOID)
+
+--*/
+{
+  INT32 i, k;
+
+  while (n > 0 && mPTLen[n - 1] == 0) {
+    n--;
+  }
+  PutBits(nbit, n);
+  i = 0;
+  while (i < n) {
+    k = mPTLen[i++];
+    if (k <= 6) {
+      PutBits(3, k);
+    } else {
+      PutBits(k - 3, (1U << (k - 3)) - 2);
+    }
+    if (i == Special) {
+      while (i < 6 && mPTLen[i] == 0) {
+        i++;
+      }
+      PutBits(2, (i - 3) & 3);
+    }
+  }
+}
+
+STATIC 
+VOID 
+WriteCLen ()
+/*++
+
+Routine Description:
+
+  Outputs the code length array for Char&Length Set
+  
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  INT32 i, k, n, Count;
+
+  n = NC;
+  while (n > 0 && mCLen[n - 1] == 0) {
+    n--;
+  }
+  PutBits(CBIT, n);
+  i = 0;
+  while (i < n) {
+    k = mCLen[i++];
+    if (k == 0) {
+      Count = 1;
+      while (i < n && mCLen[i] == 0) {
+        i++;
+        Count++;
+      }
+      if (Count <= 2) {
+        for (k = 0; k < Count; k++) {
+          PutBits(mPTLen[0], mPTCode[0]);
+        }
+      } else if (Count <= 18) {
+        PutBits(mPTLen[1], mPTCode[1]);
+        PutBits(4, Count - 3);
+      } else if (Count == 19) {
+        PutBits(mPTLen[0], mPTCode[0]);
+        PutBits(mPTLen[1], mPTCode[1]);
+        PutBits(4, 15);
+      } else {
+        PutBits(mPTLen[2], mPTCode[2]);
+        PutBits(CBIT, Count - 20);
+      }
+    } else {
+      PutBits(mPTLen[k + 2], mPTCode[k + 2]);
+    }
+  }
+}
+
+STATIC 
+VOID 
+EncodeC (
+  IN INT32 c
+  )
+{
+  PutBits(mCLen[c], mCCode[c]);
+}
+
+STATIC 
+VOID 
+EncodeP (
+  IN UINT32 p
+  )
+{
+  UINT32 c, q;
+
+  c = 0;
+  q = p;
+  while (q) {
+    q >>= 1;
+    c++;
+  }
+  PutBits(mPTLen[c], mPTCode[c]);
+  if (c > 1) {
+    PutBits(c - 1, p & (0xFFFFU >> (17 - c)));
+  }
+}
+
+STATIC 
+VOID 
+SendBlock ()
+/*++
+
+Routine Description:
+
+  Huffman code the block and output it.
+  
+Argument: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+  UINT32 i, k, Flags, Root, Pos, Size;
+  Flags = 0;
+
+  Root = MakeTree(NC, mCFreq, mCLen, mCCode);
+  Size = mCFreq[Root];
+  PutBits(16, Size);
+  if (Root >= NC) {
+    CountTFreq();
+    Root = MakeTree(NT, mTFreq, mPTLen, mPTCode);
+    if (Root >= NT) {
+      WritePTLen(NT, TBIT, 3);
+    } else {
+      PutBits(TBIT, 0);
+      PutBits(TBIT, Root);
+    }
+    WriteCLen();
+  } else {
+    PutBits(TBIT, 0);
+    PutBits(TBIT, 0);
+    PutBits(CBIT, 0);
+    PutBits(CBIT, Root);
+  }
+  Root = MakeTree(NP, mPFreq, mPTLen, mPTCode);
+  if (Root >= NP) {
+    WritePTLen(NP, PBIT, -1);
+  } else {
+    PutBits(PBIT, 0);
+    PutBits(PBIT, Root);
+  }
+  Pos = 0;
+  for (i = 0; i < Size; i++) {
+    if (i % UINT8_BIT == 0) {
+      Flags = mBuf[Pos++];
+    } else {
+      Flags <<= 1;
+    }
+    if (Flags & (1U << (UINT8_BIT - 1))) {
+      EncodeC(mBuf[Pos++] + (1U << UINT8_BIT));
+      k = mBuf[Pos++] << UINT8_BIT;
+      k += mBuf[Pos++];
+      EncodeP(k);
+    } else {
+      EncodeC(mBuf[Pos++]);
+    }
+  }
+  for (i = 0; i < NC; i++) {
+    mCFreq[i] = 0;
+  }
+  for (i = 0; i < NP; i++) {
+    mPFreq[i] = 0;
+  }
+}
+
+
+STATIC 
+VOID 
+Output (
+  IN UINT32 c, 
+  IN UINT32 p
+  )
+/*++
+
+Routine Description:
+
+  Outputs an Original Character or a Pointer
+
+Arguments:
+
+  c     - The original character or the 'String Length' element of a Pointer
+  p     - The 'Position' field of a Pointer
+
+Returns: (VOID)
+
+--*/
+{
+  STATIC UINT32 CPos;
+
+  if ((mOutputMask >>= 1) == 0) {
+    mOutputMask = 1U << (UINT8_BIT - 1);
+    if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) {
+      SendBlock();
+      mOutputPos = 0;
+    }
+    CPos = mOutputPos++;  
+    mBuf[CPos] = 0;
+  }
+  mBuf[mOutputPos++] = (UINT8) c;
+  mCFreq[c]++;
+  if (c >= (1U << UINT8_BIT)) {
+    mBuf[CPos] |= mOutputMask;
+    mBuf[mOutputPos++] = (UINT8)(p >> UINT8_BIT);
+    mBuf[mOutputPos++] = (UINT8) p;
+    c = 0;
+    while (p) {
+      p >>= 1;
+      c++;
+    }
+    mPFreq[c]++;
+  }
+}
+
+STATIC
+VOID
+HufEncodeStart ()
+{
+  INT32 i;
+
+  for (i = 0; i < NC; i++) {
+    mCFreq[i] = 0;
+  }
+  for (i = 0; i < NP; i++) {
+    mPFreq[i] = 0;
+  }
+  mOutputPos = mOutputMask = 0;
+  InitPutBits();
+  return;
+}
+
+STATIC 
+VOID 
+HufEncodeEnd ()
+{
+  SendBlock();
+  
+  //
+  // Flush remaining bits
+  //
+  PutBits(UINT8_BIT - 1, 0);
+  
+  return;
+}
+
+
+STATIC 
+VOID 
+MakeCrcTable ()
+{
+  UINT32 i, j, r;
+
+  for (i = 0; i <= UINT8_MAX; i++) {
+    r = i;
+    for (j = 0; j < UINT8_BIT; j++) {
+      if (r & 1) {
+        r = (r >> 1) ^ CRCPOLY;
+      } else {
+        r >>= 1;
+      }
+    }
+    mCrcTable[i] = (UINT16)r;    
+  }
+}
+
+STATIC 
+VOID 
+PutBits (
+  IN INT32 n, 
+  IN UINT32 x
+  )
+/*++
+
+Routine Description:
+
+  Outputs rightmost n bits of x
+
+Argments:
+
+  n   - the rightmost n bits of the data is used
+  x   - the data 
+
+Returns: (VOID)
+
+--*/
+{
+  UINT8 Temp;  
+  
+  if (n < mBitCount) {
+    mSubBitBuf |= x << (mBitCount -= n);
+  } else {
+      
+    Temp = (UINT8)(mSubBitBuf | (x >> (n -= mBitCount)));
+    if (mDst < mDstUpperLimit) {
+      *mDst++ = Temp;
+    }
+    mCompSize++;
+
+    if (n < UINT8_BIT) {
+      mSubBitBuf = x << (mBitCount = UINT8_BIT - n);
+    } else {
+        
+      Temp = (UINT8)(x >> (n - UINT8_BIT));
+      if (mDst < mDstUpperLimit) {
+        *mDst++ = Temp;
+      }
+      mCompSize++;
+      
+      mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - n);
+    }
+  }
+}
+
+STATIC 
+INT32 
+FreadCrc (
+  OUT UINT8 *p, 
+  IN  INT32 n
+  )
+/*++
+
+Routine Description:
+
+  Read in source data
+  
+Arguments:
+
+  p   - the buffer to hold the data
+  n   - number of bytes to read
+
+Returns:
+
+  number of bytes actually read
+  
+--*/
+{
+  INT32 i;
+
+  for (i = 0; mSrc < mSrcUpperLimit && i < n; i++) {
+    *p++ = *mSrc++;
+  }
+  n = i;
+
+  p -= n;
+  mOrigSize += n;
+  while (--i >= 0) {
+    UPDATE_CRC(*p++);
+  }
+  return n;
+}
+
+
+STATIC 
+VOID 
+InitPutBits ()
+{
+  mBitCount = UINT8_BIT;  
+  mSubBitBuf = 0;
+}
+
+STATIC 
+VOID 
+CountLen (
+  IN INT32 i
+  )
+/*++
+
+Routine Description:
+
+  Count the number of each code length for a Huffman tree.
+  
+Arguments:
+
+  i   - the top node
+  
+Returns: (VOID)
+
+--*/
+{
+  STATIC INT32 Depth = 0;
+
+  if (i < mN) {
+    mLenCnt[(Depth < 16) ? Depth : 16]++;
+  } else {
+    Depth++;
+    CountLen(mLeft [i]);
+    CountLen(mRight[i]);
+    Depth--;
+  }
+}
+
+STATIC 
+VOID 
+MakeLen (
+  IN INT32 Root
+  )
+/*++
+
+Routine Description:
+
+  Create code length array for a Huffman tree
+  
+Arguments:
+
+  Root   - the root of the tree
+
+--*/
+{
+  INT32 i, k;
+  UINT32 Cum;
+
+  for (i = 0; i <= 16; i++) {
+    mLenCnt[i] = 0;
+  }
+  CountLen(Root);
+  
+  //
+  // Adjust the length count array so that
+  // no code will be generated longer than its designated length
+  //
+  
+  Cum = 0;
+  for (i = 16; i > 0; i--) {
+    Cum += mLenCnt[i] << (16 - i);
+  }
+  while (Cum != (1U << 16)) {
+    mLenCnt[16]--;
+    for (i = 15; i > 0; i--) {
+      if (mLenCnt[i] != 0) {
+        mLenCnt[i]--;
+        mLenCnt[i+1] += 2;
+        break;
+      }
+    }
+    Cum--;
+  }
+  for (i = 16; i > 0; i--) {
+    k = mLenCnt[i];
+    while (--k >= 0) {
+      mLen[*mSortPtr++] = (UINT8)i;
+    }
+  }
+}
+
+STATIC 
+VOID 
+DownHeap (
+  IN INT32 i
+  )
+{
+  INT32 j, k;
+
+  //
+  // priority queue: send i-th entry down heap
+  //
+  
+  k = mHeap[i];
+  while ((j = 2 * i) <= mHeapSize) {
+    if (j < mHeapSize && mFreq[mHeap[j]] > mFreq[mHeap[j + 1]]) {
+      j++;
+    }
+    if (mFreq[k] <= mFreq[mHeap[j]]) {
+      break;
+    }
+    mHeap[i] = mHeap[j];
+    i = j;
+  }
+  mHeap[i] = (INT16)k;
+}
+
+STATIC 
+VOID 
+MakeCode (
+  IN  INT32 n, 
+  IN  UINT8 Len[], 
+  OUT UINT16 Code[]
+  )
+/*++
+
+Routine Description:
+
+  Assign code to each symbol based on the code length array
+  
+Arguments:
+
+  n     - number of symbols
+  Len   - the code length array
+  Code  - stores codes for each symbol
+
+Returns: (VOID)
+
+--*/
+{
+  INT32    i;
+  UINT16   Start[18];
+
+  Start[1] = 0;
+  for (i = 1; i <= 16; i++) {
+    Start[i + 1] = (UINT16)((Start[i] + mLenCnt[i]) << 1);
+  }
+  for (i = 0; i < n; i++) {
+    Code[i] = Start[Len[i]]++;
+  }
+}
+
+STATIC 
+INT32 
+MakeTree (
+  IN  INT32   NParm, 
+  IN  UINT16  FreqParm[], 
+  OUT UINT8   LenParm[], 
+  OUT UINT16  CodeParm[]
+  )
+/*++
+
+Routine Description:
+
+  Generates Huffman codes given a frequency distribution of symbols
+  
+Arguments:
+
+  NParm    - number of symbols
+  FreqParm - frequency of each symbol
+  LenParm  - code length for each symbol
+  CodeParm - code for each symbol
+  
+Returns:
+
+  Root of the Huffman tree.
+  
+--*/
+{
+  INT32 i, j, k, Avail;
+  
+  //
+  // make tree, calculate len[], return root
+  //
+
+  mN = NParm;
+  mFreq = FreqParm;
+  mLen = LenParm;
+  Avail = mN;
+  mHeapSize = 0;
+  mHeap[1] = 0;
+  for (i = 0; i < mN; i++) {
+    mLen[i] = 0;
+    if (mFreq[i]) {
+      mHeap[++mHeapSize] = (INT16)i;
+    }    
+  }
+  if (mHeapSize < 2) {
+    CodeParm[mHeap[1]] = 0;
+    return mHeap[1];
+  }
+  for (i = mHeapSize / 2; i >= 1; i--) {
+    
+    //
+    // make priority queue 
+    //
+    DownHeap(i);
+  }
+  mSortPtr = CodeParm;
+  do {
+    i = mHeap[1];
+    if (i < mN) {
+      *mSortPtr++ = (UINT16)i;
+    }
+    mHeap[1] = mHeap[mHeapSize--];
+    DownHeap(1);
+    j = mHeap[1];
+    if (j < mN) {
+      *mSortPtr++ = (UINT16)j;
+    }
+    k = Avail++;
+    mFreq[k] = (UINT16)(mFreq[i] + mFreq[j]);
+    mHeap[1] = (INT16)k;
+    DownHeap(1);
+    mLeft[k] = (UINT16)i;
+    mRight[k] = (UINT16)j;
+  } while (mHeapSize > 1);
+  
+  mSortPtr = CodeParm;
+  MakeLen(k);
+  MakeCode(NParm, LenParm, CodeParm);
+  
+  //
+  // return root
+  //
+  return k;
+}
+
diff --git a/EfiRom/Common/EfiUtilityMsgs.c b/EfiRom/Common/EfiUtilityMsgs.c
new file mode 100644
index 0000000..bf837f7
--- /dev/null
+++ b/EfiRom/Common/EfiUtilityMsgs.c
@@ -0,0 +1,906 @@
+/** @file
+EFI tools utility functions to display warning, error, and informational messages
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+--*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include "EfiUtilityMsgs.h"
+
+//
+// Declare module globals for keeping track of the the utility's
+// name and other settings.
+//
+STATIC STATUS mStatus                 = STATUS_SUCCESS;
+STATIC CHAR8  mUtilityName[50]        = { 0 };
+STATIC UINT64 mPrintLogLevel          = INFO_LOG_LEVEL;
+STATIC CHAR8  *mSourceFileName        = NULL;
+STATIC UINT32 mSourceFileLineNum      = 0;
+STATIC UINT32 mErrorCount             = 0;
+STATIC UINT32 mWarningCount           = 0;
+STATIC UINT32 mMaxErrors              = 0;
+STATIC UINT32 mMaxWarnings            = 0;
+STATIC UINT32 mMaxWarningsPlusErrors  = 0;
+STATIC INT8   mPrintLimitsSet         = 0;
+
+STATIC
+VOID
+PrintLimitExceeded (
+  VOID
+  );
+
+VOID
+Error (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  MessageCode,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Prints an error message.
+
+Arguments:
+  All arguments are optional, though the printed message may be useless if
+  at least something valid is not specified.
+
+  FileName - name of the file or application. If not specified, then the
+             utilty name (as set by the utility calling SetUtilityName()
+             earlier) is used. Otherwise "Unknown utility" is used.
+
+  LineNumber - the line number of error, typically used by parsers. If the
+               utility is not a parser, then 0 should be specified. Otherwise
+               the FileName and LineNumber info can be used to cause
+               MS Visual Studio to jump to the error.
+
+  MessageCode - an application-specific error code that can be referenced in
+              other documentation.
+
+  Text        - the text in question, typically used by parsers.
+
+  MsgFmt - the format string for the error message. Can contain formatting
+           controls for use with the varargs.
+
+Returns:
+  None.
+
+Notes:
+  We print the following (similar to the Warn() and Debug()
+  W
+  Typical error/warning message format:
+
+  bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters
+
+  BUGBUG -- these three utility functions are almost identical, and
+  should be modified to share code.
+
+  Visual Studio does not find error messages with:
+
+     " error :"
+     " error 1:"
+     " error c1:"
+     " error 1000:"
+     " error c100:"
+
+  It does find:
+     " error c1000:"
+--*/
+{
+  va_list List;
+  //
+  // If limits have been set, then check that we have not exceeded them
+  //
+  if (mPrintLimitsSet) {
+    //
+    // See if we've exceeded our total count
+    //
+    if (mMaxWarningsPlusErrors != 0) {
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+    //
+    // See if we've exceeded our error count
+    //
+    if (mMaxErrors != 0) {
+      if (mErrorCount > mMaxErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+  }
+
+  mErrorCount++;
+  va_start (List, MsgFmt);
+  PrintMessage ("ERROR", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+ParserError (
+  UINT32  MessageCode,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a parser error, using the source file name and line number
+  set by a previous call to SetParserPosition().
+
+Arguments:
+  MessageCode   - application-specific error code
+  Text          - text to print in the error message
+  MsgFmt        - format string to print at the end of the error message
+
+Returns:
+  NA
+
+--*/
+{
+  va_list List;
+  //
+  // If limits have been set, then check them
+  //
+  if (mPrintLimitsSet) {
+    //
+    // See if we've exceeded our total count
+    //
+    if (mMaxWarningsPlusErrors != 0) {
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+    //
+    // See if we've exceeded our error count
+    //
+    if (mMaxErrors != 0) {
+      if (mErrorCount > mMaxErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+  }
+
+  mErrorCount++;
+  va_start (List, MsgFmt);
+  PrintMessage ("ERROR", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+ParserWarning (
+  UINT32  ErrorCode,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a parser warning, using the source file name and line number
+  set by a previous call to SetParserPosition().
+
+Arguments:
+  ErrorCode     - application-specific error code
+  OffendingText - text to print in the warning message
+  MsgFmt        - format string to print at the end of the warning message
+
+Returns:
+  NA
+
+--*/
+{
+  va_list List;
+  //
+  // If limits have been set, then check them
+  //
+  if (mPrintLimitsSet) {
+    //
+    // See if we've exceeded our total count
+    //
+    if (mMaxWarningsPlusErrors != 0) {
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+    //
+    // See if we've exceeded our warning count
+    //
+    if (mMaxWarnings != 0) {
+      if (mWarningCount > mMaxWarnings) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+  }
+
+  mWarningCount++;
+  va_start (List, MsgFmt);
+  PrintMessage ("WARNING", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);
+  va_end (List);
+  //
+  // Don't set warning status accordingly
+  //
+  //  if (mStatus < STATUS_WARNING) {
+  //    mStatus = STATUS_WARNING;
+  //  }
+}
+
+VOID
+Warning (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  MessageCode,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a warning message.
+
+Arguments:
+  FileName    - name of the file where the warning was detected, or the name
+                of the application that detected the warning
+
+  LineNumber  - the line number where the warning was detected (parsers).
+                0 should be specified if the utility is not a parser.
+
+  MessageCode - an application-specific warning code that can be referenced in
+                other documentation.
+
+  Text        - the text in question (parsers)
+
+  MsgFmt      - the format string for the warning message. Can contain formatting
+                controls for use with varargs.
+
+Returns:
+  None.
+
+--*/
+{
+  va_list List;
+
+  //
+  // Current Print Level not output warning information.
+  //
+  if (WARNING_LOG_LEVEL < mPrintLogLevel) {
+    return;
+  }
+  //
+  // If limits have been set, then check them
+  //
+  if (mPrintLimitsSet) {
+    //
+    // See if we've exceeded our total count
+    //
+    if (mMaxWarningsPlusErrors != 0) {
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+    //
+    // See if we've exceeded our warning count
+    //
+    if (mMaxWarnings != 0) {
+      if (mWarningCount > mMaxWarnings) {
+        PrintLimitExceeded ();
+        return ;
+      }
+    }
+  }
+
+  mWarningCount++;
+  va_start (List, MsgFmt);
+  PrintMessage ("WARNING", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+DebugMsg (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT64  MsgLevel,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a Debug message.
+
+Arguments:
+  FileName    - typically the name of the utility printing the debug message, but
+                can be the name of a file being parsed.
+
+  LineNumber  - the line number in FileName (parsers)
+
+  MsgLevel    - Debug message print level (0~9)
+
+  Text        - the text in question (parsers)
+
+  MsgFmt      - the format string for the debug message. Can contain formatting
+                controls for use with varargs.
+
+Returns:
+  None.
+
+--*/
+{
+  va_list List;
+  //
+  // If the debug level is less than current print level, then do nothing.
+  //
+  if (MsgLevel < mPrintLogLevel) {
+    return ;
+  }
+
+  va_start (List, MsgFmt);
+  PrintMessage ("DEBUG", FileName, LineNumber, 0, Text, MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+PrintMessage (
+  CHAR8   *Type,
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  MessageCode,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  va_list List
+  )
+/*++
+
+Routine Description:
+  Worker routine for all the utility printing services. Prints the message in
+  a format that Visual Studio will find when scanning build outputs for
+  errors or warnings.
+
+Arguments:
+  Type        - "warning" or "error" string to insert into the message to be
+                printed. The first character of this string (converted to uppercase)
+                is used to preceed the MessageCode value in the output string.
+
+  FileName    - name of the file where the warning was detected, or the name
+                of the application that detected the warning
+
+  LineNumber  - the line number where the warning was detected (parsers).
+                0 should be specified if the utility is not a parser.
+
+  MessageCode - an application-specific warning code that can be referenced in
+                other documentation.
+
+  Text        - part of the message to print
+
+  MsgFmt      - the format string for the message. Can contain formatting
+                controls for use with varargs.
+  List        - the variable list.
+
+Returns:
+  None.
+
+Notes:
+  If FileName == NULL then this utility will use the string passed into SetUtilityName().
+
+  LineNumber is only used if the caller is a parser, in which case FileName refers to the
+  file being parsed.
+
+  Text and MsgFmt are both optional, though it would be of little use calling this function with
+  them both NULL.
+
+  Output will typically be of the form:
+    <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>
+
+    Parser (LineNumber != 0)
+      VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters
+    Generic utility (LineNumber == 0)
+      UtilityName : error E1234 : Text string : MsgFmt string and args
+
+--*/
+{
+  CHAR8       Line[MAX_LINE_LEN];
+  CHAR8       Line2[MAX_LINE_LEN];
+  CHAR8       *Cptr;
+  struct tm   *NewTime;
+  time_t      CurrentTime;
+
+  //
+  // init local variable
+  //
+  Line[0] = '\0';
+  Line2[0] = '\0';
+
+  //
+  // If given a filename, then add it (and the line number) to the string.
+  // If there's no filename, then use the program name if provided.
+  //
+  if (FileName != NULL) {
+    Cptr = FileName;
+  } else {
+    Cptr = NULL;
+  }
+
+  if (strcmp (Type, "DEBUG") == 0) {
+    //
+    // Debug Message requires current time.
+    //
+    time (&CurrentTime);
+    NewTime = localtime (&CurrentTime);
+    fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d",
+                     NewTime->tm_year + 1900,
+                     NewTime->tm_mon + 1,
+                     NewTime->tm_mday,
+                     NewTime->tm_hour,
+                     NewTime->tm_min,
+                     NewTime->tm_sec
+                     );
+    if (Cptr != NULL) {
+      sprintf (Line, ": %s", Cptr);
+      if (LineNumber != 0) {
+        sprintf (Line2, "(%u)", (unsigned) LineNumber);
+        strcat (Line, Line2);
+      }
+    }
+  } else {
+    //
+    // Error and Warning Information.
+    //
+    if (Cptr != NULL) {
+      if (mUtilityName[0] != '\0') {
+        fprintf (stdout, "%s...\n", mUtilityName);
+      }
+      sprintf (Line, "%s", Cptr);
+      if (LineNumber != 0) {
+        sprintf (Line2, "(%u)", (unsigned) LineNumber);
+        strcat (Line, Line2);
+      }
+    } else {
+      if (mUtilityName[0] != '\0') {
+        sprintf (Line, "%s", mUtilityName);
+      }
+    }
+
+    if (strcmp (Type, "ERROR") == 0) {
+      //
+      // Set status accordingly for ERROR information.
+      //
+      if (mStatus < STATUS_ERROR) {
+        mStatus = STATUS_ERROR;
+      }
+    }
+  }
+
+  //
+  // Have to print an error code or Visual Studio won't find the
+  // message for you. It has to be decimal digits too.
+  //
+  if (MessageCode != 0) {
+    sprintf (Line2, ": %s %04u", Type, (unsigned) MessageCode);
+  } else {
+    sprintf (Line2, ": %s", Type);
+  }
+  strcat (Line, Line2);
+  fprintf (stdout, "%s", Line);
+  //
+  // If offending text was provided, then print it
+  //
+  if (Text != NULL) {
+    fprintf (stdout, ": %s", Text);
+  }
+  fprintf (stdout, "\n");
+
+  //
+  // Print formatted message if provided
+  //
+  if (MsgFmt != NULL) {
+    vsprintf (Line2, MsgFmt, List);
+    fprintf (stdout, "  %s\n", Line2);
+  }
+
+}
+
+STATIC
+VOID
+PrintSimpleMessage (
+  CHAR8   *MsgFmt,
+  va_list List
+  )
+/*++
+Routine Description:
+  Print message into stdout.
+
+Arguments:
+  MsgFmt      - the format string for the message. Can contain formatting
+                controls for use with varargs.
+  List        - the variable list.
+
+Returns:
+  None.
+--*/
+{
+  CHAR8       Line[MAX_LINE_LEN];
+  //
+  // Print formatted message if provided
+  //
+  if (MsgFmt != NULL) {
+    vsprintf (Line, MsgFmt, List);
+    fprintf (stdout, "%s\n", Line);
+  }
+}
+
+VOID
+ParserSetPosition (
+  CHAR8   *SourceFileName,
+  UINT32  LineNum
+  )
+/*++
+
+Routine Description:
+  Set the position in a file being parsed. This can be used to
+  print error messages deeper down in a parser.
+
+Arguments:
+  SourceFileName - name of the source file being parsed
+  LineNum        - line number of the source file being parsed
+
+Returns:
+  NA
+
+--*/
+{
+  mSourceFileName     = SourceFileName;
+  mSourceFileLineNum  = LineNum;
+}
+
+VOID
+SetUtilityName (
+  CHAR8   *UtilityName
+  )
+/*++
+
+Routine Description:
+  All printed error/warning/debug messages follow the same format, and
+  typically will print a filename or utility name followed by the error
+  text. However if a filename is not passed to the print routines, then
+  they'll print the utility name if you call this function early in your
+  app to set the utility name.
+
+Arguments:
+  UtilityName  -  name of the utility, which will be printed with all
+                  error/warning/debug messags.
+
+Returns:
+  NA
+
+--*/
+{
+  //
+  // Save the name of the utility in our local variable. Make sure its
+  // length does not exceed our buffer.
+  //
+  if (UtilityName != NULL) {
+    if (strlen (UtilityName) >= sizeof (mUtilityName)) {
+      Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");
+      strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
+      mUtilityName[sizeof (mUtilityName) - 1] = 0;
+      return ;
+    } else {
+      strcpy (mUtilityName, UtilityName);
+    }
+  } else {
+    Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
+  }
+}
+
+STATUS
+GetUtilityStatus (
+  VOID
+  )
+/*++
+
+Routine Description:
+  When you call Error() or Warning(), this module keeps track of it and
+  sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
+  exits, it can call this function to get the status and use it as a return
+  value.
+
+Arguments:
+  None.
+
+Returns:
+  Worst-case status reported, as defined by which print function was called.
+
+--*/
+{
+  return mStatus;
+}
+
+VOID
+SetPrintLevel (
+  UINT64  LogLevel
+  )
+/*++
+
+Routine Description:
+  Set the printing message Level. This is used by the PrintMsg() function
+  to determine when/if a message should be printed.
+
+Arguments:
+  LogLevel  - 0~50 to specify the different level message.
+
+Returns:
+  NA
+
+--*/
+{
+  mPrintLogLevel = LogLevel;
+}
+
+VOID
+VerboseMsg (
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a verbose level message.
+
+Arguments:
+  MsgFmt      - the format string for the message. Can contain formatting
+                controls for use with varargs.
+  List        - the variable list.
+
+Returns:
+  NA
+
+--*/
+{
+  va_list List;
+  //
+  // If the debug level is less than current print level, then do nothing.
+  //
+  if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
+    return ;
+  }
+
+  va_start (List, MsgFmt);
+  PrintSimpleMessage (MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+NormalMsg (
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a default level message.
+
+Arguments:
+  MsgFmt      - the format string for the message. Can contain formatting
+                controls for use with varargs.
+  List        - the variable list.
+
+Returns:
+  NA
+
+--*/
+{
+  va_list List;
+  //
+  // If the debug level is less than current print level, then do nothing.
+  //
+  if (INFO_LOG_LEVEL < mPrintLogLevel) {
+    return ;
+  }
+
+  va_start (List, MsgFmt);
+  PrintSimpleMessage (MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+KeyMsg (
+  CHAR8   *MsgFmt,
+  ...
+  )
+/*++
+
+Routine Description:
+  Print a key level message.
+
+Arguments:
+  MsgFmt      - the format string for the message. Can contain formatting
+                controls for use with varargs.
+  List        - the variable list.
+
+Returns:
+  NA
+
+--*/
+{
+  va_list List;
+  //
+  // If the debug level is less than current print level, then do nothing.
+  //
+  if (KEY_LOG_LEVEL < mPrintLogLevel) {
+    return ;
+  }
+
+  va_start (List, MsgFmt);
+  PrintSimpleMessage (MsgFmt, List);
+  va_end (List);
+}
+
+VOID
+SetPrintLimits (
+  UINT32  MaxErrors,
+  UINT32  MaxWarnings,
+  UINT32  MaxWarningsPlusErrors
+  )
+/*++
+
+Routine Description:
+  Set the limits of how many errors, warnings, and errors+warnings
+  we will print.
+
+Arguments:
+  MaxErrors       - maximum number of error messages to print
+  MaxWarnings     - maximum number of warning messages to print
+  MaxWarningsPlusErrors
+                  - maximum number of errors+warnings to print
+
+Returns:
+  NA
+
+--*/
+{
+  mMaxErrors              = MaxErrors;
+  mMaxWarnings            = MaxWarnings;
+  mMaxWarningsPlusErrors  = MaxWarningsPlusErrors;
+  mPrintLimitsSet         = 1;
+}
+
+STATIC
+VOID
+PrintLimitExceeded (
+  VOID
+  )
+{
+  STATIC INT8 mPrintLimitExceeded = 0;
+  //
+  // If we've already printed the message, do nothing. Otherwise
+  // temporarily increase our print limits so we can pass one
+  // more message through.
+  //
+  if (mPrintLimitExceeded == 0) {
+    mPrintLimitExceeded++;
+    mMaxErrors++;
+    mMaxWarnings++;
+    mMaxWarningsPlusErrors++;
+    Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
+    mMaxErrors--;
+    mMaxWarnings--;
+    mMaxWarningsPlusErrors--;
+  }
+}
+
+#if 0
+VOID
+TestUtilityMessages (
+  VOID
+  )
+{
+  CHAR8 *ArgStr = "ArgString";
+  int   ArgInt;
+
+  ArgInt  = 0x12345678;
+  //
+  // Test without setting utility name
+  //
+  fprintf (stdout, "* Testing without setting utility name\n");
+  fprintf (stdout, "** Test debug message not printed\n");
+  DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
+  fprintf (stdout, "** Test warning with two strings and two args\n");
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+  fprintf (stdout, "** Test error with two strings and two args\n");
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+  fprintf (stdout, "** Test parser warning with nothing\n");
+  ParserWarning (0, NULL, NULL);
+  fprintf (stdout, "** Test parser error with nothing\n");
+  ParserError (0, NULL, NULL);
+  //
+  // Test with utility name set now
+  //
+  fprintf (stdout, "** Testingin with utility name set\n");
+  SetUtilityName ("MyUtilityName");
+  //
+  // Test debug prints
+  //
+  SetDebugMsgMask (2);
+  fprintf (stdout, "** Test debug message with one string\n");
+  DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
+  fprintf (stdout, "** Test debug message with one string\n");
+  DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
+  fprintf (stdout, "** Test debug message with two strings\n");
+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
+  fprintf (stdout, "** Test debug message with two strings and two args\n");
+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+  //
+  // Test warning prints
+  //
+  fprintf (stdout, "** Test warning with no strings\n");
+  Warning (NULL, 0, 1234, NULL, NULL);
+  fprintf (stdout, "** Test warning with one string\n");
+  Warning (NULL, 0, 1234, "Text1", NULL);
+  fprintf (stdout, "** Test warning with one string\n");
+  Warning (NULL, 0, 1234, NULL, "Text2");
+  fprintf (stdout, "** Test warning with two strings and two args\n");
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+  //
+  // Test error prints
+  //
+  fprintf (stdout, "** Test error with no strings\n");
+  Error (NULL, 0, 1234, NULL, NULL);
+  fprintf (stdout, "** Test error with one string\n");
+  Error (NULL, 0, 1234, "Text1", NULL);
+  fprintf (stdout, "** Test error with one string\n");
+  Error (NULL, 0, 1234, NULL, "Text2");
+  fprintf (stdout, "** Test error with two strings and two args\n");
+  Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+  //
+  // Test parser prints
+  //
+  fprintf (stdout, "** Test parser errors\n");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserError (1234, NULL, NULL);
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserError (1234, "Text1", NULL);
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserError (1234, NULL, "Text2");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserError (1234, "Text1", "Text2");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+
+  fprintf (stdout, "** Test parser warnings\n");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserWarning (4321, NULL, NULL);
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserWarning (4321, "Text1", NULL);
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserWarning (4321, NULL, "Text2");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserWarning (4321, "Text1", "Text2");
+  ParserSetPosition (__FILE__, __LINE__ + 1);
+  ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+}
+#endif
diff --git a/EfiRom/Common/EfiUtilityMsgs.h b/EfiRom/Common/EfiUtilityMsgs.h
new file mode 100644
index 0000000..90aa530
--- /dev/null
+++ b/EfiRom/Common/EfiUtilityMsgs.h
@@ -0,0 +1,170 @@
+/** @file
+Defines and prototypes for common EFI utility error and debug messages.
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef _EFI_UTILITY_MSGS_H_
+#define _EFI_UTILITY_MSGS_H_
+
+#include <Common/UefiBaseTypes.h>
+
+//
+// Log message print Level
+//
+#define VERBOSE_LOG_LEVEL    15
+#define WARNING_LOG_LEVEL    15
+#define INFO_LOG_LEVEL       20
+#define KEY_LOG_LEVEL        40
+#define ERROR_LOG_LEVLE      50
+
+//
+// Status codes returned by EFI utility programs and functions
+//
+#define STATUS_SUCCESS  0
+#define STATUS_WARNING  1
+#define STATUS_ERROR    2
+#define VOID void 
+
+typedef int STATUS;
+
+#define MAX_LINE_LEN               0x200
+#define MAXIMUM_INPUT_FILE_NUM     10
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+//
+// When we call Error() or Warning(), the module keeps track of the worst
+// case reported. GetUtilityStatus() will get the worst-case results, which
+// can be used as the return value from the app.
+//
+STATUS
+GetUtilityStatus (
+  VOID
+  );
+
+//
+// If someone prints an error message and didn't specify a source file name,
+// then we print the utility name instead. However they must tell us the
+// utility name early on via this function.
+//
+VOID
+SetUtilityName (
+  CHAR8 *ProgramName
+  )
+;
+
+VOID
+PrintMessage (
+  CHAR8   *Type,
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  MessageCode,
+  CHAR8   *Text,
+  CHAR8   *MsgFmt,
+  va_list List
+  );
+
+VOID
+Error (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  ErrorCode,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+;
+
+VOID
+Warning (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT32  WarningCode,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+;
+
+VOID
+DebugMsg (
+  CHAR8   *FileName,
+  UINT32  LineNumber,
+  UINT64  MsgLevel,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+;
+
+VOID
+VerboseMsg (
+  CHAR8   *MsgFmt,
+  ...
+  );
+
+VOID
+NormalMsg (
+  CHAR8   *MsgFmt,
+  ...
+  );
+
+VOID
+KeyMsg (
+  CHAR8   *MsgFmt,
+  ...
+  );
+
+VOID
+SetPrintLevel (
+  UINT64  LogLevel
+  );
+
+VOID
+ParserSetPosition (
+  CHAR8   *SourceFileName,
+  UINT32  LineNum
+  )
+;
+
+VOID
+ParserError (
+  UINT32  ErrorCode,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+;
+
+VOID
+ParserWarning (
+  UINT32  ErrorCode,
+  CHAR8   *OffendingText,
+  CHAR8   *MsgFmt,
+  ...
+  )
+;
+
+VOID
+SetPrintLimits (
+  UINT32  NumErrors,
+  UINT32  NumWarnings,
+  UINT32  NumWarningsPlusErrors
+  )
+;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _EFI_UTILITY_MSGS_H_
diff --git a/EfiRom/Common/MemoryFile.h b/EfiRom/Common/MemoryFile.h
new file mode 100644
index 0000000..5ce4095
--- /dev/null
+++ b/EfiRom/Common/MemoryFile.h
@@ -0,0 +1,111 @@
+/** @file
+Header file for helper functions useful for accessing files.
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef _EFI_MEMORY_FILE_H
+#define _EFI_MEMORY_FILE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Common/UefiBaseTypes.h>
+
+//
+// Common data structures
+//
+typedef struct {
+  CHAR8 *FileImage;
+  CHAR8 *Eof;
+  CHAR8 *CurrentFilePointer;
+} MEMORY_FILE;
+
+
+//
+// Functions declarations
+//
+
+EFI_STATUS
+GetMemoryFile (
+  IN CHAR8       *InputFileName,
+  OUT EFI_HANDLE *OutputMemoryFile
+  )
+;
+/**
+
+Routine Description:
+
+  This opens a file, reads it into memory and returns a memory file
+  object.
+
+Arguments:
+
+  InputFile          Memory file image.
+  OutputMemoryFile   Handle to memory file
+
+Returns:
+
+  EFI_STATUS
+  OutputMemoryFile is valid if !EFI_ERROR
+
+**/
+
+
+EFI_STATUS
+FreeMemoryFile (
+  IN EFI_HANDLE InputMemoryFile
+  )
+;
+/**
+
+Routine Description:
+
+  Frees all memory associated with the input memory file.
+
+Arguments:
+
+  InputMemoryFile   Handle to memory file
+
+Returns:
+
+  EFI_STATUS
+
+**/
+
+
+CHAR8 *
+ReadMemoryFileLine (
+  IN EFI_HANDLE     InputMemoryFile
+  )
+;
+/**
+
+Routine Description:
+
+  This function reads a line from the memory file.  The newline characters
+  are stripped and a null terminated string is returned.
+
+  If the string pointer returned is non-NULL, then the caller must free the
+  memory associated with this string.
+
+Arguments:
+
+  InputMemoryFile   Handle to memory file
+
+Returns:
+
+  NULL if error or EOF
+  NULL character termincated string otherwise (MUST BE FREED BY CALLER)
+
+**/
+
+
+#endif
diff --git a/EfiRom/Common/ParseInf.c b/EfiRom/Common/ParseInf.c
new file mode 100644
index 0000000..08460be
--- /dev/null
+++ b/EfiRom/Common/ParseInf.c
@@ -0,0 +1,701 @@
+/** @file
+This contains some useful functions for parsing INF files.
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "CommonLib.h"
+
+CHAR8 *
+ReadLine (
+  IN MEMORY_FILE    *InputFile,
+  IN OUT CHAR8      *InputBuffer,
+  IN UINTN          MaxLength
+  )
+/*++
+
+Routine Description:
+
+  This function reads a line, stripping any comments.
+  The function reads a string from the input stream argument and stores it in 
+  the input string. ReadLine reads characters from the current file position 
+  to and including the first newline character, to the end of the stream, or 
+  until the number of characters read is equal to MaxLength - 1, whichever 
+  comes first.  The newline character, if read, is replaced with a \0. 
+
+Arguments:
+
+  InputFile     Memory file image.
+  InputBuffer   Buffer to read into, must be MaxLength size.
+  MaxLength     The maximum size of the input buffer.
+
+Returns:
+
+  NULL if error or EOF
+  InputBuffer otherwise
+
+--*/
+{
+  CHAR8 *CharPtr;
+  CHAR8 *EndOfLine;
+  UINTN CharsToCopy;
+
+  //
+  // Verify input parameters are not null
+  //
+  assert (InputBuffer);
+  assert (InputFile->FileImage);
+  assert (InputFile->Eof);
+  assert (InputFile->CurrentFilePointer);
+
+  //
+  // Check for end of file condition
+  //
+  if (InputFile->CurrentFilePointer >= InputFile->Eof) {
+    return NULL;
+  }
+  //
+  // Find the next newline char
+  //
+  EndOfLine = strchr (InputFile->CurrentFilePointer, '\n');
+
+  //
+  // Determine the number of characters to copy.
+  //
+  if (EndOfLine == 0) {
+    //
+    // If no newline found, copy to the end of the file.
+    //
+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
+  } else if (EndOfLine >= InputFile->Eof) {
+    //
+    // If the newline found was beyond the end of file, copy to the eof.
+    //
+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
+  } else {
+    //
+    // Newline found in the file.
+    //
+    CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
+  }
+  //
+  // If the end of line is too big for the current buffer, set it to the max
+  // size of the buffer (leaving room for the \0.
+  //
+  if (CharsToCopy > MaxLength - 1) {
+    CharsToCopy = MaxLength - 1;
+  }
+  //
+  // Copy the line.
+  //
+  memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy);
+
+  //
+  // Add the null termination over the 0x0D
+  //
+  if (InputBuffer[CharsToCopy - 1] == '\r') {
+
+    InputBuffer[CharsToCopy - 1] = '\0';
+
+  } else {
+
+    InputBuffer[CharsToCopy] = '\0';
+
+  }
+
+  //
+  // Increment the current file pointer (include the 0x0A)
+  //
+  InputFile->CurrentFilePointer += CharsToCopy + 1;
+
+  //
+  // Strip any comments
+  //
+  CharPtr = strstr (InputBuffer, "//");
+  if (CharPtr != 0) {
+    CharPtr[0] = 0;
+  }
+  //
+  // Return the string
+  //
+  return InputBuffer;
+}
+
+BOOLEAN
+FindSection (
+  IN MEMORY_FILE    *InputFile,
+  IN CHAR8          *Section
+  )
+/*++
+
+Routine Description:
+
+  This function parses a file from the beginning to find a section.
+  The section string may be anywhere within a line.
+
+Arguments:
+
+  InputFile     Memory file image.
+  Section       Section to search for
+
+Returns:
+
+  FALSE if error or EOF
+  TRUE if section found
+
+--*/
+{
+  CHAR8 InputBuffer[MAX_LONG_FILE_PATH];
+  CHAR8 *CurrentToken;
+
+  //
+  // Verify input is not NULL
+  //
+  assert (InputFile->FileImage);
+  assert (InputFile->Eof);
+  assert (InputFile->CurrentFilePointer);
+  assert (Section);
+
+  //
+  // Rewind to beginning of file
+  //
+  InputFile->CurrentFilePointer = InputFile->FileImage;
+
+  //
+  // Read lines until the section is found
+  //
+  while (InputFile->CurrentFilePointer < InputFile->Eof) {
+    //
+    // Read a line
+    //
+    ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH);
+
+    //
+    // Check if the section is found
+    //
+    CurrentToken = strstr (InputBuffer, Section);
+    if (CurrentToken != NULL) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+FindToken (
+  IN MEMORY_FILE    *InputFile,
+  IN CHAR8          *Section,
+  IN CHAR8          *Token,
+  IN UINTN          Instance,
+  OUT CHAR8         *Value
+  )
+/*++
+
+Routine Description:
+
+  Finds a token value given the section and token to search for.
+
+Arguments:
+
+  InputFile Memory file image.
+  Section   The section to search for, a string within [].
+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
+  Instance  The instance of the token to search for.  Zero is the first instance.
+  Value     The string that holds the value following the =.  Must be MAX_LONG_FILE_PATH in size.
+
+Returns:
+
+  EFI_SUCCESS             Value found.
+  EFI_ABORTED             Format error detected in INF file.
+  EFI_INVALID_PARAMETER   Input argument was null.
+  EFI_LOAD_ERROR          Error reading from the file.
+  EFI_NOT_FOUND           Section/Token/Value not found.
+
+--*/
+{
+  CHAR8   InputBuffer[MAX_LONG_FILE_PATH];
+  CHAR8   *CurrentToken;
+  CHAR8   *Delimiter;
+  BOOLEAN ParseError;
+  BOOLEAN ReadError;
+  UINTN   Occurrance;
+
+  //
+  // Check input parameters
+  //
+  if (InputFile->FileImage == NULL ||
+      InputFile->Eof == NULL ||
+      InputFile->CurrentFilePointer == NULL ||
+      Section == NULL ||
+      strlen (Section) == 0 ||
+      Token == NULL ||
+      strlen (Token) == 0 ||
+      Value == NULL
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize error codes
+  //
+  ParseError  = FALSE;
+  ReadError   = FALSE;
+
+  //
+  // Initialize our instance counter for the search token
+  //
+  Occurrance = 0;
+
+  if (FindSection (InputFile, Section)) {
+    //
+    // Found the desired section, find and read the desired token
+    //
+    do {
+      //
+      // Read a line from the file
+      //
+      if (ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH) == NULL) {
+        //
+        // Error reading from input file
+        //
+        ReadError = TRUE;
+        break;
+      }
+      //
+      // Get the first non-whitespace string
+      //
+      Delimiter = strchr (InputBuffer, '=');
+      if (Delimiter != NULL) {
+        *Delimiter = 0;
+      }
+
+      CurrentToken = strtok (InputBuffer, " \t\n");
+      if (CurrentToken == NULL || Delimiter == NULL) {
+        //
+        // Whitespace line found (or comment) so continue
+        //
+        CurrentToken = InputBuffer;
+        continue;
+      }
+      //
+      // Make sure we have not reached the end of the current section
+      //
+      if (CurrentToken[0] == '[') {
+        break;
+      }
+      //
+      // Compare the current token with the desired token
+      //
+      if (strcmp (CurrentToken, Token) == 0) {
+        //
+        // Found it
+        //
+        //
+        // Check if it is the correct instance
+        //
+        if (Instance == Occurrance) {
+          //
+          // Copy the contents following the =
+          //
+          CurrentToken = Delimiter + 1;
+          if (*CurrentToken == 0) {
+            //
+            // Nothing found, parsing error
+            //
+            ParseError = TRUE;
+          } else {
+            //
+            // Strip leading white space
+            //
+            while (*CurrentToken == ' ' || *CurrentToken == '\t') {
+              CurrentToken++;
+            }
+            //
+            // Copy the current token to the output value
+            //
+            strcpy (Value, CurrentToken);
+            //
+            // Strip trailing white space
+            //
+            while (strlen(Value) > 0 && (*(Value + strlen(Value) - 1) == ' ' || *(Value + strlen(Value) - 1) == '\t')) {
+              *(Value + strlen(Value) - 1) = 0;
+            }
+            return EFI_SUCCESS;
+          }
+        } else {
+          //
+          // Increment the occurrance found
+          //
+          Occurrance++;
+        }
+      }
+    } while (
+      !ParseError &&
+      !ReadError &&
+      InputFile->CurrentFilePointer < InputFile->Eof &&
+      CurrentToken[0] != '[' &&
+      Occurrance <= Instance
+    );
+  }
+  //
+  // Distinguish between read errors and INF file format errors.
+  //
+  if (ReadError) {
+    return EFI_LOAD_ERROR;
+  }
+
+  if (ParseError) {
+    return EFI_ABORTED;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+StringToGuid (
+  IN CHAR8      *AsciiGuidBuffer,
+  OUT EFI_GUID  *GuidBuffer
+  )
+/*++
+
+Routine Description: 
+
+  Converts a string to an EFI_GUID.  The string must be in the 
+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
+
+Arguments:  
+
+  AsciiGuidBuffer - pointer to ascii string
+  GuidBuffer      - pointer to destination Guid
+
+Returns:  
+
+  EFI_ABORTED             Could not convert the string
+  EFI_SUCCESS             The string was successfully converted
+  EFI_INVALID_PARAMETER   Input parameter is invalid.
+
+--*/
+{
+  INT32 Index;
+  unsigned Data1;
+  unsigned Data2;
+  unsigned Data3;
+  unsigned Data4[8];
+
+  if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check Guid Format strictly xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+  //
+  for (Index = 0; AsciiGuidBuffer[Index] != '\0' && Index < 37; Index ++) {
+    if (Index == 8 || Index == 13 || Index == 18 || Index == 23) {
+      if (AsciiGuidBuffer[Index] != '-') {
+        break;
+      }
+    } else {
+      if (((AsciiGuidBuffer[Index] >= '0') && (AsciiGuidBuffer[Index] <= '9')) || 
+         ((AsciiGuidBuffer[Index] >= 'a') && (AsciiGuidBuffer[Index] <= 'f')) ||
+         ((AsciiGuidBuffer[Index] >= 'A') && (AsciiGuidBuffer[Index] <= 'F'))) {
+        continue;
+      } else {
+        break;
+      }
+    }
+  }
+  
+  if (Index < 36 || AsciiGuidBuffer[36] != '\0') {
+    Error (NULL, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n  Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer);
+    return EFI_ABORTED;
+  }
+  
+  //
+  // Scan the guid string into the buffer
+  //
+  Index = sscanf (
+            AsciiGuidBuffer,
+            "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+            &Data1,
+            &Data2,
+            &Data3,
+            &Data4[0],
+            &Data4[1],
+            &Data4[2],
+            &Data4[3],
+            &Data4[4],
+            &Data4[5],
+            &Data4[6],
+            &Data4[7]
+            );
+
+  //
+  // Verify the correct number of items were scanned.
+  //
+  if (Index != 11) {
+    Error (NULL, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n  Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer);
+    return EFI_ABORTED;
+  }
+  //
+  // Copy the data into our GUID.
+  //
+  GuidBuffer->Data1     = (UINT32) Data1;
+  GuidBuffer->Data2     = (UINT16) Data2;
+  GuidBuffer->Data3     = (UINT16) Data3;
+  GuidBuffer->Data4[0]  = (UINT8) Data4[0];
+  GuidBuffer->Data4[1]  = (UINT8) Data4[1];
+  GuidBuffer->Data4[2]  = (UINT8) Data4[2];
+  GuidBuffer->Data4[3]  = (UINT8) Data4[3];
+  GuidBuffer->Data4[4]  = (UINT8) Data4[4];
+  GuidBuffer->Data4[5]  = (UINT8) Data4[5];
+  GuidBuffer->Data4[6]  = (UINT8) Data4[6];
+  GuidBuffer->Data4[7]  = (UINT8) Data4[7];
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AsciiStringToUint64 (
+  IN CONST CHAR8  *AsciiString,
+  IN BOOLEAN      IsHex,
+  OUT UINT64      *ReturnValue
+  )
+/*++
+
+Routine Description:
+
+  Converts a null terminated ascii string that represents a number into a 
+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be 
+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 
+  unless the IsHex input is true.
+
+Arguments:
+
+  AsciiString   The string to convert.
+  IsHex         Force the string to be treated as a hex number.
+  ReturnValue   The return value.
+
+Returns:
+
+  EFI_SUCCESS   Number successfully converted.
+  EFI_ABORTED   Invalid character encountered.
+
+--*/
+{
+  UINT8   Index;
+  UINT64  Value;
+  CHAR8   CurrentChar;
+  
+  //
+  // Initialize the result
+  //
+  Value = 0;
+  Index = 0;
+  
+  //
+  // Check input paramter
+  //
+  if (AsciiString == NULL || ReturnValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  while (AsciiString[Index] == ' ') {
+    Index ++;
+  }
+  
+  //
+  // Add each character to the result
+  //
+  
+  //
+  // Skip first two chars only if the string starts with '0x' or '0X'
+  //
+  if (AsciiString[Index] == '0' && (AsciiString[Index + 1] == 'x' || AsciiString[Index + 1] == 'X')) {
+    IsHex = TRUE;
+    Index += 2;
+  }
+  if (IsHex) {
+    //
+    // Convert the hex string.
+    //
+    for (; AsciiString[Index] != '\0'; Index++) {
+      CurrentChar = AsciiString[Index];
+      if (CurrentChar == ' ') {
+        break;
+      }
+      //
+      // Verify Hex string
+      //
+      if (isxdigit ((int)CurrentChar) == 0) {
+        return EFI_ABORTED;
+      }
+      //
+      // Add hex value
+      //
+      Value *= 16;
+      if (CurrentChar >= '0' && CurrentChar <= '9') {
+        Value += CurrentChar - '0';
+      } else if (CurrentChar >= 'a' && CurrentChar <= 'f') {
+        Value += CurrentChar - 'a' + 10;
+      } else if (CurrentChar >= 'A' && CurrentChar <= 'F') {
+        Value += CurrentChar - 'A' + 10;
+      }
+    }
+
+    *ReturnValue = Value;
+  } else {
+    //
+    // Convert dec string is a number
+    //
+    for (; Index < strlen (AsciiString); Index++) {
+      CurrentChar = AsciiString[Index];
+      if (CurrentChar == ' ') {
+        break;
+      }
+      //
+      // Verify Dec string
+      //
+      if (isdigit ((int)CurrentChar) == 0) {
+        return EFI_ABORTED;
+      }
+      //
+      // Add dec value
+      //
+      Value = Value * 10;
+      Value += CurrentChar - '0';
+    }
+
+    *ReturnValue = Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+CHAR8 *
+ReadLineInStream (
+  IN FILE       *InputFile,
+  IN OUT CHAR8  *InputBuffer
+  )
+/*++
+
+Routine Description:
+
+  This function reads a line, stripping any comments.
+  // BUGBUG:  This is obsolete once genmake goes away...
+
+Arguments:
+
+  InputFile     Stream pointer.
+  InputBuffer   Buffer to read into, must be MAX_LONG_FILE_PATH size.
+
+Returns:
+
+  NULL if error or EOF
+  InputBuffer otherwise
+
+--*/
+{
+  CHAR8 *CharPtr;
+
+  //
+  // Verify input parameters are not null
+  //
+  assert (InputFile);
+  assert (InputBuffer);
+
+  //
+  // Read a line
+  //
+  if (fgets (InputBuffer, MAX_LONG_FILE_PATH, InputFile) == NULL) {
+    return NULL;
+  }
+  //
+  // Strip any comments
+  //
+  CharPtr = strstr (InputBuffer, "//");
+  if (CharPtr != 0) {
+    CharPtr[0] = 0;
+  }
+
+  CharPtr = strstr (InputBuffer, "#");
+  if (CharPtr != 0) {
+    CharPtr[0] = 0;
+  }
+  //
+  // Return the string
+  //
+  return InputBuffer;
+}
+
+BOOLEAN
+FindSectionInStream (
+  IN FILE       *InputFile,
+  IN CHAR8      *Section
+  )
+/*++
+
+Routine Description:
+
+  This function parses a stream file from the beginning to find a section.
+  The section string may be anywhere within a line.
+  // BUGBUG:  This is obsolete once genmake goes away...
+
+Arguments:
+
+  InputFile     Stream pointer.
+  Section       Section to search for
+
+Returns:
+
+  FALSE if error or EOF
+  TRUE if section found
+
+--*/
+{
+  CHAR8 InputBuffer[MAX_LONG_FILE_PATH];
+  CHAR8 *CurrentToken;
+
+  //
+  // Verify input is not NULL
+  //
+  assert (InputFile);
+  assert (Section);
+
+  //
+  // Rewind to beginning of file
+  //
+  if (fseek (InputFile, 0, SEEK_SET) != 0) {
+    return FALSE;
+  }
+  //
+  // Read lines until the section is found
+  //
+  while (feof (InputFile) == 0) {
+    //
+    // Read a line
+    //
+    ReadLineInStream (InputFile, InputBuffer);
+
+    //
+    // Check if the section is found
+    //
+    CurrentToken = strstr (InputBuffer, Section);
+    if (CurrentToken != NULL) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
diff --git a/EfiRom/Common/ParseInf.h b/EfiRom/Common/ParseInf.h
new file mode 100644
index 0000000..9c2821d
--- /dev/null
+++ b/EfiRom/Common/ParseInf.h
@@ -0,0 +1,226 @@
+/** @file
+Header file for helper functions useful for parsing INF files.
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef _EFI_PARSE_INF_H
+#define _EFI_PARSE_INF_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Common/UefiBaseTypes.h>
+#include <MemoryFile.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+//
+// Functions declarations
+//
+CHAR8 *
+ReadLine (
+  IN MEMORY_FILE    *InputFile,
+  IN OUT CHAR8      *InputBuffer,
+  IN UINTN          MaxLength
+  )
+;
+
+/*++
+
+Routine Description:
+
+  This function reads a line, stripping any comments.
+  The function reads a string from the input stream argument and stores it in 
+  the input string. ReadLine reads characters from the current file position 
+  to and including the first newline character, to the end of the stream, or 
+  until the number of characters read is equal to MaxLength - 1, whichever 
+  comes first.  The newline character, if read, is replaced with a \0. 
+
+Arguments:
+
+  InputFile     Memory file image.
+  InputBuffer   Buffer to read into, must be MaxLength size.
+  MaxLength     The maximum size of the input buffer.
+
+Returns:
+
+  NULL if error or EOF
+  InputBuffer otherwise
+
+--*/
+BOOLEAN
+FindSection (
+  IN MEMORY_FILE    *InputFile,
+  IN CHAR8          *Section
+  )
+;
+
+/*++
+
+Routine Description:
+
+  This function parses a file from the beginning to find a section.
+  The section string may be anywhere within a line.
+
+Arguments:
+
+  InputFile     Memory file image.
+  Section       Section to search for
+
+Returns:
+
+  FALSE if error or EOF
+  TRUE if section found
+
+--*/
+EFI_STATUS
+FindToken (
+  IN MEMORY_FILE    *InputFile,
+  IN CHAR8          *Section,
+  IN CHAR8          *Token,
+  IN UINTN          Instance,
+  OUT CHAR8         *Value
+  )
+;
+
+/*++
+
+Routine Description:
+
+  Finds a token value given the section and token to search for.
+
+Arguments:
+
+  InputFile Memory file image.
+  Section   The section to search for, a string within [].
+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
+  Instance  The instance of the token to search for.  Zero is the first instance.
+  Value     The string that holds the value following the =.  Must be MAX_LONG_FILE_PATH in size.
+
+Returns:
+
+  EFI_SUCCESS             Value found.
+  EFI_ABORTED             Format error detected in INF file.
+  EFI_INVALID_PARAMETER   Input argument was null.
+  EFI_LOAD_ERROR          Error reading from the file.
+  EFI_NOT_FOUND           Section/Token/Value not found.
+
+--*/
+EFI_STATUS
+StringToGuid (
+  IN CHAR8        *AsciiGuidBuffer,
+  OUT EFI_GUID    *GuidBuffer
+  )
+;
+
+/*++
+
+Routine Description: 
+
+  Converts a string to an EFI_GUID.  The string must be in the 
+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
+
+Arguments:  
+
+  GuidBuffer      - pointer to destination Guid
+  AsciiGuidBuffer - pointer to ascii string
+
+Returns:  
+
+  EFI_ABORTED    Could not convert the string
+  EFI_SUCCESS    The string was successfully converted
+
+--*/
+EFI_STATUS
+AsciiStringToUint64 (
+  IN CONST CHAR8  *AsciiString,
+  IN BOOLEAN      IsHex,
+  OUT UINT64      *ReturnValue
+  )
+;
+
+/*++
+
+Routine Description:
+
+  Converts a null terminated ascii string that represents a number into a 
+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be 
+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 
+  unless the IsHex input is true.
+
+Arguments:
+
+  AsciiString   The string to convert.
+  IsHex         Force the string to be treated as a hex number.
+  ReturnValue   The return value.
+
+Returns:
+
+  EFI_SUCCESS   Number successfully converted.
+  EFI_ABORTED   Invalid character encountered.
+
+--*/
+CHAR8 *
+ReadLineInStream (
+  IN FILE       *InputFile,
+  IN OUT CHAR8  *InputBuffer
+  )
+;
+
+/*++
+
+Routine Description:
+
+  This function reads a line, stripping any comments.
+
+Arguments:
+
+  InputFile     Stream pointer.
+  InputBuffer   Buffer to read into, must be MAX_LONG_FILE_PATH size.
+
+Returns:
+
+  NULL if error or EOF
+  InputBuffer otherwise
+
+--*/
+BOOLEAN
+FindSectionInStream (
+  IN FILE       *InputFile,
+  IN CHAR8      *Section
+  )
+;
+
+/*++
+
+Routine Description:
+
+  This function parses a stream file from the beginning to find a section.
+  The section string may be anywhere within a line.
+
+Arguments:
+
+  InputFile     Stream pointer.
+  Section       Section to search for
+
+Returns:
+
+  FALSE if error or EOF
+  TRUE if section found
+
+--*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/EfiRom/EfiRom.c b/EfiRom/EfiRom.c
new file mode 100644
index 0000000..a5d1926
--- /dev/null
+++ b/EfiRom/EfiRom.c
@@ -0,0 +1,1564 @@
+/** @file
+Utility program to create an EFI option ROM image from binary and EFI PE32 files.
+
+Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available 
+under the terms and conditions of the BSD License which accompanies this 
+distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "EfiRom.h"
+
+UINT64  DebugLevel = 0;
+
+int
+main (
+  int   Argc,
+  char  *Argv[]
+  )
+/*++
+
+Routine Description:
+  
+  Given an EFI image filename, create a ROM-able image by creating an option 
+  ROM header and PCI data structure, filling them in, and then writing the
+  option ROM header + PCI data structure + EFI image out to the output file.
+
+Arguments:
+
+  Argc            - standard C main() argument count
+
+  Argv            - standard C main() argument list
+
+Returns:
+
+  0             success
+  non-zero      otherwise
+
+--*/
+{
+  CHAR8     *Ext;
+  FILE      *FptrOut;
+  UINT32    Status;
+  FILE_LIST *FList;
+  UINT32    TotalSize;
+  UINT32    Size;
+  CHAR8     *Ptr0;
+
+  SetUtilityName(UTILITY_NAME);
+
+  Status  = STATUS_SUCCESS;
+  FptrOut = NULL;
+
+  //
+  // Parse the command line arguments
+  //
+  if (ParseCommandLine (Argc, Argv, &mOptions)) {
+    return STATUS_ERROR;
+  }
+
+  if (mOptions.Quiet) {
+    SetPrintLevel(40);
+  } else if (mOptions.Verbose) {
+    SetPrintLevel(15);
+  } else if (mOptions.Debug) {
+    SetPrintLevel(DebugLevel);
+  }
+  
+  if (mOptions.Verbose) {
+    VerboseMsg("%s tool start.\n", UTILITY_NAME);
+  }
+  
+  //
+  // If dumping an image, then do that and quit
+  //
+  if (mOptions.DumpOption == 1) {
+    if (mOptions.FileList != NULL) {
+      if ((Ptr0 = strstr ((CONST CHAR8 *) mOptions.FileList->FileName, DEFAULT_OUTPUT_EXTENSION)) != NULL) {
+        DumpImage (mOptions.FileList);
+        goto BailOut;
+      } else {
+        Error (NULL, 0, 1002, "No PciRom input file", "No *.rom input file");
+        goto BailOut;
+      }
+    }
+  }
+  //
+  // Determine the output filename. Either what they specified on
+  // the command line, or the first input filename with a different extension.
+  //
+  if (!mOptions.OutFileName[0]) {
+    strcpy (mOptions.OutFileName, mOptions.FileList->FileName);
+    //
+    // Find the last . on the line and replace the filename extension with
+    // the default
+    //
+    for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
+         (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');
+         Ext--
+        )
+      ;
+    //
+    // If dot here, then insert extension here, otherwise append
+    //
+    if (*Ext != '.') {
+      Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
+    }
+
+    strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
+  }
+  //
+  // Make sure we don't have the same filename for input and output files
+  //
+  for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {
+    if (stricmp (mOptions.OutFileName, FList->FileName) == 0) {
+      Status = STATUS_ERROR;
+      Error (NULL, 0, 1002, "Invalid input paramter", "Input and output file names must be different - %s = %s.", FList->FileName, mOptions.OutFileName);
+      goto BailOut;
+    }
+  }
+  //
+  // Now open our output file
+  //
+  if ((FptrOut = fopen (LongFilePath (mOptions.OutFileName), "wb")) == NULL) {
+    Error (NULL, 0, 0001, "Error opening file", "Error opening file %s", mOptions.OutFileName);
+    goto BailOut;
+  }
+  //
+  // Process all our files
+  //
+  TotalSize = 0;
+  for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {
+    Size = 0;
+    if ((FList->FileFlags & FILE_FLAG_EFI) != 0) {
+      if (mOptions.Verbose) {
+        VerboseMsg("Processing EFI file    %s\n", FList->FileName);
+      }
+
+      Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size);
+    } else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) {
+      if (mOptions.Verbose) {
+        VerboseMsg("Processing binary file %s\n", FList->FileName);
+      }
+
+      Status = ProcessBinFile (FptrOut, FList, &Size);
+    } else {
+      Error (NULL, 0, 2000, "Invalid parameter", "File type not specified, it must be either an EFI or binary file: %s.", FList->FileName);
+      Status = STATUS_ERROR;
+    }
+
+    if (mOptions.Verbose) {
+      VerboseMsg("  Output size = 0x%X\n", (unsigned) Size);
+    }
+
+    if (Status != STATUS_SUCCESS) {
+      break;
+    }
+
+    TotalSize += Size;
+  }
+  //
+  // Check total size
+  //
+  if (TotalSize > MAX_OPTION_ROM_SIZE) {
+    Error (NULL, 0, 2000, "Invalid paramter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE);
+    Status = STATUS_ERROR;
+  }
+
+BailOut:
+  if (Status == STATUS_SUCCESS) {
+    if (FptrOut != NULL) {
+      fclose (FptrOut);
+    }
+    //
+    // Clean up our file list
+    //
+    while (mOptions.FileList != NULL) {
+      FList = mOptions.FileList->Next;
+      free (mOptions.FileList);
+      mOptions.FileList = FList;
+    }
+  }
+
+  if (mOptions.Verbose) {
+    VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
+  }
+
+  return GetUtilityStatus (); 
+}
+
+static
+int
+ProcessBinFile (
+  FILE      *OutFptr,
+  FILE_LIST *InFile,
+  UINT32    *Size
+  )
+/*++
+
+Routine Description:
+  
+  Process a binary input file.
+
+Arguments:
+
+  OutFptr     - file pointer to output binary ROM image file we're creating
+  InFile      - structure contains information on the binary file to process
+  Size        - pointer to where to return the size added to the output file
+
+Returns:
+
+  0 - successful
+
+--*/
+{
+  FILE                      *InFptr;
+  UINT32                    TotalSize;
+  UINT32                    FileSize;
+  UINT8                     *Buffer;
+  UINT32                    Status;
+  PCI_EXPANSION_ROM_HEADER  *RomHdr;
+  PCI_DATA_STRUCTURE        *PciDs23;
+  PCI_3_0_DATA_STRUCTURE    *PciDs30;
+  UINT32                    Index;
+  UINT8                     ByteCheckSum;
+  UINT16                    CodeType;
+ 
+  PciDs23 = NULL;
+  PciDs30 = NULL;
+  Status = STATUS_SUCCESS;
+
+  //
+  // Try to open the input file
+  //
+  if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+    Error (NULL, 0, 0001, "Error opening file", InFile->FileName);
+    return STATUS_ERROR;
+  }
+  //
+  // Seek to the end of the input file and get the file size. Then allocate
+  // a buffer to read it in to.
+  //
+  fseek (InFptr, 0, SEEK_END);
+  FileSize = ftell (InFptr);
+  if (mOptions.Verbose) {
+    VerboseMsg("  File size   = 0x%X\n", (unsigned) FileSize);
+  }
+
+  fseek (InFptr, 0, SEEK_SET);
+  Buffer = (UINT8 *) malloc (FileSize);
+  if (Buffer == NULL) {
+    Error (NULL, 0, 4003, "Resource", "memory cannot be allocated!");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  if (fread (Buffer, FileSize, 1, InFptr) != 1) {
+    Error (NULL, 0, 2000, "Invalid", "Failed to read all bytes from input file.");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+  //
+  // Total size must be an even multiple of 512 bytes, and can't exceed
+  // the option ROM image size.
+  //
+  TotalSize = FileSize;
+  if (TotalSize & 0x1FF) {
+    TotalSize = (TotalSize + 0x200) &~0x1ff;
+  }
+
+  if (TotalSize > MAX_OPTION_ROM_SIZE) {
+    Error (NULL, 0, 3001, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+  //
+  // Return the size to the caller so they can keep track of the running total.
+  //
+  *Size = TotalSize;
+
+  //
+  // Crude check to make sure it's a legitimate ROM image
+  //
+  RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;
+  if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+    Error (NULL, 0, 2000, "Invalid parameter", "ROM image file has an invalid ROM signature.");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+  //
+  // Make sure the pointer to the PCI data structure is within the size of the image.
+  // Then check it for valid signature.
+  //
+  if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) {
+    Error (NULL, 0, 2000, "Invalid parameter", "Invalid PCI data structure offset.");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  //
+  // Check the header is conform to PCI2.3 or PCI3.0
+  //
+  if (mOptions.Pci23 == 1) {
+    PciDs23 = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);
+    if (PciDs23->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+      Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+  } else {
+    //
+    // Default setting is PCI3.0 header
+    //
+    PciDs30 = (PCI_3_0_DATA_STRUCTURE *)(Buffer + RomHdr->PcirOffset);
+    if (PciDs30->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+      Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+  }
+
+  //
+  // ReSet Option Rom size
+  //
+  if (mOptions.Pci23 == 1) {
+    PciDs23->ImageLength = (UINT16) (TotalSize / 512);
+    CodeType = PciDs23->CodeType;
+  } else {
+    PciDs30->ImageLength = (UINT16) (TotalSize / 512);
+    CodeType = PciDs30->CodeType;
+	}
+
+  //
+  // If this is the last image, then set the LAST bit unless requested not
+  // to via the command-line -n argument. Otherwise, make sure you clear it.
+  //
+  if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {
+    if (mOptions.Pci23 == 1) {
+      PciDs23->Indicator = INDICATOR_LAST;
+    } else {
+      PciDs30->Indicator = INDICATOR_LAST;
+		}
+  } else {
+    if (mOptions.Pci23 == 1) {
+      PciDs23->Indicator = 0;
+    } else {
+      PciDs30->Indicator = 0;
+		}
+  }
+
+  if (CodeType != PCI_CODE_TYPE_EFI_IMAGE) {
+    ByteCheckSum = 0;
+    for (Index = 0; Index < FileSize - 1; Index++) {
+      ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]);
+    }
+
+    Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1);
+    if (mOptions.Verbose) {
+      VerboseMsg("  Checksum = %02x\n\n", Buffer[FileSize - 1]);
+    }
+  }
+
+  //
+  // Now copy the input file contents out to the output file
+  //
+  if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
+    Error (NULL, 0, 0005, "Failed to write all file bytes to output file.", NULL);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  TotalSize -= FileSize;
+  //
+  // Pad the rest of the image to make it a multiple of 512 bytes
+  //
+  while (TotalSize > 0) {
+    putc (~0, OutFptr);
+    TotalSize--;
+  }
+
+BailOut:
+  if (InFptr != NULL) {
+    fclose (InFptr);
+  }
+
+  if (Buffer != NULL) {
+    free (Buffer);
+  }
+  //
+  // Print the file name if errors occurred
+  //
+  if (Status != STATUS_SUCCESS) {
+    Error (NULL, 0, 0003, "Error", "Error parsing file: %s", InFile->FileName);
+  }
+
+  return Status;
+}
+
+static
+int
+ProcessEfiFile (
+  FILE      *OutFptr,
+  FILE_LIST *InFile,
+  UINT16    VendId,
+  UINT16    DevId,
+  UINT32    *Size
+  )
+/*++
+
+Routine Description:
+  
+  Process a PE32 EFI file.
+
+Arguments:
+
+  OutFptr     - file pointer to output binary ROM image file we're creating
+  InFile      - structure contains information on the PE32 file to process
+  VendId      - vendor ID as required in the option ROM header
+  DevId       - device ID as required in the option ROM header
+  Size        - pointer to where to return the size added to the output file
+
+Returns:
+
+  0 - successful
+
+--*/
+{
+  UINT32                        Status;
+  FILE                          *InFptr;
+  EFI_PCI_EXPANSION_ROM_HEADER  RomHdr;
+  PCI_DATA_STRUCTURE            PciDs23;
+  PCI_3_0_DATA_STRUCTURE        PciDs30;
+  UINT32                        FileSize;
+  UINT32                        CompressedFileSize;
+  UINT8                         *Buffer;
+  UINT8                         *CompressedBuffer;
+  UINT8                         *TempBufferPtr;
+  UINT32                        TotalSize;
+  UINT32                        HeaderSize;
+  UINT16                        MachineType;
+  UINT16                        SubSystem;
+  UINT32                        HeaderPadBytes;
+  UINT32                        PadBytesBeforeImage;
+  UINT32                        PadBytesAfterImage;
+
+  //
+  // Try to open the input file
+  //
+  if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+    Error (NULL, 0, 0001, "Open file error", "Error opening file: %s", InFile->FileName);
+    return STATUS_ERROR;
+  }
+  //
+  // Initialize our buffer pointers to null.
+  //
+  Buffer            = NULL;
+  CompressedBuffer  = NULL;
+
+  //
+  // Double-check the file to make sure it's what we expect it to be
+  //
+  Status = CheckPE32File (InFptr, &MachineType, &SubSystem);
+  if (Status != STATUS_SUCCESS) {
+    goto BailOut;
+  }
+  //
+  // Seek to the end of the input file and get the file size
+  //
+  fseek (InFptr, 0, SEEK_END);
+  FileSize = ftell (InFptr);
+
+  //
+  // Get the size of the headers we're going to put in front of the image. The
+  // EFI header must be aligned on a 4-byte boundary, so pad accordingly.
+  //
+  if (sizeof (RomHdr) & 0x03) {
+    HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03);
+  } else {
+    HeaderPadBytes = 0;
+  }
+  
+  //
+  // For Pci3.0 to use the different data structure.
+  //
+  if (mOptions.Pci23 == 1) {
+    HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
+  } else {
+    HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
+  }
+
+  if (mOptions.Verbose) {
+    VerboseMsg("  File size   = 0x%X\n", (unsigned) FileSize);
+  }
+  //
+  // Allocate memory for the entire file (in case we have to compress), then
+  // seek back to the beginning of the file and read it into our buffer.
+  //
+  Buffer = (UINT8 *) malloc (FileSize);
+  if (Buffer == NULL) {
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  fseek (InFptr, 0, SEEK_SET);
+  if (fread (Buffer, FileSize, 1, InFptr) != 1) {
+    Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+  //
+  // Now determine the size of the final output file. It's either the header size
+  // plus the file's size, or the header size plus the compressed file size.
+  //
+  if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) {
+    //
+    // Allocate a buffer into which we can compress the image, compress it,
+    // and use that size as the new size.
+    //
+    CompressedBuffer = (UINT8 *) malloc (FileSize);
+    if (CompressedBuffer == NULL) {
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+
+    CompressedFileSize  = FileSize;
+    Status              = EfiCompress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize);
+    if (Status != STATUS_SUCCESS) {
+      Error (NULL, 0, 0007, "Error compressing file!", NULL);
+      goto BailOut;
+    }
+    //
+    // Now compute the size, then swap buffer pointers.
+    //
+    if (mOptions.Verbose) {
+      VerboseMsg("  Comp size   = 0x%X\n", (unsigned) CompressedFileSize);
+    }
+
+    TotalSize         = CompressedFileSize + HeaderSize;
+    FileSize          = CompressedFileSize;
+    TempBufferPtr     = Buffer;
+    Buffer            = CompressedBuffer;
+    CompressedBuffer  = TempBufferPtr;
+  } else {
+    TotalSize = FileSize + HeaderSize;
+  }
+  //
+  // Total size must be an even multiple of 512 bytes
+  //
+  if (TotalSize & 0x1FF) {
+    TotalSize = (TotalSize + 0x200) &~0x1ff;
+  }
+  //
+  // Workaround:
+  //   If compressed, put the pad bytes after the image,
+  //   else put the pad bytes before the image.
+  //
+  if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) {
+    PadBytesBeforeImage = 0;
+    PadBytesAfterImage = TotalSize - (FileSize + HeaderSize);
+  } else {
+    PadBytesBeforeImage = TotalSize - (FileSize + HeaderSize);
+    PadBytesAfterImage = 0;
+  }
+  //
+  // Check size
+  //
+  if (TotalSize > MAX_OPTION_ROM_SIZE) {
+    Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);	
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+  //
+  // Return the size to the caller so they can keep track of the running total.
+  //
+  *Size = TotalSize;
+
+  //
+  // Now fill in the ROM header. These values come from chapter 18 of the
+  // EFI 1.02 specification.
+  //
+  memset (&RomHdr, 0, sizeof (RomHdr));
+  RomHdr.Signature            = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
+  RomHdr.InitializationSize   = (UINT16) (TotalSize / 512);
+  RomHdr.EfiSignature         = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
+  RomHdr.EfiSubsystem         = SubSystem;
+  RomHdr.EfiMachineType       = MachineType;
+  RomHdr.EfiImageHeaderOffset = (UINT16) (HeaderSize + PadBytesBeforeImage);
+  RomHdr.PcirOffset           = (UINT16) (sizeof (RomHdr) + HeaderPadBytes);
+  //
+  // Set image as compressed or not
+  //
+  if (InFile->FileFlags & FILE_FLAG_COMPRESS) {
+    RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED;
+  }
+  //
+  // Fill in the PCI data structure
+  //
+  if (mOptions.Pci23 == 1) {
+    memset (&PciDs23, 0, sizeof (PCI_DATA_STRUCTURE));
+  } else {
+    memset (&PciDs30, 0, sizeof (PCI_3_0_DATA_STRUCTURE));
+  }
+
+  if (mOptions.Pci23 == 1) {
+    PciDs23.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
+    PciDs23.VendorId  = VendId;
+    PciDs23.DeviceId  = DevId;
+    PciDs23.Length    = (UINT16) sizeof (PCI_DATA_STRUCTURE);
+    PciDs23.Revision  = 0;
+    //
+    // Class code and code revision from the command line (optional)
+    //
+    PciDs23.ClassCode[0]  = (UINT8) InFile->ClassCode;
+    PciDs23.ClassCode[1]  = (UINT8) (InFile->ClassCode >> 8);
+    PciDs23.ClassCode[2]  = (UINT8) (InFile->ClassCode >> 16);
+    PciDs23.ImageLength   = RomHdr.InitializationSize;
+    PciDs23.CodeRevision  = InFile->CodeRevision;
+    PciDs23.CodeType      = PCI_CODE_TYPE_EFI_IMAGE;
+  } else {
+    PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
+    PciDs30.VendorId  = VendId;
+    PciDs30.DeviceId  = DevId;
+    PciDs30.DeviceListOffset = 0; // to be fixed
+    PciDs30.Length    = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);
+    PciDs30.Revision  = 0x3;
+    //
+    // Class code and code revision from the command line (optional)
+    //
+    PciDs30.ClassCode[0]  = (UINT8) InFile->ClassCode;
+    PciDs30.ClassCode[1]  = (UINT8) (InFile->ClassCode >> 8);
+    PciDs30.ClassCode[2]  = (UINT8) (InFile->ClassCode >> 16);
+    PciDs30.ImageLength   = RomHdr.InitializationSize;
+    PciDs30.CodeRevision  = InFile->CodeRevision;
+    PciDs30.CodeType      = PCI_CODE_TYPE_EFI_IMAGE;
+    PciDs30.MaxRuntimeImageLength = 0; // to be fixed
+    PciDs30.ConfigUtilityCodeHeaderOffset = 0; // to be fixed
+    PciDs30.DMTFCLPEntryPointOffset = 0; // to be fixed
+  }
+  //
+  // If this is the last image, then set the LAST bit unless requested not
+  // to via the command-line -n argument.
+  //
+  if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {
+    if (mOptions.Pci23 == 1) {
+      PciDs23.Indicator = INDICATOR_LAST;
+	  } else {
+    PciDs30.Indicator = INDICATOR_LAST;}
+  } else {
+    if (mOptions.Pci23 == 1) {
+      PciDs23.Indicator = 0;
+	} else {
+      PciDs30.Indicator = 0;
+    }
+  }
+  //
+  // Write the ROM header to the output file
+  //
+  if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) {
+    Error (NULL, 0, 0002, "Failed to write ROM header to output file!", NULL);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  //
+  // Write pad bytes to align the PciDs
+  //
+  while (HeaderPadBytes > 0) {
+    if (putc (0, OutFptr) == EOF) {
+      Error (NULL, 0, 0002, "Failed to write ROM header pad bytes to output file!", NULL);
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+
+    HeaderPadBytes--;
+  }
+  //
+  // Write the PCI data structure header to the output file
+  //
+  if (mOptions.Pci23 == 1) {
+    if (fwrite (&PciDs23, sizeof (PciDs23), 1, OutFptr) != 1) {
+      Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
+      Status = STATUS_ERROR;
+      goto BailOut;
+    } 
+  } else {
+    if (fwrite (&PciDs30, sizeof (PciDs30), 1, OutFptr) != 1) {
+      Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
+      Status = STATUS_ERROR;
+      goto BailOut;
+    } 
+  }
+
+  //
+  // Pad head to make it a multiple of 512 bytes
+  //
+  while (PadBytesBeforeImage > 0) {
+    if (putc (~0, OutFptr) == EOF) {
+      Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL);
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+    PadBytesBeforeImage--;
+  }
+  //
+  // Now dump the input file's contents to the output file
+  //
+  if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
+    Error (NULL, 0, 0002, "Failed to write all file bytes to output file!", NULL);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  //
+  // Pad the rest of the image to make it a multiple of 512 bytes
+  //
+  while (PadBytesAfterImage > 0) {
+    if (putc (~0, OutFptr) == EOF) {
+      Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL);
+      Status = STATUS_ERROR;
+      goto BailOut;
+    }
+
+    PadBytesAfterImage--;
+  }
+
+BailOut:
+  if (InFptr != NULL) {
+    fclose (InFptr);
+  }
+  //
+  // Free up our buffers
+  //
+  if (Buffer != NULL) {
+    free (Buffer);
+  }
+
+  if (CompressedBuffer != NULL) {
+    free (CompressedBuffer);
+  }
+  //
+  // Print the file name if errors occurred
+  //
+  if (Status != STATUS_SUCCESS) {
+    Error (NULL, 0, 0003, "Error parsing", "Error parsing file: %s", InFile->FileName);
+  }
+
+  return Status;
+}
+
+static
+int
+CheckPE32File (
+  FILE      *Fptr,
+  UINT16    *MachineType,
+  UINT16    *SubSystem
+  )
+/*++
+
+Routine Description:
+  
+  Given a file pointer to a supposed PE32 image file, verify that it is indeed a
+  PE32 image file, and then return the machine type in the supplied pointer.
+
+Arguments:
+
+  Fptr          File pointer to the already-opened PE32 file
+  MachineType   Location to stuff the machine type of the PE32 file. This is needed
+                because the image may be Itanium-based, IA32, or EBC.
+
+Returns:
+
+  0             success
+  non-zero      otherwise
+
+--*/
+{
+  EFI_IMAGE_DOS_HEADER            DosHeader;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
+
+  //
+  // Position to the start of the file
+  //
+  fseek (Fptr, 0, SEEK_SET);
+
+  //
+  // Read the DOS header
+  //
+  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
+    Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL);
+    return STATUS_ERROR;
+  }
+  //
+  // Check the magic number (0x5A4D)
+  //
+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+    Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!");
+    return STATUS_ERROR;
+  }
+  //
+  // Position into the file and check the PE signature
+  //
+  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
+
+  //
+  // Read PE headers
+  //
+  if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) {
+    Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL);
+    return STATUS_ERROR;
+  }
+
+
+  //
+  // Check the PE signature in the header "PE\0\0"
+  //
+  if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+    Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!");
+    return STATUS_ERROR;
+  }
+
+  memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2);
+
+  if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+    *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem;
+  } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+    *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem;
+  } else {
+    Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!");
+    return STATUS_ERROR;
+  }
+
+  if (mOptions.Verbose) {
+    VerboseMsg("  Got subsystem = 0x%X from image\n", *SubSystem);
+  }
+
+  //
+  // File was successfully identified as a PE32
+  //
+  return STATUS_SUCCESS;
+}
+
+static
+int
+ParseCommandLine (
+  int         Argc,
+  char        *Argv[],
+  OPTIONS     *Options
+  )
+/*++
+
+Routine Description:
+  
+  Given the Argc/Argv program arguments, and a pointer to an options structure,
+  parse the command-line options and check their validity.
+
+
+Arguments:
+
+  Argc            - standard C main() argument count
+  Argv[]          - standard C main() argument list
+  Options         - pointer to a structure to store the options in
+
+Returns:
+
+  STATUS_SUCCESS    success
+  non-zero          otherwise
+
+--*/
+{
+  FILE_LIST *FileList;
+  FILE_LIST *PrevFileList;
+  UINT32    FileFlags;
+  UINT32    ClassCode;
+  UINT32    CodeRevision;
+  EFI_STATUS Status;
+  BOOLEAN    EfiRomFlag;
+  UINT64     TempValue;
+
+  FileFlags = 0;
+  EfiRomFlag = FALSE;
+
+  //
+  // Clear out the options
+  //
+  memset ((char *) Options, 0, sizeof (OPTIONS));
+
+  //
+  // To avoid compile warnings
+  //
+  FileList                = PrevFileList = NULL;
+
+  ClassCode               = 0;
+  CodeRevision            = 0;
+  //
+  // Skip over the program name
+  //
+  Argc--;
+  Argv++;
+
+  //
+  // If no arguments, assume they want usage info
+  //
+  if (Argc == 0) {
+    Usage ();
+    return STATUS_ERROR;
+  }
+  
+  if ((stricmp(Argv[0], "-h") == 0) || (stricmp(Argv[0], "--help") == 0)) {
+    Usage();
+    return STATUS_ERROR;
+  }
+  
+  if ((stricmp(Argv[0], "--version") == 0)) {
+    Version();
+    return STATUS_ERROR;
+  }
+
+  //
+  // Process until no more arguments
+  //
+  while (Argc > 0) {
+    if (Argv[0][0] == '-') {
+      //
+      // Vendor ID specified with -f
+      //
+      if (stricmp (Argv[0], "-f") == 0) {
+        //
+        // Make sure there's another parameter
+        //
+        Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+          return 1;
+        }
+        if (TempValue >= 0x10000) {
+          Error (NULL, 0, 2000, "Invalid option value", "Vendor Id %s out of range!", Argv[1]);
+          return 1;
+        }
+        Options->VendId       = (UINT16) TempValue;
+        Options->VendIdValid  = 1;
+
+        Argv++;
+        Argc--;
+      } else if (stricmp (Argv[0], "-i") == 0) {
+        //
+        // Device ID specified with -i
+        // Make sure there's another parameter
+        //
+        Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+          return 1;
+        }
+        if (TempValue >= 0x10000) {
+          Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);
+          return 1;
+        }
+        Options->DevId      = (UINT16) TempValue;
+        Options->DevIdValid = 1;
+
+        Argv++;
+        Argc--;
+      } else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) {
+        //
+        // Output filename specified with -o
+        // Make sure there's another parameter
+        //
+        if (Argv[1] == NULL || Argv[1][0] == '-') {
+          Error (NULL, 0, 2000, "Invalid parameter", "Missing output file name with %s option!", Argv[0]);
+          return STATUS_ERROR;
+        }
+        strcpy (Options->OutFileName, Argv[1]);
+
+        Argv++;
+        Argc--;
+      } else if ((stricmp (Argv[0], "-h") == 0) || (stricmp (Argv[0], "--help") == 0)) {
+        //
+        // Help option
+        //
+        Usage ();
+        return STATUS_ERROR;
+      } else if (stricmp (Argv[0], "-b") == 0) {
+        //
+        // Specify binary files with -b
+        //
+        FileFlags = FILE_FLAG_BINARY;
+      } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) {
+        //
+        // Specify EFI files with -e. Specify EFI-compressed with -c.
+        //
+        FileFlags = FILE_FLAG_EFI;
+        if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) {
+          FileFlags |= FILE_FLAG_COMPRESS;
+        }
+        //
+        // Specify not to set the LAST bit in the last file with -n
+        //
+      } else if (stricmp (Argv[0], "-n") == 0) {
+        Options->NoLast = 1;
+      } else if (((stricmp (Argv[0], "-v") == 0)) || ((stricmp (Argv[0], "--verbose") == 0))) {
+        //
+        // -v for verbose
+        //
+        Options->Verbose = 1;
+      } else if (stricmp (Argv[0], "--debug") == 0) {
+        Status = AsciiStringToUint64(Argv[1], FALSE, &DebugLevel);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+          return 1;
+        }
+        if (DebugLevel > 9)  {
+          Error (NULL, 0, 2000, "Invalid option value", "Debug Level range is 0-9, current input level is %d", Argv[1]);
+          return 1;
+        }
+        if (DebugLevel>=5 && DebugLevel<=9) {
+          Options->Debug = TRUE;
+        } else {
+          Options->Debug = FALSE;
+        }
+        Argv++;
+        Argc--;
+      } else if ((stricmp (Argv[0], "--quiet") == 0) || (stricmp (Argv[0], "-q") == 0)) {
+        Options->Quiet = TRUE;
+      } else if ((stricmp (Argv[0], "--dump") == 0) || (stricmp (Argv[0], "-d") == 0)) {
+        //
+        // -dump for dumping a ROM image. In this case, say that the device id
+        // and vendor id are valid so we don't have to specify bogus ones on the
+        // command line.
+        //
+        Options->DumpOption   = 1;
+
+        Options->VendIdValid  = 1;
+        Options->DevIdValid   = 1;
+        FileFlags             = FILE_FLAG_BINARY;
+      } else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) {
+        //
+        // Class code value for the next file in the list.
+        // Make sure there's another parameter
+        //
+        Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+          return 1;
+        }
+        ClassCode = (UINT32) TempValue;
+        if (ClassCode & 0xFF000000) {
+          Error (NULL, 0, 2000, "Invalid parameter", "Class code %s out of range!", Argv[1]);
+          return STATUS_ERROR;
+        }
+        if (FileList != NULL && FileList->ClassCode == 0) {
+          FileList->ClassCode = ClassCode;
+        }
+        Argv++;
+        Argc--;
+      } else if ((stricmp (Argv[0], "-r") == 0) || (stricmp (Argv[0], "--Revision") == 0)) {
+        //
+        // Code revision in the PCI data structure. The value is for the next
+        // file in the list.
+        // Make sure there's another parameter
+        //
+        Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+          return 1;
+        }
+        CodeRevision = (UINT32) TempValue;
+        if (CodeRevision & 0xFFFF0000) {
+          Error (NULL, 0, 2000, "Invalid parameter", "Code revision %s out of range!", Argv[1]);
+          return STATUS_ERROR;
+        }
+        if (FileList != NULL && FileList->CodeRevision == 0) {
+          FileList->CodeRevision = (UINT16) CodeRevision;
+        }
+        Argv++;
+        Argc--;
+      } else if ((stricmp (Argv[0], "-p") == 0) || (stricmp (Argv[0], "--pci23") == 0)) {
+        //
+        // Default layout meets PCI 3.0 specifications, specifying this flag will for a PCI 2.3 layout.
+        //
+        mOptions.Pci23 = 1;
+      } else {
+        Error (NULL, 0, 2000, "Invalid parameter", "Invalid option specified: %s", Argv[0]);
+        return STATUS_ERROR;
+      }
+    } else {
+      //
+      // Not a slash-option argument. Must be a file name. Make sure they've specified
+      // -e or -b already.
+      //
+      if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) {
+        Error (NULL, 0, 2000, "Invalid parameter", "Missing -e or -b with input file %s!", Argv[0]);
+        return STATUS_ERROR;
+      }
+      //
+      // Check Efi Option RomImage
+      //
+      if ((FileFlags & FILE_FLAG_EFI) == FILE_FLAG_EFI) {
+        EfiRomFlag = TRUE;
+      }
+      //
+      // Create a new file structure
+      //
+      FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST));
+      if (FileList == NULL) {
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);
+        return STATUS_ERROR;
+      }
+      
+      //
+      // set flag and class code for this image.
+      //
+      memset ((char *) FileList, 0, sizeof (FILE_LIST));
+      FileList->FileName      = Argv[0];
+      FileList->FileFlags     = FileFlags;
+      FileList->ClassCode     = ClassCode;
+      FileList->CodeRevision  = (UINT16) CodeRevision;
+      ClassCode               = 0;
+      CodeRevision            = 0;
+
+      if (Options->FileList == NULL) {
+        Options->FileList = FileList;
+      } else {
+        if (PrevFileList == NULL) {
+          PrevFileList = FileList;
+        } else {          
+          PrevFileList->Next = FileList;
+        }
+      }
+
+      PrevFileList = FileList;
+    }
+    //
+    // Next argument
+    //
+    Argv++;
+    Argc--;
+  }
+
+  //
+  // Must have specified some files
+  //
+  if (Options->FileList == NULL) {
+    Error (NULL, 0, 2000, "Invalid parameter", "Missing input file name!");
+    return STATUS_ERROR;
+  }
+
+  //
+  // For EFI OptionRom image, Make sure a device ID and vendor ID are both specified.
+  //
+  if (EfiRomFlag) {
+    if (!Options->VendIdValid) {
+      Error (NULL, 0, 2000, "Missing Vendor ID in command line", NULL);
+      return STATUS_ERROR;
+    }
+  
+    if (!Options->DevIdValid) {
+      Error (NULL, 0, 2000, "Missing Device ID in command line", NULL);
+      return STATUS_ERROR;
+    }
+  }
+
+  return 0;
+}
+
+static
+void
+Version (
+  VOID
+  )
+/*++
+
+Routine Description:
+  
+  Print version information for this utility.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  Nothing.
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+   
+static
+void
+Usage (
+  VOID
+  )
+/*++
+
+Routine Description:
+  
+  Print usage information for this utility.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  Nothing.
+
+--*/
+{
+  //
+  // Summary usage
+  //
+  fprintf (stdout, "Usage: %s -f VendorId -i DeviceId [options] [file name<s>] \n\n", UTILITY_NAME);
+  
+  //
+  // Copyright declaration
+  // 
+  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
+
+  //
+  // Details Option
+  //
+  fprintf (stdout, "Options:\n");
+  fprintf (stdout, "  -o FileName, --output FileName\n\
+            File will be created to store the output content.\n");
+  fprintf (stdout, "  -e EfiFileName\n\
+            EFI PE32 image files.\n");
+  fprintf (stdout, "  -ec EfiFileName\n\
+            EFI PE32 image files and will be compressed.\n");
+  fprintf (stdout, "  -b BinFileName\n\
+            Legacy binary files.\n");
+  fprintf (stdout, "  -l ClassCode\n\
+            Hex ClassCode in the PCI data structure header.\n");
+  fprintf (stdout, "  -r Rev    Hex Revision in the PCI data structure header.\n");
+  fprintf (stdout, "  -n        Not to automatically set the LAST bit in the last file.\n");
+  fprintf (stdout, "  -f VendorId\n\
+            Hex PCI Vendor ID for the device OpROM, must be specified\n");
+  fprintf (stdout, "  -i DeviceId\n\
+            Hex PCI Device ID for the device OpROM, must be specified\n");
+  fprintf (stdout, "  -p, --pci23\n\
+            Default layout meets PCI 3.0 specifications\n\
+            specifying this flag will for a PCI 2.3 layout.\n");
+  fprintf (stdout, "  -d, --dump\n\
+            Dump the headers of an existing option ROM image.\n");
+  fprintf (stdout, "  -v, --verbose\n\
+            Turn on verbose output with informational messages.\n");
+  fprintf (stdout, "  --version Show program's version number and exit.\n");
+  fprintf (stdout, "  -h, --help\n\
+            Show this help message and exit.\n");
+  fprintf (stdout, "  -q, --quiet\n\
+            Disable all messages except FATAL ERRORS.\n");
+  fprintf (stdout, "  --debug [#,0-9]\n\
+            Enable debug messages at level #.\n");  
+}
+
+static
+void
+DumpImage (
+  FILE_LIST *InFile
+  )
+/*++
+
+Routine Description:
+
+  Dump the headers of an existing option ROM image
+
+Arguments:
+
+  InFile  - the file name of an existing option ROM image
+
+Returns:
+
+  none
+
+--*/
+{
+  PCI_EXPANSION_ROM_HEADER      PciRomHdr;
+  FILE                          *InFptr;
+  UINT32                        ImageStart;
+  UINT32                        ImageCount;
+  EFI_PCI_EXPANSION_ROM_HEADER  EfiRomHdr;
+  PCI_DATA_STRUCTURE            PciDs23;
+  PCI_3_0_DATA_STRUCTURE        PciDs30;
+
+  //
+  // Open the input file
+  //
+  if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+    Error (NULL, 0, 0001, "Error opening file", InFile->FileName);
+    return ;
+  }
+  //
+  // Go through the image and dump the header stuff for each
+  //
+  ImageCount = 0;
+  for (;;) {
+    //
+    // Save our postition in the file, since offsets in the headers
+    // are relative to the particular image.
+    //
+    ImageStart = ftell (InFptr);
+    ImageCount++;
+
+    //
+    // Read the option ROM header. Have to assume a raw binary image for now.
+    //
+    if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) {
+      Error (NULL, 0, 3001, "Not supported", "Failed to read PCI ROM header from file!");
+      goto BailOut;
+    }
+
+    //
+    // Dump the contents of the header
+    //
+    fprintf (stdout, "Image %u -- Offset 0x%X\n", (unsigned) ImageCount, (unsigned) ImageStart);
+    fprintf (stdout, "  ROM header contents\n");
+    fprintf (stdout, "    Signature              0x%04X\n", PciRomHdr.Signature);
+    fprintf (stdout, "    PCIR offset            0x%04X\n", PciRomHdr.PcirOffset);
+    //
+    // Find PCI data structure
+    //
+    if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) {
+      Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI data structure!");
+      goto BailOut;
+    }
+    //
+    // Read and dump the PCI data structure
+    //
+    memset (&PciDs23, 0, sizeof (PciDs23));
+    memset (&PciDs30, 0, sizeof (PciDs30));
+    if (mOptions.Pci23 == 1) {
+      if (fread (&PciDs23, sizeof (PciDs23), 1, InFptr) != 1) {
+        Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName);
+        goto BailOut;
+      }
+    } else {
+      if (fread (&PciDs30, sizeof (PciDs30), 1, InFptr) != 1) {
+        Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName);
+        goto BailOut;
+      }
+    }
+    if (mOptions.Verbose) {
+      VerboseMsg("Read PCI data structure from file %s", InFile->FileName);
+    }
+
+    //fprintf (stdout, "  PCI Data Structure\n");
+    if (mOptions.Pci23 == 1) {
+    fprintf (
+      stdout,
+      "    Signature              %c%c%c%c\n",
+      (char) PciDs23.Signature,
+      (char) (PciDs23.Signature >> 8),
+      (char) (PciDs23.Signature >> 16),
+      (char) (PciDs23.Signature >> 24)
+      );
+    fprintf (stdout, "    Vendor ID              0x%04X\n", PciDs23.VendorId);
+    fprintf (stdout, "    Device ID              0x%04X\n", PciDs23.DeviceId);
+    fprintf (stdout, "    Length                 0x%04X\n", PciDs23.Length);
+    fprintf (stdout, "    Revision               0x%04X\n", PciDs23.Revision);
+    fprintf (
+      stdout,
+      "    Class Code             0x%06X\n",
+      (unsigned) (PciDs23.ClassCode[0] | (PciDs23.ClassCode[1] << 8) | (PciDs23.ClassCode[2] << 16))
+      );
+    fprintf (stdout, "    Image size             0x%X\n", (unsigned) PciDs23.ImageLength * 512);
+    fprintf (stdout, "    Code revision:         0x%04X\n", PciDs23.CodeRevision);
+    fprintf (stdout, "    Indicator              0x%02X", PciDs23.Indicator);
+    } else {
+    fprintf (
+      stdout,
+      "    Signature               %c%c%c%c\n",
+      (char) PciDs30.Signature,
+      (char) (PciDs30.Signature >> 8),
+      (char) (PciDs30.Signature >> 16),
+      (char) (PciDs30.Signature >> 24)
+      );
+    fprintf (stdout, "    Vendor ID               0x%04X\n", PciDs30.VendorId);
+    fprintf (stdout, "    Device ID               0x%04X\n", PciDs30.DeviceId);
+    fprintf (stdout, "    Length                  0x%04X\n", PciDs30.Length);
+    fprintf (stdout, "    Revision                0x%04X\n", PciDs30.Revision);
+    fprintf (stdout, "    DeviceListOffset        0x%02X\n", PciDs30.DeviceListOffset);    
+    fprintf (
+      stdout,
+      "    Class Code              0x%06X\n",
+      (unsigned) (PciDs30.ClassCode[0] | (PciDs30.ClassCode[1] << 8) | (PciDs30.ClassCode[2] << 16))
+      );
+    fprintf (stdout, "    Image size              0x%X\n", (unsigned) PciDs30.ImageLength * 512);
+    fprintf (stdout, "    Code revision:          0x%04X\n", PciDs30.CodeRevision);
+    fprintf (stdout, "    MaxRuntimeImageLength   0x%02X\n", PciDs30.MaxRuntimeImageLength);
+    fprintf (stdout, "    ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30.ConfigUtilityCodeHeaderOffset);
+    fprintf (stdout, "    DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);   
+    fprintf (stdout, "    Indicator               0x%02X", PciDs30.Indicator);    
+    }
+    //
+    // Print the indicator, used to flag the last image
+    //
+    if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) {
+      fprintf (stdout, "   (last image)\n");
+    } else {
+      fprintf (stdout, "\n");
+    }
+    //
+    // Print the code type. If EFI code, then we can provide more info.
+    //
+    if (mOptions.Pci23 == 1) {
+      fprintf (stdout, "    Code type              0x%02X", PciDs23.CodeType);
+    } else {
+      fprintf (stdout, "    Code type               0x%02X", PciDs30.CodeType); 
+    }
+    if (PciDs23.CodeType == PCI_CODE_TYPE_EFI_IMAGE || PciDs30.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
+      fprintf (stdout, "   (EFI image)\n");
+      //
+      // Re-read the header as an EFI ROM header, then dump more info
+      //
+      fprintf (stdout, "  EFI ROM header contents\n");
+      if (fseek (InFptr, ImageStart, SEEK_SET)) {
+        Error (NULL, 0, 5001, "Failed to re-seek to ROM header structure!", NULL);
+        goto BailOut;
+      }
+
+      if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {
+        Error (NULL, 0, 5001, "Failed to read EFI PCI ROM header from file!", NULL);
+        goto BailOut;
+      }
+      //
+      // Now dump more info
+      //
+      fprintf (stdout, "    EFI Signature          0x%04X\n", (unsigned) EfiRomHdr.EfiSignature);
+      fprintf (
+        stdout,
+        "    Compression Type       0x%04X ",
+        EfiRomHdr.CompressionType
+        );
+      if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+        fprintf (stdout, "(compressed)\n");
+      } else {
+        fprintf (stdout, "(not compressed)\n");
+      }
+
+      fprintf (
+        stdout,
+        "    Machine type           0x%04X (%s)\n",
+        EfiRomHdr.EfiMachineType,
+        GetMachineTypeStr (EfiRomHdr.EfiMachineType)
+        );
+      fprintf (
+        stdout,
+        "    Subsystem              0x%04X (%s)\n",
+        EfiRomHdr.EfiSubsystem,
+        GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem)
+        );
+      fprintf (
+        stdout,
+        "    EFI image offset       0x%04X (@0x%X)\n",
+        EfiRomHdr.EfiImageHeaderOffset,
+        EfiRomHdr.EfiImageHeaderOffset + (unsigned) ImageStart
+        );
+
+    } else {
+      //
+      // Not an EFI image
+      //
+      fprintf (stdout, "\n");
+    }
+    //
+    // If code type is EFI image, then dump it as well?
+    //
+    // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
+    // }
+    //
+    // If last image, then we're done
+    //
+    if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) {
+      goto BailOut;
+    }
+    //
+    // Seek to the start of the next image
+    //
+    if (mOptions.Pci23 == 1) {
+      if (fseek (InFptr, ImageStart + (PciDs23.ImageLength * 512), SEEK_SET)) {
+        Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!");
+        goto BailOut;
+      }
+    } else {
+      if (fseek (InFptr, ImageStart + (PciDs30.ImageLength * 512), SEEK_SET)) {
+        Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!");
+        goto BailOut;
+      }
+    }
+  }
+
+BailOut:
+  fclose (InFptr);
+}
+
+char *
+GetMachineTypeStr (
+  UINT16    MachineType
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  MachineType - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  int Index;
+
+  for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {
+    if (mMachineTypes[Index].Value == MachineType) {
+      return mMachineTypes[Index].Name;
+    }
+  }
+
+  return "unknown";
+}
+
+static
+char *
+GetSubsystemTypeStr (
+  UINT16  SubsystemType
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SubsystemType - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  int Index;
+
+  for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {
+    if (mSubsystemTypes[Index].Value == SubsystemType) {
+      return mSubsystemTypes[Index].Name;
+    }
+  }
+
+  return "unknown";
+}
diff --git a/EfiRom/EfiRom.h b/EfiRom/EfiRom.h
new file mode 100644
index 0000000..ce22f31
--- /dev/null
+++ b/EfiRom/EfiRom.h
@@ -0,0 +1,357 @@
+/** @file
+This file contains the relevant declarations required to generate Option Rom File
+
+Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available 
+under the terms and conditions of the BSD License which accompanies this 
+distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_ROM_H__
+#define __EFI_ROM_H__
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h> // for PE32 structure definitions
+
+#include <IndustryStandard/pci22.h>  // for option ROM header structures
+#include <IndustryStandard/pci30.h>
+
+#include "Compress.h"
+#include "CommonLib.h"
+
+//
+// Version of this utility
+//
+#define UTILITY_NAME "EfiRom"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+//
+// Define the max length of a filename
+//
+#define MAX_PATH                  200
+
+//
+// Define the default file extension name
+//
+#define DEFAULT_OUTPUT_EXTENSION  ".rom"
+
+//
+// Max size for an option ROM image
+//
+#define MAX_OPTION_ROM_SIZE (1024 * 1024 * 16)  // 16MB
+
+//
+// Values for the indicator field in the PCI data structure
+//
+#define INDICATOR_LAST  0x80  // last file in series of files
+
+//
+// Masks for the FILE_LIST.FileFlags field
+//
+#define FILE_FLAG_BINARY    0x01
+#define FILE_FLAG_EFI       0x02
+#define FILE_FLAG_COMPRESS  0x04
+
+//
+// Use this linked list structure to keep track of all the filenames
+// specified on the command line.
+//
+typedef struct _FILE_LIST {
+  struct _FILE_LIST *Next;
+  CHAR8             *FileName;
+  UINT32            FileFlags;
+  UINT32            ClassCode;
+  UINT16            CodeRevision;
+} FILE_LIST;
+
+//
+// Use this to track our command-line options
+//
+typedef struct {
+  CHAR8     OutFileName[MAX_PATH];
+  INT8      NoLast;
+  UINT16    ClassCode;
+  UINT16    PciRevision;
+  UINT16    VendId;
+  UINT16    DevId;
+  UINT8     VendIdValid;
+  UINT8     DevIdValid;
+  INT8      Verbose;
+  INT8      Quiet;
+  INT8      Debug;
+  INT8      Pci23;
+  INT8      Pci30;
+  INT8      DumpOption;
+//  INT8      Help;
+//  INT8      Version;  
+  FILE_LIST *FileList;
+} OPTIONS;
+
+//
+// Make a global structure to keep track of command-line options
+//
+static OPTIONS  mOptions;
+
+//
+// Use these to convert from machine type value to a named type
+//
+typedef struct {
+  UINT16  Value;
+  CHAR8   *Name;
+} STRING_LOOKUP;
+
+//
+// Machine Types
+//
+static STRING_LOOKUP  mMachineTypes[] = {
+  { EFI_IMAGE_MACHINE_IA32, "IA32" },
+  { EFI_IMAGE_MACHINE_IA64, "IA64" },
+  { EFI_IMAGE_MACHINE_EBC, "EBC" },
+  { 0, NULL }
+};
+
+//
+// Subsystem Types
+//
+static STRING_LOOKUP  mSubsystemTypes[] = {
+  { EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, "EFI application" },
+  { EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, "EFI boot service driver" },
+  { EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, "EFI runtime driver" },
+  { 0, NULL }
+};
+
+//
+//  Function prototypes
+//
+static
+void
+Version (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Displays the utility version to STDOUT
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+;
+
+static
+void
+Usage (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/  
+;
+
+static
+int
+ParseCommandLine (
+  int       Argc,
+  char      *Argv[],
+  OPTIONS   *Options
+  )
+/*++
+
+Routine Description:
+  
+  Given the Argc/Argv program arguments, and a pointer to an options structure,
+  parse the command-line options and check their validity.
+
+Arguments:
+
+  Argc            - standard C main() argument count
+  Argv[]          - standard C main() argument list
+  Options         - pointer to a structure to store the options in
+
+Returns:
+
+  STATUS_SUCCESS    success
+  non-zero          otherwise
+
+--*/
+;
+
+static
+int
+CheckPE32File (
+  FILE      *Fptr,
+  UINT16    *MachineType,
+  UINT16    *SubSystem
+  )
+/*++
+
+Routine Description:
+  
+  Given the Argc/Argv program arguments, and a pointer to an options structure,
+  parse the command-line options and check their validity.
+
+Arguments:
+
+  Argc            - standard C main() argument count
+  Argv[]          - standard C main() argument list
+  Options         - pointer to a structure to store the options in
+
+Returns:
+
+  STATUS_SUCCESS    success
+  non-zero          otherwise
+
+--*/  
+;
+
+static
+int
+ProcessEfiFile (
+  FILE      *OutFptr,
+  FILE_LIST *InFile,
+  UINT16    VendId,
+  UINT16    DevId,
+  UINT32    *Size
+  )
+/*++
+
+Routine Description:
+  
+  Process a PE32 EFI file.
+
+Arguments:
+
+  OutFptr     - file pointer to output binary ROM image file we're creating
+  InFile      - structure contains information on the PE32 file to process
+  VendId      - vendor ID as required in the option ROM header
+  DevId       - device ID as required in the option ROM header
+  Size        - pointer to where to return the size added to the output file
+
+Returns:
+
+  0 - successful
+
+--*/
+;
+
+static
+int
+ProcessBinFile (
+  FILE      *OutFptr,
+  FILE_LIST *InFile,
+  UINT32    *Size
+  )
+/*++
+
+Routine Description:
+  
+  Process a binary input file.
+
+Arguments:
+
+  OutFptr     - file pointer to output binary ROM image file we're creating
+  InFile      - structure contains information on the binary file to process
+  Size        - pointer to where to return the size added to the output file
+
+Returns:
+
+  0 - successful
+
+--*/  
+;
+
+static
+void
+DumpImage (
+  FILE_LIST *InFile
+  )
+/*++
+
+Routine Description:
+
+  Dump the headers of an existing option ROM image
+
+Arguments:
+
+  InFile  - the file name of an existing option ROM image
+
+Returns:
+
+  none
+
+--*/
+;
+
+char                  *
+GetMachineTypeStr (
+  UINT16    MachineType
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  MachineType - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+static
+char                  *
+GetSubsystemTypeStr (
+  UINT16  SubsystemType
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SubsystemType - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EfiRom/Include/Common/BaseTypes.h b/EfiRom/Include/Common/BaseTypes.h
new file mode 100644
index 0000000..4dbba73
--- /dev/null
+++ b/EfiRom/Include/Common/BaseTypes.h
@@ -0,0 +1,286 @@
+/** @file
+  Processor or Compiler specific defines for all supported processors.
+
+  This file is stand alone self consistent set of definitions. 
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __BASE_TYPES_H__
+#define __BASE_TYPES_H__
+
+//
+// Include processor specific binding
+//
+#include <ProcessorBind.h>
+#include <stdarg.h>
+
+//
+// Modifiers to abstract standard types to aid in debug of problems
+//
+#define CONST     const
+#define STATIC    static
+#define VOID      void
+
+//
+// Modifiers for Data Types used to self document code.
+// This concept is borrowed for UEFI specification.
+//
+#ifndef IN
+//
+// Some other environments use this construct, so #ifndef to prevent
+// multiple definition.
+//
+#define IN
+#define OUT
+#define OPTIONAL
+#endif
+
+//
+// Constants. They may exist in other build structures, so #ifndef them.
+//
+#ifndef TRUE
+//
+// BugBug: UEFI specification claims 1 and 0. We are concerned about the 
+//  complier portability so we did it this way.
+//
+#define TRUE  ((BOOLEAN)(1==1))
+#endif
+
+#ifndef FALSE
+#define FALSE ((BOOLEAN)(0==1))
+#endif
+
+#ifndef NULL
+#define NULL  ((VOID *) 0)
+#endif
+
+//
+//  Support for variable length argument lists using the ANSI standard.
+//  
+//  Since we are using the ANSI standard we used the standard naming and
+//  did not follow the coding convention
+//
+//  VA_LIST  - typedef for argument list.
+//  VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
+//  VA_END (VA_LIST Marker) - Clear Marker
+//  VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
+//    the ... list. You must know the size and pass it in this macro.
+//
+//  example:
+//
+//  UINTN
+//  ExampleVarArg (
+//    IN UINTN  NumberOfArgs,
+//    ...
+//    )
+//  {
+//    VA_LIST Marker;
+//    UINTN   Index;
+//    UINTN   Result;
+//
+//    //
+//    // Initialize the Marker
+//    //
+//    VA_START (Marker, NumberOfArgs);
+//    for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
+//      //
+//      // The ... list is a series of UINTN values, so average them up.
+//      //
+//      Result += VA_ARG (Marker, UINTN);
+//    }
+//
+//    VA_END (Marker);
+//    return Result
+//  }
+//
+
+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
+
+//
+// Also support coding convention rules for var arg macros
+//
+#ifndef VA_START
+
+// typedef CHAR8 *VA_LIST;
+// #define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v))
+// #define VA_ARG(ap, t)   (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t)))
+// #define VA_END(ap)      (ap = (VA_LIST) 0)
+// Use the native arguments for tools.
+#define VA_START va_start
+#define VA_ARG   va_arg
+#define VA_END   va_end
+#define VA_LIST  va_list
+
+#endif
+
+//
+// Macro that returns the byte offset of a field in a data structure. 
+//
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+
+///
+///  _CR - returns a pointer to the structure
+///      from one of it's elements.
+///
+#define _CR(Record, TYPE, Field)  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+///
+///  ALIGN_POINTER - aligns a pointer to the lowest boundary
+///
+#define ALIGN_POINTER(p, s) ((VOID *) ((UINTN)(p) + (((s) - ((UINTN) (p))) & ((s) - 1))))
+
+///
+///  ALIGN_VARIABLE - aligns a variable up to the next natural boundary for int size of a processor
+///
+#define ALIGN_VARIABLE(Value, Adjustment) \
+  Adjustment = 0U; \
+  if ((UINTN) (Value) % sizeof (UINTN)) { \
+    (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \
+  } \
+  (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment))
+
+//
+// Return the maximum of two operands. 
+// This macro returns the maximum of two operand specified by a and b.  
+// Both a and b must be the same numerical types, signed or unsigned.
+//
+#define MAX(a, b)                       \
+  (((a) > (b)) ? (a) : (b))
+
+
+//
+// Return the minimum of two operands. 
+// This macro returns the minimal of two operand specified by a and b.  
+// Both a and b must be the same numerical types, signed or unsigned.
+//
+#define MIN(a, b)                       \
+  (((a) < (b)) ? (a) : (b))
+
+
+//
+// EFI Error Codes common to all execution phases
+//
+
+typedef INTN RETURN_STATUS;
+
+///
+/// Set the upper bit to indicate EFI Error.
+///
+#define ENCODE_ERROR(a)              (MAX_BIT | (a))
+
+#define ENCODE_WARNING(a)            (a)
+#define RETURN_ERROR(a)              ((a) < 0)
+
+#define RETURN_SUCCESS               0
+#define RETURN_LOAD_ERROR            ENCODE_ERROR (1)
+#define RETURN_INVALID_PARAMETER     ENCODE_ERROR (2)
+#define RETURN_UNSUPPORTED           ENCODE_ERROR (3)
+#define RETURN_BAD_BUFFER_SIZE       ENCODE_ERROR (4)
+#define RETURN_BUFFER_TOO_SMALL      ENCODE_ERROR (5)
+#define RETURN_NOT_READY             ENCODE_ERROR (6)
+#define RETURN_DEVICE_ERROR          ENCODE_ERROR (7)
+#define RETURN_WRITE_PROTECTED       ENCODE_ERROR (8)
+#define RETURN_OUT_OF_RESOURCES      ENCODE_ERROR (9)
+#define RETURN_VOLUME_CORRUPTED      ENCODE_ERROR (10)
+#define RETURN_VOLUME_FULL           ENCODE_ERROR (11)
+#define RETURN_NO_MEDIA              ENCODE_ERROR (12)
+#define RETURN_MEDIA_CHANGED         ENCODE_ERROR (13)
+#define RETURN_NOT_FOUND             ENCODE_ERROR (14)
+#define RETURN_ACCESS_DENIED         ENCODE_ERROR (15)
+#define RETURN_NO_RESPONSE           ENCODE_ERROR (16)
+#define RETURN_NO_MAPPING            ENCODE_ERROR (17)
+#define RETURN_TIMEOUT               ENCODE_ERROR (18)
+#define RETURN_NOT_STARTED           ENCODE_ERROR (19)
+#define RETURN_ALREADY_STARTED       ENCODE_ERROR (20)
+#define RETURN_ABORTED               ENCODE_ERROR (21)
+#define RETURN_ICMP_ERROR            ENCODE_ERROR (22)
+#define RETURN_TFTP_ERROR            ENCODE_ERROR (23)
+#define RETURN_PROTOCOL_ERROR        ENCODE_ERROR (24)
+#define RETURN_INCOMPATIBLE_VERSION  ENCODE_ERROR (25)
+#define RETURN_SECURITY_VIOLATION    ENCODE_ERROR (26)
+#define RETURN_CRC_ERROR             ENCODE_ERROR (27)
+#define RETURN_END_OF_MEDIA          ENCODE_ERROR (28)
+#define RETURN_END_OF_FILE           ENCODE_ERROR (31)
+
+#define RETURN_WARN_UNKNOWN_GLYPH    ENCODE_WARNING (1)
+#define RETURN_WARN_DELETE_FAILURE   ENCODE_WARNING (2)
+#define RETURN_WARN_WRITE_FAILURE    ENCODE_WARNING (3)
+#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)
+
+typedef UINT64 PHYSICAL_ADDRESS;
+
+#define  BIT0     0x00000001
+#define  BIT1     0x00000002
+#define  BIT2     0x00000004
+#define  BIT3     0x00000008
+#define  BIT4     0x00000010
+#define  BIT5     0x00000020
+#define  BIT6     0x00000040
+#define  BIT7     0x00000080
+#define  BIT8     0x00000100
+#define  BIT9     0x00000200
+#define  BIT10    0x00000400
+#define  BIT11    0x00000800
+#define  BIT12    0x00001000
+#define  BIT13    0x00002000
+#define  BIT14    0x00004000
+#define  BIT15    0x00008000
+#define  BIT16    0x00010000
+#define  BIT17    0x00020000
+#define  BIT18    0x00040000
+#define  BIT19    0x00080000
+#define  BIT20    0x00100000
+#define  BIT21    0x00200000
+#define  BIT22    0x00400000
+#define  BIT23    0x00800000
+#define  BIT24    0x01000000
+#define  BIT25    0x02000000
+#define  BIT26    0x04000000
+#define  BIT27    0x08000000
+#define  BIT28    0x10000000
+#define  BIT29    0x20000000
+#define  BIT30    0x40000000
+#define  BIT31    0x80000000
+#define  BIT32    0x0000000100000000ULL
+#define  BIT33    0x0000000200000000ULL
+#define  BIT34    0x0000000400000000ULL
+#define  BIT35    0x0000000800000000ULL
+#define  BIT36    0x0000001000000000ULL
+#define  BIT37    0x0000002000000000ULL
+#define  BIT38    0x0000004000000000ULL
+#define  BIT39    0x0000008000000000ULL
+#define  BIT40    0x0000010000000000ULL
+#define  BIT41    0x0000020000000000ULL
+#define  BIT42    0x0000040000000000ULL
+#define  BIT43    0x0000080000000000ULL
+#define  BIT44    0x0000100000000000ULL
+#define  BIT45    0x0000200000000000ULL
+#define  BIT46    0x0000400000000000ULL
+#define  BIT47    0x0000800000000000ULL
+#define  BIT48    0x0001000000000000ULL
+#define  BIT49    0x0002000000000000ULL
+#define  BIT50    0x0004000000000000ULL
+#define  BIT51    0x0008000000000000ULL
+#define  BIT52    0x0010000000000000ULL
+#define  BIT53    0x0020000000000000ULL
+#define  BIT54    0x0040000000000000ULL
+#define  BIT55    0x0080000000000000ULL
+#define  BIT56    0x0100000000000000ULL
+#define  BIT57    0x0200000000000000ULL
+#define  BIT58    0x0400000000000000ULL
+#define  BIT59    0x0800000000000000ULL
+#define  BIT60    0x1000000000000000ULL
+#define  BIT61    0x2000000000000000ULL
+#define  BIT62    0x4000000000000000ULL
+#define  BIT63    0x8000000000000000ULL
+
+#endif
diff --git a/EfiRom/Include/Common/BuildVersion.h b/EfiRom/Include/Common/BuildVersion.h
new file mode 100644
index 0000000..2892926
--- /dev/null
+++ b/EfiRom/Include/Common/BuildVersion.h
@@ -0,0 +1,15 @@
+/** @file
+This file is for build version number auto generation
+
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#define __BUILD_VERSION ""
diff --git a/EfiRom/Include/Common/UefiBaseTypes.h b/EfiRom/Include/Common/UefiBaseTypes.h
new file mode 100644
index 0000000..d52fa3e
--- /dev/null
+++ b/EfiRom/Include/Common/UefiBaseTypes.h
@@ -0,0 +1,175 @@
+/** @file
+  Defines data types and constants introduced in UEFI.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_BASETYPE_H__
+#define __UEFI_BASETYPE_H__
+
+#include <Common/BaseTypes.h>
+
+//
+// Basical data type definitions introduced in UEFI.
+// 
+typedef struct {
+  UINT32  Data1;
+  UINT16  Data2;
+  UINT16  Data3;
+  UINT8   Data4[8];
+} EFI_GUID;
+
+typedef RETURN_STATUS             EFI_STATUS;
+typedef VOID                      *EFI_HANDLE;
+
+typedef VOID                      *EFI_EVENT;
+
+typedef UINTN                     EFI_TPL;
+
+
+typedef UINT64                    EFI_LBA;
+
+
+typedef UINT16                    STRING_REF;
+
+typedef UINT64                    EFI_PHYSICAL_ADDRESS;
+typedef UINT64                    EFI_VIRTUAL_ADDRESS;
+
+//
+// EFI Time Abstraction:
+//  Year:       2000 - 20XX
+//  Month:      1 - 12
+//  Day:        1 - 31
+//  Hour:       0 - 23
+//  Minute:     0 - 59
+//  Second:     0 - 59
+//  Nanosecond: 0 - 999,999,999
+//  TimeZone:   -1440 to 1440 or 2047
+//
+typedef struct {
+  UINT16  Year;
+  UINT8   Month;
+  UINT8   Day;
+  UINT8   Hour;
+  UINT8   Minute;
+  UINT8   Second;
+  UINT8   Pad1;
+  UINT32  Nanosecond;
+  INT16   TimeZone;
+  UINT8   Daylight;
+  UINT8   Pad2;
+} EFI_TIME;
+
+
+//
+// Networking Definitions
+//
+typedef struct {
+  UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+typedef struct {
+  UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+typedef struct {
+  UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+typedef union {
+  UINT32            Addr[4];
+  EFI_IPv4_ADDRESS  v4;
+  EFI_IPv6_ADDRESS  v6;
+} EFI_IP_ADDRESS;
+
+
+//
+// Enumeration of EFI_STATUS.
+// 
+#define EFI_SUCCESS               RETURN_SUCCESS              
+#define EFI_LOAD_ERROR            RETURN_LOAD_ERROR           
+#define EFI_INVALID_PARAMETER     RETURN_INVALID_PARAMETER    
+#define EFI_UNSUPPORTED           RETURN_UNSUPPORTED          
+#define EFI_BAD_BUFFER_SIZE       RETURN_BAD_BUFFER_SIZE      
+#define EFI_BUFFER_TOO_SMALL      RETURN_BUFFER_TOO_SMALL     
+#define EFI_NOT_READY             RETURN_NOT_READY            
+#define EFI_DEVICE_ERROR          RETURN_DEVICE_ERROR         
+#define EFI_WRITE_PROTECTED       RETURN_WRITE_PROTECTED      
+#define EFI_OUT_OF_RESOURCES      RETURN_OUT_OF_RESOURCES     
+#define EFI_VOLUME_CORRUPTED      RETURN_VOLUME_CORRUPTED     
+#define EFI_VOLUME_FULL           RETURN_VOLUME_FULL          
+#define EFI_NO_MEDIA              RETURN_NO_MEDIA             
+#define EFI_MEDIA_CHANGED         RETURN_MEDIA_CHANGED        
+#define EFI_NOT_FOUND             RETURN_NOT_FOUND            
+#define EFI_ACCESS_DENIED         RETURN_ACCESS_DENIED        
+#define EFI_NO_RESPONSE           RETURN_NO_RESPONSE          
+#define EFI_NO_MAPPING            RETURN_NO_MAPPING           
+#define EFI_TIMEOUT               RETURN_TIMEOUT              
+#define EFI_NOT_STARTED           RETURN_NOT_STARTED          
+#define EFI_ALREADY_STARTED       RETURN_ALREADY_STARTED      
+#define EFI_ABORTED               RETURN_ABORTED              
+#define EFI_ICMP_ERROR            RETURN_ICMP_ERROR           
+#define EFI_TFTP_ERROR            RETURN_TFTP_ERROR           
+#define EFI_PROTOCOL_ERROR        RETURN_PROTOCOL_ERROR       
+#define EFI_INCOMPATIBLE_VERSION  RETURN_INCOMPATIBLE_VERSION 
+#define EFI_SECURITY_VIOLATION    RETURN_SECURITY_VIOLATION   
+#define EFI_CRC_ERROR             RETURN_CRC_ERROR   
+#define EFI_END_OF_MEDIA          RETURN_END_OF_MEDIA
+#define EFI_END_OF_FILE           RETURN_END_OF_FILE
+
+#define EFI_WARN_UNKNOWN_GLYPH    RETURN_WARN_UNKNOWN_GLYPH   
+#define EFI_WARN_DELETE_FAILURE   RETURN_WARN_DELETE_FAILURE  
+#define EFI_WARN_WRITE_FAILURE    RETURN_WARN_WRITE_FAILURE   
+#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
+
+
+#define NULL_HANDLE               ((VOID *) 0)
+
+//
+// Define macro to encode the status code.
+// 
+#define EFIERR(_a)                ENCODE_ERROR(_a)
+
+#define EFI_ERROR(A)              RETURN_ERROR(A)
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define SIGNATURE_16(A, B)        ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D)  (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+    (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+
+
+//
+//  Returns the byte offset to a field within a structure
+//
+#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
+
+//
+// The EFI memory allocation functions work in units of EFI_PAGEs that are
+// 4K. This should in no way be confused with the page size of the processor.
+// An EFI_PAGE is just the quanta of memory in EFI.
+//
+#define EFI_PAGE_SIZE             0x1000
+#define EFI_PAGE_MASK             0xFFF
+#define EFI_PAGE_SHIFT            12
+
+#define EFI_SIZE_TO_PAGES(a)  (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0))
+
+#define EFI_PAGES_TO_SIZE(a)   ( (a) << EFI_PAGE_SHIFT)
+
+
+#define EFI_MAX_BIT               MAX_BIT
+#define EFI_MAX_ADDRESS           MAX_ADDRESS
+
+#endif
diff --git a/EfiRom/Include/IndustryStandard/EfiPci.h b/EfiRom/Include/IndustryStandard/EfiPci.h
new file mode 100644
index 0000000..58c7700
--- /dev/null
+++ b/EfiRom/Include/IndustryStandard/EfiPci.h
@@ -0,0 +1,57 @@
+/** @file
+  Support for EFI PCI specification.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_PCI_H_
+#define _EFI_PCI_H_
+
+//#include "pci22.h"
+//#include "pci23.h"
+//#include "pci30.h"
+
+#pragma pack(push, 1)
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Function;
+  UINT8 Device;
+  UINT8 Bus;
+  UINT8 Reserved[4];
+} DEFIO_PCI_ADDR;
+
+#define EFI_ROOT_BRIDGE_LIST                            'eprb'
+#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE       0x0EF1
+
+typedef struct {
+  UINT16  Signature;    // 0xaa55
+  UINT16  InitializationSize;
+  UINT32  EfiSignature; // 0x0EF1
+  UINT16  EfiSubsystem;
+  UINT16  EfiMachineType;
+  UINT16  CompressionType;
+  UINT8   Reserved[8];
+  UINT16  EfiImageHeaderOffset;
+  UINT16  PcirOffset;
+} EFI_PCI_EXPANSION_ROM_HEADER;
+
+typedef union {
+  UINT8                           *Raw;
+  PCI_EXPANSION_ROM_HEADER        *Generic;
+  EFI_PCI_EXPANSION_ROM_HEADER    *Efi;
+  EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt;
+} EFI_PCI_ROM_HEADER;
+
+#pragma pack(pop)
+
+#endif
diff --git a/EfiRom/Include/IndustryStandard/PeImage.h b/EfiRom/Include/IndustryStandard/PeImage.h
new file mode 100644
index 0000000..342040a
--- /dev/null
+++ b/EfiRom/Include/IndustryStandard/PeImage.h
@@ -0,0 +1,769 @@
+/** @file
+  EFI image format for PE32+. Please note some data structures are different
+  for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64
+
+  @bug Fix text - doc as defined in MSFT EFI specification.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PE_IMAGE_H__
+#define __PE_IMAGE_H__
+
+//
+// PE32+ Subsystem type for EFI images
+//
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13
+
+//
+// BugBug: Need to get a real answer for this problem. This is not in the
+//         PE specification.
+//
+//         A SAL runtime driver does not get fixed up when a transition to
+//         virtual mode is made. In all other cases it should be treated
+//         like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image
+//
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER  13
+
+//
+// PE32+ Machine type for EFI images
+//
+#define IMAGE_FILE_MACHINE_I386     0x014c
+#define IMAGE_FILE_MACHINE_IA64     0x0200
+#define IMAGE_FILE_MACHINE_EBC      0x0EBC
+#define IMAGE_FILE_MACHINE_X64      0x8664
+#define IMAGE_FILE_MACHINE_ARM      0x01c0  // Thumb only
+#define IMAGE_FILE_MACHINE_ARMT     0x01c2  // 32bit Mixed ARM and Thumb/Thumb 2  Little Endian
+#define IMAGE_FILE_MACHINE_ARM64    0xAA64  // 64bit ARM Architecture, Little Endian
+
+//
+// Support old names for backward compatible
+//
+#define EFI_IMAGE_MACHINE_IA32      IMAGE_FILE_MACHINE_I386 
+#define EFI_IMAGE_MACHINE_IA64      IMAGE_FILE_MACHINE_IA64  
+#define EFI_IMAGE_MACHINE_IPF       IMAGE_FILE_MACHINE_IA64  
+#define EFI_IMAGE_MACHINE_EBC       IMAGE_FILE_MACHINE_EBC  
+#define EFI_IMAGE_MACHINE_X64       IMAGE_FILE_MACHINE_X64
+#define EFI_IMAGE_MACHINE_ARMT      IMAGE_FILE_MACHINE_ARMT
+#define EFI_IMAGE_MACHINE_AARCH64   IMAGE_FILE_MACHINE_ARM64
+
+#define EFI_IMAGE_DOS_SIGNATURE     0x5A4D      // MZ
+#define EFI_IMAGE_OS2_SIGNATURE     0x454E      // NE
+#define EFI_IMAGE_OS2_SIGNATURE_LE  0x454C      // LE
+#define EFI_IMAGE_NT_SIGNATURE      0x00004550  // PE00
+#define EFI_IMAGE_EDOS_SIGNATURE    0x44454550  // PEED
+
+///
+/// PE images can start with an optional DOS header, so if an image is run
+///  under DOS it can print an error message.
+///
+typedef struct {
+  UINT16  e_magic;    // Magic number
+  UINT16  e_cblp;     // Bytes on last page of file
+  UINT16  e_cp;       // Pages in file
+  UINT16  e_crlc;     // Relocations
+  UINT16  e_cparhdr;  // Size of header in paragraphs
+  UINT16  e_minalloc; // Minimum extra paragraphs needed
+  UINT16  e_maxalloc; // Maximum extra paragraphs needed
+  UINT16  e_ss;       // Initial (relative) SS value
+  UINT16  e_sp;       // Initial SP value
+  UINT16  e_csum;     // Checksum
+  UINT16  e_ip;       // Initial IP value
+  UINT16  e_cs;       // Initial (relative) CS value
+  UINT16  e_lfarlc;   // File address of relocation table
+  UINT16  e_ovno;     // Overlay number
+  UINT16  e_res[4];   // Reserved words
+  UINT16  e_oemid;    // OEM identifier (for e_oeminfo)
+  UINT16  e_oeminfo;  // OEM information; e_oemid specific
+  UINT16  e_res2[10]; // Reserved words
+  UINT32  e_lfanew;   // File address of new exe header
+} EFI_IMAGE_DOS_HEADER;
+
+///
+/// File header format.
+///
+typedef struct {
+  UINT16  Machine;
+  UINT16  NumberOfSections;
+  UINT32  TimeDateStamp;
+  UINT32  PointerToSymbolTable;
+  UINT32  NumberOfSymbols;
+  UINT16  SizeOfOptionalHeader;
+  UINT16  Characteristics;
+} EFI_IMAGE_FILE_HEADER;
+
+#define EFI_IMAGE_SIZEOF_FILE_HEADER        20
+
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED      0x0001  // Relocation info stripped from file.
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE     0x0002  // File is executable  (i.e. no unresolved externel references).
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED   0x0004  // Line nunbers stripped from file.
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED  0x0008  // Local symbols stripped from file.
+#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE  0x0020  // Supports addresses > 2-GB
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO    0x0080  // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_32BIT_MACHINE        0x0100  // 32 bit word machine.
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED       0x0200  // Debugging info stripped from file in .DBG file
+#define EFI_IMAGE_FILE_SYSTEM               0x1000  // System File.
+#define EFI_IMAGE_FILE_DLL                  0x2000  // File is a DLL.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI    0x8000  // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN      0
+#define EFI_IMAGE_FILE_MACHINE_I386         0x14c   // Intel 386.
+#define EFI_IMAGE_FILE_MACHINE_R3000        0x162   // MIPS* little-endian, 0540 big-endian
+#define EFI_IMAGE_FILE_MACHINE_R4000        0x166   // MIPS* little-endian
+#define EFI_IMAGE_FILE_MACHINE_ALPHA        0x184   // Alpha_AXP*
+#define EFI_IMAGE_FILE_MACHINE_POWERPC      0x1F0   // IBM* PowerPC Little-Endian
+#define EFI_IMAGE_FILE_MACHINE_TAHOE        0x7cc   // Intel EM machine
+//
+// * Other names and brands may be claimed as the property of others.
+//
+
+///
+/// Directory format.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  Size;
+} EFI_IMAGE_DATA_DIRECTORY;
+
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+
+typedef struct {
+  UINT16  Magic;
+  UINT8   MajorLinkerVersion;
+  UINT8   MinorLinkerVersion;
+  UINT32  SizeOfCode;
+  UINT32  SizeOfInitializedData;
+  UINT32  SizeOfUninitializedData;
+  UINT32  AddressOfEntryPoint;
+  UINT32  BaseOfCode;
+  UINT32  BaseOfData;
+  UINT32  BaseOfBss;
+  UINT32  GprMask;
+  UINT32  CprMask[4];
+  UINT32  GpValue;
+} EFI_IMAGE_ROM_OPTIONAL_HEADER;
+
+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC      0x107
+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER  sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)
+
+typedef struct {
+  EFI_IMAGE_FILE_HEADER         FileHeader;
+  EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} EFI_IMAGE_ROM_HEADERS;
+
+///
+/// @attention
+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+/// are for use ONLY by tools.  All proper EFI code MUST use
+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+
+typedef struct {
+  //
+  // Standard fields.
+  //
+  UINT16                    Magic;
+  UINT8                     MajorLinkerVersion;
+  UINT8                     MinorLinkerVersion;
+  UINT32                    SizeOfCode;
+  UINT32                    SizeOfInitializedData;
+  UINT32                    SizeOfUninitializedData;
+  UINT32                    AddressOfEntryPoint;
+  UINT32                    BaseOfCode;
+  UINT32                    BaseOfData;
+  //
+  // NT additional fields.
+  //
+  UINT32                    ImageBase;
+  UINT32                    SectionAlignment;
+  UINT32                    FileAlignment;
+  UINT16                    MajorOperatingSystemVersion;
+  UINT16                    MinorOperatingSystemVersion;
+  UINT16                    MajorImageVersion;
+  UINT16                    MinorImageVersion;
+  UINT16                    MajorSubsystemVersion;
+  UINT16                    MinorSubsystemVersion;
+  UINT32                    Win32VersionValue;
+  UINT32                    SizeOfImage;
+  UINT32                    SizeOfHeaders;
+  UINT32                    CheckSum;
+  UINT16                    Subsystem;
+  UINT16                    DllCharacteristics;
+  UINT32                    SizeOfStackReserve;
+  UINT32                    SizeOfStackCommit;
+  UINT32                    SizeOfHeapReserve;
+  UINT32                    SizeOfHeapCommit;
+  UINT32                    LoaderFlags;
+  UINT32                    NumberOfRvaAndSizes;
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER32;
+
+///
+/// @attention
+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+/// are for use ONLY by tools.  All proper EFI code MUST use
+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+
+typedef struct {
+  //
+  // Standard fields.
+  //
+  UINT16                    Magic;
+  UINT8                     MajorLinkerVersion;
+  UINT8                     MinorLinkerVersion;
+  UINT32                    SizeOfCode;
+  UINT32                    SizeOfInitializedData;
+  UINT32                    SizeOfUninitializedData;
+  UINT32                    AddressOfEntryPoint;
+  UINT32                    BaseOfCode;
+  //
+  // NT additional fields.
+  //
+  UINT64                    ImageBase;
+  UINT32                    SectionAlignment;
+  UINT32                    FileAlignment;
+  UINT16                    MajorOperatingSystemVersion;
+  UINT16                    MinorOperatingSystemVersion;
+  UINT16                    MajorImageVersion;
+  UINT16                    MinorImageVersion;
+  UINT16                    MajorSubsystemVersion;
+  UINT16                    MinorSubsystemVersion;
+  UINT32                    Win32VersionValue;
+  UINT32                    SizeOfImage;
+  UINT32                    SizeOfHeaders;
+  UINT32                    CheckSum;
+  UINT16                    Subsystem;
+  UINT16                    DllCharacteristics;
+  UINT64                    SizeOfStackReserve;
+  UINT64                    SizeOfStackCommit;
+  UINT64                    SizeOfHeapReserve;
+  UINT64                    SizeOfHeapCommit;
+  UINT32                    LoaderFlags;
+  UINT32                    NumberOfRvaAndSizes;
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER64;
+
+///
+/// @attention
+/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY
+/// by tools.  All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!
+///
+typedef struct {
+  UINT32                      Signature;
+  EFI_IMAGE_FILE_HEADER       FileHeader;
+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS32;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
+
+typedef struct {
+  UINT32                      Signature;
+  EFI_IMAGE_FILE_HEADER       FileHeader;
+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS64;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
+
+//
+// Subsystem Values
+//
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN     0
+#define EFI_IMAGE_SUBSYSTEM_NATIVE      1
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI     5
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI   7
+
+//
+// Directory Entries
+//
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT      0
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT      1
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE    2
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION   3
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY    4
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC   5
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG       6
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT   7
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR   8
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS         9
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+
+//
+// Section header format.
+//
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct {
+  UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
+  union {
+    UINT32  PhysicalAddress;
+    UINT32  VirtualSize;
+  } Misc;
+  UINT32  VirtualAddress;
+  UINT32  SizeOfRawData;
+  UINT32  PointerToRawData;
+  UINT32  PointerToRelocations;
+  UINT32  PointerToLinenumbers;
+  UINT16  NumberOfRelocations;
+  UINT16  NumberOfLinenumbers;
+  UINT32  Characteristics;
+} EFI_IMAGE_SECTION_HEADER;
+
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER       40
+
+#define EFI_IMAGE_SCN_TYPE_NO_PAD             0x00000008  // Reserved.
+#define EFI_IMAGE_SCN_CNT_CODE                0x00000020
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080
+
+#define EFI_IMAGE_SCN_LNK_OTHER               0x00000100  // Reserved.
+#define EFI_IMAGE_SCN_LNK_INFO                0x00000200  // Section contains comments or some other type of information.
+#define EFI_IMAGE_SCN_LNK_REMOVE              0x00000800  // Section contents will not become part of image.
+#define EFI_IMAGE_SCN_LNK_COMDAT              0x00001000
+
+#define EFI_IMAGE_SCN_ALIGN_1BYTES            0x00100000
+#define EFI_IMAGE_SCN_ALIGN_2BYTES            0x00200000
+#define EFI_IMAGE_SCN_ALIGN_4BYTES            0x00300000
+#define EFI_IMAGE_SCN_ALIGN_8BYTES            0x00400000
+#define EFI_IMAGE_SCN_ALIGN_16BYTES           0x00500000
+#define EFI_IMAGE_SCN_ALIGN_32BYTES           0x00600000
+#define EFI_IMAGE_SCN_ALIGN_64BYTES           0x00700000
+
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE         0x02000000
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED          0x04000000
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED           0x08000000
+#define EFI_IMAGE_SCN_MEM_SHARED              0x10000000
+#define EFI_IMAGE_SCN_MEM_EXECUTE             0x20000000
+#define EFI_IMAGE_SCN_MEM_READ                0x40000000
+#define EFI_IMAGE_SCN_MEM_WRITE               0x80000000
+
+///
+/// Symbol format.
+///
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0  // Symbol is undefined or is common.
+#define EFI_IMAGE_SYM_ABSOLUTE  (UINT16) -1 // Symbol is an absolute value.
+#define EFI_IMAGE_SYM_DEBUG     (UINT16) -2 // Symbol is a special debug item.
+//
+// Type (fundamental) values.
+//
+#define EFI_IMAGE_SYM_TYPE_NULL   0   // no type.
+#define EFI_IMAGE_SYM_TYPE_VOID   1   //
+#define EFI_IMAGE_SYM_TYPE_CHAR   2   // type character.
+#define EFI_IMAGE_SYM_TYPE_SHORT  3   // type short integer.
+#define EFI_IMAGE_SYM_TYPE_INT    4
+#define EFI_IMAGE_SYM_TYPE_LONG   5
+#define EFI_IMAGE_SYM_TYPE_FLOAT  6
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
+#define EFI_IMAGE_SYM_TYPE_UNION  9
+#define EFI_IMAGE_SYM_TYPE_ENUM   10  // enumeration.
+#define EFI_IMAGE_SYM_TYPE_MOE    11  // member of enumeration.
+#define EFI_IMAGE_SYM_TYPE_BYTE   12
+#define EFI_IMAGE_SYM_TYPE_WORD   13
+#define EFI_IMAGE_SYM_TYPE_UINT   14
+#define EFI_IMAGE_SYM_TYPE_DWORD  15
+
+//
+// Type (derived) values.
+//
+#define EFI_IMAGE_SYM_DTYPE_NULL      0 // no derived type.
+#define EFI_IMAGE_SYM_DTYPE_POINTER   1
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION  2
+#define EFI_IMAGE_SYM_DTYPE_ARRAY     3
+
+//
+// Storage classes.
+//
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION   (UINT8) -1
+#define EFI_IMAGE_SYM_CLASS_NULL              0
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC         1
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL          2
+#define EFI_IMAGE_SYM_CLASS_STATIC            3
+#define EFI_IMAGE_SYM_CLASS_REGISTER          4
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF      5
+#define EFI_IMAGE_SYM_CLASS_LABEL             6
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL   7
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT  8
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT          9
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG        10
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION   11
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG         12
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION   13
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC  14
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG          15
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM    16
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM    17
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD         18
+#define EFI_IMAGE_SYM_CLASS_BLOCK             100
+#define EFI_IMAGE_SYM_CLASS_FUNCTION          101
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT     102
+#define EFI_IMAGE_SYM_CLASS_FILE              103
+#define EFI_IMAGE_SYM_CLASS_SECTION           104
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL     105
+
+//
+// type packing constants
+//
+#define EFI_IMAGE_N_BTMASK  017
+#define EFI_IMAGE_N_TMASK   060
+#define EFI_IMAGE_N_TMASK1  0300
+#define EFI_IMAGE_N_TMASK2  0360
+#define EFI_IMAGE_N_BTSHFT  4
+#define EFI_IMAGE_N_TSHIFT  2
+
+//
+// Communal selection types.
+//
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES    1
+#define EFI_IMAGE_COMDAT_SELECT_ANY             2
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE       3
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH     4
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE     5
+
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3
+
+///
+/// Relocation format.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  SymbolTableIndex;
+  UINT16  Type;
+} EFI_IMAGE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0   // Reference is absolute, no relocation is necessary
+#define EFI_IMAGE_REL_I386_DIR16    01  // Direct 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_REL16    02  // PC-relative 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32    06  // Direct 32-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32NB  07  // Direct 32-bit reference to the symbols virtual address, base not included
+#define EFI_IMAGE_REL_I386_SEG12    09  // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define EFI_IMAGE_REL_I386_SECTION  010
+#define EFI_IMAGE_REL_I386_SECREL   011
+#define EFI_IMAGE_REL_I386_REL32    020 // PC-relative 32-bit reference to the symbols virtual address
+
+//
+// x64 processor relocation types.
+//
+#define IMAGE_REL_AMD64_ABSOLUTE	0x0000
+#define IMAGE_REL_AMD64_ADDR64	  0x0001
+#define IMAGE_REL_AMD64_ADDR32	  0x0002
+#define IMAGE_REL_AMD64_ADDR32NB	0x0003
+#define IMAGE_REL_AMD64_REL32	    0x0004
+#define IMAGE_REL_AMD64_REL32_1	  0x0005
+#define IMAGE_REL_AMD64_REL32_2	  0x0006
+#define IMAGE_REL_AMD64_REL32_3	  0x0007
+#define IMAGE_REL_AMD64_REL32_4	  0x0008
+#define IMAGE_REL_AMD64_REL32_5	  0x0009
+#define IMAGE_REL_AMD64_SECTION	  0x000A
+#define IMAGE_REL_AMD64_SECREL	  0x000B
+#define IMAGE_REL_AMD64_SECREL7	  0x000C
+#define IMAGE_REL_AMD64_TOKEN	    0x000D
+#define IMAGE_REL_AMD64_SREL32	  0x000E
+#define IMAGE_REL_AMD64_PAIR	    0x000F
+#define IMAGE_REL_AMD64_SSPAN32	  0x0010
+
+///
+/// Based relocation format.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  SizeOfBlock;
+} EFI_IMAGE_BASE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION  8
+
+//
+// Based relocation types.
+//
+#define EFI_IMAGE_REL_BASED_ABSOLUTE      0
+#define EFI_IMAGE_REL_BASED_HIGH          1
+#define EFI_IMAGE_REL_BASED_LOW           2
+#define EFI_IMAGE_REL_BASED_HIGHLOW       3
+#define EFI_IMAGE_REL_BASED_HIGHADJ       4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR  5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A    5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T    7
+#define EFI_IMAGE_REL_BASED_IA64_IMM64    9
+#define EFI_IMAGE_REL_BASED_DIR64         10
+
+
+///
+/// Line number format.
+///
+typedef struct {
+  union {
+    UINT32  SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+    UINT32  VirtualAddress;   // Virtual address of line number.
+  } Type;
+  UINT16  Linenumber;         // Line number.
+} EFI_IMAGE_LINENUMBER;
+
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+#define EFI_IMAGE_ARCHIVE_START_SIZE        8
+#define EFI_IMAGE_ARCHIVE_START             "!<arch>\n"
+#define EFI_IMAGE_ARCHIVE_END               "`\n"
+#define EFI_IMAGE_ARCHIVE_PAD               "\n"
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER     "/               "
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER  "//              "
+
+typedef struct {
+  UINT8 Name[16];     // File member name - `/' terminated.
+  UINT8 Date[12];     // File member date - decimal.
+  UINT8 UserID[6];    // File member user id - decimal.
+  UINT8 GroupID[6];   // File member group id - decimal.
+  UINT8 Mode[8];      // File member mode - octal.
+  UINT8 Size[10];     // File member size - decimal.
+  UINT8 EndHeader[2]; // String to end header.
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+
+///
+/// DLL Export Format
+///
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT32  Name;
+  UINT32  Base;
+  UINT32  NumberOfFunctions;
+  UINT32  NumberOfNames;
+  UINT32  AddressOfFunctions;
+  UINT32  AddressOfNames;
+  UINT32  AddressOfNameOrdinals;
+} EFI_IMAGE_EXPORT_DIRECTORY;
+
+///
+/// DLL support.
+/// Import Format
+///
+typedef struct {
+  UINT16  Hint;
+  UINT8   Name[1];
+} EFI_IMAGE_IMPORT_BY_NAME;
+
+typedef struct {
+  union {
+    UINT32                    Function;
+    UINT32                    Ordinal;
+    EFI_IMAGE_IMPORT_BY_NAME  *AddressOfData;
+  } u1;
+} EFI_IMAGE_THUNK_DATA;
+
+#define EFI_IMAGE_ORDINAL_FLAG              0x80000000
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal)  ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
+#define EFI_IMAGE_ORDINAL(Ordinal)          (Ordinal & 0xffff)
+
+typedef struct {
+  UINT32                Characteristics;
+  UINT32                TimeDateStamp;
+  UINT32                ForwarderChain;
+  UINT32                Name;
+  EFI_IMAGE_THUNK_DATA  *FirstThunk;
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
+
+///
+/// Debug Format
+///
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
+
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT32  Type;
+  UINT32  SizeOfData;
+  UINT32  RVA;
+  UINT32  FileOffset;
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define CODEVIEW_SIGNATURE_NB10 0x3031424E  // "NB10"
+typedef struct {
+  UINT32  Signature;                        // "NB10"
+  UINT32  Unknown;
+  UINT32  Unknown2;
+  UINT32  Unknown3;
+  //
+  // Filename of .PDB goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+#define CODEVIEW_SIGNATURE_RSDS 0x53445352  // "RSDS"
+typedef struct {
+  UINT32  Signature;                        // "RSDS"
+  UINT32  Unknown;
+  UINT32  Unknown2;
+  UINT32  Unknown3;
+  UINT32  Unknown4;
+  UINT32  Unknown5;
+  //
+  // Filename of .PDB goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+///
+/// Debug Data Structure defined by Apple Mach-O to Coff utility
+///
+#define CODEVIEW_SIGNATURE_MTOC  SIGNATURE_32('M', 'T', 'O', 'C')
+typedef struct {
+  UINT32    Signature;                       ///< "MTOC"
+  EFI_GUID  MachOUuid;
+  //
+  //  Filename of .DLL (Mach-O with debug info) goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
+
+//
+// .pdata entries for X64
+//
+typedef struct {
+  UINT32  FunctionStartAddress;
+  UINT32  FunctionEndAddress;
+  UINT32  UnwindInfoAddress;
+} RUNTIME_FUNCTION;
+
+typedef struct {
+  UINT8  Version:3;
+  UINT8  Flags:5;
+  UINT8  SizeOfProlog;
+  UINT8  CountOfUnwindCodes;
+  UINT8  FrameRegister:4;
+  UINT8  FrameRegisterOffset:4;
+} UNWIND_INFO;
+
+///
+/// Resource format.
+///
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT16  NumberOfNamedEntries;
+  UINT16  NumberOfIdEntries;
+  //
+  // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here.
+  //
+} EFI_IMAGE_RESOURCE_DIRECTORY;
+
+///
+/// Resource directory entry format.
+///
+typedef struct {
+  union {
+    struct {
+      UINT32  NameOffset:31;
+      UINT32  NameIsString:1;
+    } s;
+    UINT32  Id;
+  } u1;
+  union {
+    UINT32  OffsetToData;
+    struct {
+      UINT32  OffsetToDirectory:31;
+      UINT32  DataIsDirectory:1;
+    } s;
+  } u2;
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+///
+/// Resource directory entry for string.
+///
+typedef struct {
+  UINT16  Length;
+  CHAR16  String[1];
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
+
+///
+/// Resource directory entry for data array.
+///
+typedef struct {
+  UINT32  OffsetToData;
+  UINT32  Size;
+  UINT32  CodePage;
+  UINT32  Reserved;
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;
+
+///
+/// Header format for TE images
+///
+typedef struct {
+  UINT16                    Signature;            // signature for TE format = "VZ"
+  UINT16                    Machine;              // from the original file header
+  UINT8                     NumberOfSections;     // from the original file header
+  UINT8                     Subsystem;            // from original optional header
+  UINT16                    StrippedSize;         // how many bytes we removed from the header
+  UINT32                    AddressOfEntryPoint;  // offset to entry point -- from original optional header
+  UINT32                    BaseOfCode;           // from original image -- required for ITP debug
+  UINT64                    ImageBase;            // from original file header
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[2];     // only base relocation and debug directory
+} EFI_TE_IMAGE_HEADER;
+
+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56      // "VZ"
+
+//
+// Data directory indexes in our TE image header
+//
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC  0
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG      1
+
+
+//
+// Union of PE32, PE32+, and TE headers
+//
+typedef union {
+  EFI_IMAGE_NT_HEADERS32   Pe32;
+  EFI_IMAGE_NT_HEADERS64   Pe32Plus;
+  EFI_TE_IMAGE_HEADER      Te;
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
+
+typedef union {
+  EFI_IMAGE_NT_HEADERS32            *Pe32;
+  EFI_IMAGE_NT_HEADERS64            *Pe32Plus;
+  EFI_TE_IMAGE_HEADER               *Te;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION   *Union;
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
+
+#endif
diff --git a/EfiRom/Include/IndustryStandard/pci22.h b/EfiRom/Include/IndustryStandard/pci22.h
new file mode 100644
index 0000000..dce7cc0
--- /dev/null
+++ b/EfiRom/Include/IndustryStandard/pci22.h
@@ -0,0 +1,542 @@
+/** @file
+  Support for PCI 2.2 standard.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI22_H
+#define _PCI22_H
+
+#define PCI_MAX_SEGMENT 0
+
+#define PCI_MAX_BUS     255
+
+#define PCI_MAX_DEVICE  31
+#define PCI_MAX_FUNC    7
+
+//
+// Command
+//
+#define PCI_VGA_PALETTE_SNOOP_DISABLED  0x20
+
+#pragma pack(push, 1)
+typedef struct {
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  Command;
+  UINT16  Status;
+  UINT8   RevisionID;
+  UINT8   ClassCode[3];
+  UINT8   CacheLineSize;
+  UINT8   LatencyTimer;
+  UINT8   HeaderType;
+  UINT8   BIST;
+} PCI_DEVICE_INDEPENDENT_REGION;
+
+typedef struct {
+  UINT32  Bar[6];
+  UINT32  CISPtr;
+  UINT16  SubsystemVendorID;
+  UINT16  SubsystemID;
+  UINT32  ExpansionRomBar;
+  UINT8   CapabilityPtr;
+  UINT8   Reserved1[3];
+  UINT32  Reserved2;
+  UINT8   InterruptLine;
+  UINT8   InterruptPin;
+  UINT8   MinGnt;
+  UINT8   MaxLat;
+} PCI_DEVICE_HEADER_TYPE_REGION;
+
+typedef struct {
+  PCI_DEVICE_INDEPENDENT_REGION Hdr;
+  PCI_DEVICE_HEADER_TYPE_REGION Device;
+} PCI_TYPE00;
+
+typedef struct {
+  UINT32  Bar[2];
+  UINT8   PrimaryBus;
+  UINT8   SecondaryBus;
+  UINT8   SubordinateBus;
+  UINT8   SecondaryLatencyTimer;
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  SecondaryStatus;
+  UINT16  MemoryBase;
+  UINT16  MemoryLimit;
+  UINT16  PrefetchableMemoryBase;
+  UINT16  PrefetchableMemoryLimit;
+  UINT32  PrefetchableBaseUpper32;
+  UINT32  PrefetchableLimitUpper32;
+  UINT16  IoBaseUpper16;
+  UINT16  IoLimitUpper16;
+  UINT8   CapabilityPtr;
+  UINT8   Reserved[3];
+  UINT32  ExpansionRomBAR;
+  UINT8   InterruptLine;
+  UINT8   InterruptPin;
+  UINT16  BridgeControl;
+} PCI_BRIDGE_CONTROL_REGISTER;
+
+typedef struct {
+  PCI_DEVICE_INDEPENDENT_REGION Hdr;
+  PCI_BRIDGE_CONTROL_REGISTER   Bridge;
+} PCI_TYPE01;
+
+typedef union {
+  PCI_TYPE00  Device;
+  PCI_TYPE01  Bridge;
+} PCI_TYPE_GENERIC;
+
+typedef struct {
+  UINT32  CardBusSocketReg; // Cardus Socket/ExCA Base
+  // Address Register
+  //
+  UINT16  Reserved;
+  UINT16  SecondaryStatus;      // Secondary Status
+  UINT8   PciBusNumber;         // PCI Bus Number
+  UINT8   CardBusBusNumber;     // CardBus Bus Number
+  UINT8   SubordinateBusNumber; // Subordinate Bus Number
+  UINT8   CardBusLatencyTimer;  // CardBus Latency Timer
+  UINT32  MemoryBase0;          // Memory Base Register 0
+  UINT32  MemoryLimit0;         // Memory Limit Register 0
+  UINT32  MemoryBase1;
+  UINT32  MemoryLimit1;
+  UINT32  IoBase0;
+  UINT32  IoLimit0;             // I/O Base Register 0
+  UINT32  IoBase1;              // I/O Limit Register 0
+  UINT32  IoLimit1;
+  UINT8   InterruptLine;        // Interrupt Line
+  UINT8   InterruptPin;         // Interrupt Pin
+  UINT16  BridgeControl;        // Bridge Control
+} PCI_CARDBUS_CONTROL_REGISTER;
+
+//
+// Definitions of PCI class bytes and manipulation macros.
+//
+#define PCI_CLASS_OLD                 0x00
+#define PCI_CLASS_OLD_OTHER           0x00
+#define PCI_CLASS_OLD_VGA             0x01
+
+#define PCI_CLASS_MASS_STORAGE        0x01
+#define PCI_CLASS_MASS_STORAGE_SCSI   0x00
+#define PCI_CLASS_MASS_STORAGE_IDE    0x01  // obsolete
+#define PCI_CLASS_IDE                 0x01
+#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02
+#define PCI_CLASS_MASS_STORAGE_IPI    0x03
+#define PCI_CLASS_MASS_STORAGE_RAID   0x04
+#define PCI_CLASS_MASS_STORAGE_OTHER  0x80
+
+#define PCI_CLASS_NETWORK             0x02
+#define PCI_CLASS_NETWORK_ETHERNET    0x00
+#define PCI_CLASS_ETHERNET            0x00  // obsolete
+#define PCI_CLASS_NETWORK_TOKENRING   0x01
+#define PCI_CLASS_NETWORK_FDDI        0x02
+#define PCI_CLASS_NETWORK_ATM         0x03
+#define PCI_CLASS_NETWORK_ISDN        0x04
+#define PCI_CLASS_NETWORK_OTHER       0x80
+
+#define PCI_CLASS_DISPLAY             0x03
+#define PCI_CLASS_DISPLAY_CTRL        0x03  // obsolete
+#define PCI_CLASS_DISPLAY_VGA         0x00
+#define PCI_CLASS_VGA                 0x00  // obsolete
+#define PCI_CLASS_DISPLAY_XGA         0x01
+#define PCI_CLASS_DISPLAY_3D          0x02
+#define PCI_CLASS_DISPLAY_OTHER       0x80
+#define PCI_CLASS_DISPLAY_GFX         0x80
+#define PCI_CLASS_GFX                 0x80  // obsolete
+#define PCI_CLASS_BRIDGE              0x06
+#define PCI_CLASS_BRIDGE_HOST         0x00
+#define PCI_CLASS_BRIDGE_ISA          0x01
+#define PCI_CLASS_ISA                 0x01  // obsolete
+#define PCI_CLASS_BRIDGE_EISA         0x02
+#define PCI_CLASS_BRIDGE_MCA          0x03
+#define PCI_CLASS_BRIDGE_P2P          0x04
+#define PCI_CLASS_BRIDGE_PCMCIA       0x05
+#define PCI_CLASS_BRIDGE_NUBUS        0x06
+#define PCI_CLASS_BRIDGE_CARDBUS      0x07
+#define PCI_CLASS_BRIDGE_RACEWAY      0x08
+#define PCI_CLASS_BRIDGE_ISA_PDECODE  0x80
+#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80  // obsolete
+
+#define PCI_CLASS_SCC                 0x07  // Simple communications controllers 
+#define PCI_SUBCLASS_SERIAL           0x00
+#define PCI_IF_GENERIC_XT             0x00
+#define PCI_IF_16450                  0x01
+#define PCI_IF_16550                  0x02
+#define PCI_IF_16650                  0x03
+#define PCI_IF_16750                  0x04
+#define PCI_IF_16850                  0x05
+#define PCI_IF_16950                  0x06
+#define PCI_SUBCLASS_PARALLEL         0x01
+#define PCI_IF_PARALLEL_PORT          0x00
+#define PCI_IF_BI_DIR_PARALLEL_PORT   0x01
+#define PCI_IF_ECP_PARALLEL_PORT      0x02
+#define PCI_IF_1284_CONTROLLER        0x03
+#define PCI_IF_1284_DEVICE            0xFE
+#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02
+#define PCI_SUBCLASS_MODEM            0x03
+#define PCI_IF_GENERIC_MODEM          0x00
+#define PCI_IF_16450_MODEM            0x01
+#define PCI_IF_16550_MODEM            0x02
+#define PCI_IF_16650_MODEM            0x03
+#define PCI_IF_16750_MODEM            0x04
+#define PCI_SUBCLASS_OTHER            0x80
+
+#define PCI_CLASS_SYSTEM_PERIPHERAL   0x08
+#define PCI_SUBCLASS_PIC              0x00
+#define PCI_IF_8259_PIC               0x00
+#define PCI_IF_ISA_PIC                0x01
+#define PCI_IF_EISA_PIC               0x02
+#define PCI_IF_APIC_CONTROLLER        0x10 // I/O APIC interrupt controller , 32 bye none-prefectable memory.  
+#define PCI_IF_APIC_CONTROLLER2       0x20 
+#define PCI_SUBCLASS_TIMER            0x02
+#define PCI_IF_8254_TIMER             0x00
+#define PCI_IF_ISA_TIMER              0x01
+#define PCI_EISA_TIMER                0x02
+#define PCI_SUBCLASS_RTC              0x03
+#define PCI_IF_GENERIC_RTC            0x00
+#define PCI_IF_ISA_RTC                0x00
+#define PCI_SUBCLASS_PNP_CONTROLLER   0x04 // HotPlug Controller
+
+#define PCI_CLASS_INPUT_DEVICE        0x09
+#define PCI_SUBCLASS_KEYBOARD         0x00
+#define PCI_SUBCLASS_PEN              0x01
+#define PCI_SUBCLASS_MOUSE_CONTROLLER 0x02
+#define PCI_SUBCLASS_SCAN_CONTROLLER  0x03
+#define PCI_SUBCLASS_GAMEPORT         0x04
+
+#define PCI_CLASS_DOCKING_STATION     0x0A
+
+#define PCI_CLASS_PROCESSOR           0x0B
+#define PCI_SUBCLASS_PROC_386         0x00
+#define PCI_SUBCLASS_PROC_486         0x01
+#define PCI_SUBCLASS_PROC_PENTIUM     0x02
+#define PCI_SUBCLASS_PROC_ALPHA       0x10
+#define PCI_SUBCLASS_PROC_POWERPC     0x20
+#define PCI_SUBCLASS_PROC_MIPS        0x30
+#define PCI_SUBCLASS_PROC_CO_PORC     0x40 // Co-Processor
+
+#define PCI_CLASS_SERIAL              0x0C
+#define PCI_CLASS_SERIAL_FIREWIRE     0x00
+#define PCI_CLASS_SERIAL_ACCESS_BUS   0x01
+#define PCI_CLASS_SERIAL_SSA          0x02
+#define PCI_CLASS_SERIAL_USB          0x03
+#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04
+#define PCI_CLASS_SERIAL_SMB          0x05
+
+#define PCI_CLASS_WIRELESS            0x0D
+#define PCI_SUBCLASS_IRDA             0x00
+#define PCI_SUBCLASS_IR               0x01
+#define PCI_SUBCLASS_RF               0x02
+
+#define PCI_CLASS_INTELLIGENT_IO      0x0E
+
+#define PCI_CLASS_SATELLITE           0x0F
+#define PCI_SUBCLASS_TV               0x01
+#define PCI_SUBCLASS_AUDIO            0x02
+#define PCI_SUBCLASS_VOICE            0x03
+#define PCI_SUBCLASS_DATA             0x04
+
+#define PCI_SECURITY_CONTROLLER       0x10 // Encryption and decryption controller
+#define PCI_SUBCLASS_NET_COMPUT       0x00
+#define PCI_SUBCLASS_ENTERTAINMENT    0x10 
+
+#define PCI_CLASS_DPIO                0x11
+
+#define IS_CLASS1(_p, c)              ((_p)->Hdr.ClassCode[2] == (c))
+#define IS_CLASS2(_p, c, s)           (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))
+#define IS_CLASS3(_p, c, s, p)        (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))
+
+#define IS_PCI_DISPLAY(_p)            IS_CLASS1 (_p, PCI_CLASS_DISPLAY)
+#define IS_PCI_VGA(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0)
+#define IS_PCI_8514(_p)               IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1)
+#define IS_PCI_GFX(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0)
+#define IS_PCI_OLD(_p)                IS_CLASS1 (_p, PCI_CLASS_OLD)
+#define IS_PCI_OLD_VGA(_p)            IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA)
+#define IS_PCI_IDE(_p)                IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)
+#define IS_PCI_SCSI(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0)
+#define IS_PCI_RAID(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0)
+#define IS_PCI_LPC(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0)
+#define IS_PCI_P2P(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0)
+#define IS_PCI_P2P_SUB(_p)            IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1)
+#define IS_PCI_USB(_p)                IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB)
+
+#define HEADER_TYPE_DEVICE            0x00
+#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
+#define HEADER_TYPE_CARDBUS_BRIDGE    0x02
+
+#define HEADER_TYPE_MULTI_FUNCTION    0x80
+#define HEADER_LAYOUT_CODE            0x7f
+
+#define IS_PCI_BRIDGE(_p)             (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE))
+#define IS_CARDBUS_BRIDGE(_p)         (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE))
+#define IS_PCI_MULTI_FUNC(_p)         ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)
+
+#define PCI_DEVICE_ROMBAR             0x30
+#define PCI_BRIDGE_ROMBAR             0x38
+
+#define PCI_MAX_BAR                   0x0006
+#define PCI_MAX_CONFIG_OFFSET         0x0100
+
+#define PCI_VENDOR_ID_OFFSET                        0x00
+#define PCI_DEVICE_ID_OFFSET                        0x02
+#define PCI_COMMAND_OFFSET                          0x04
+#define PCI_PRIMARY_STATUS_OFFSET                   0x06
+#define PCI_REVISION_ID_OFFSET                      0x08
+#define PCI_CLASSCODE_OFFSET                        0x09
+#define PCI_CACHELINE_SIZE_OFFSET                   0x0C
+#define PCI_LATENCY_TIMER_OFFSET                    0x0D
+#define PCI_HEADER_TYPE_OFFSET                      0x0E
+#define PCI_BIST_OFFSET                             0x0F
+#define PCI_BASE_ADDRESSREG_OFFSET                  0x10
+#define PCI_CARDBUS_CIS_OFFSET                      0x28
+#define PCI_SVID_OFFSET                             0x2C // SubSystem Vendor id
+#define PCI_SUBSYSTEM_VENDOR_ID_OFFSET              0x2C
+#define PCI_SID_OFFSET                              0x2E // SubSystem ID
+#define PCI_SUBSYSTEM_ID_OFFSET                     0x2E
+#define PCI_EXPANSION_ROM_BASE                      0x30
+#define PCI_CAPBILITY_POINTER_OFFSET                0x34
+#define PCI_INT_LINE_OFFSET                         0x3C // Interrupt Line Register
+#define PCI_INT_PIN_OFFSET                          0x3D // Interrupt Pin Register
+#define PCI_MAXGNT_OFFSET                           0x3E // Max Grant Register
+#define PCI_MAXLAT_OFFSET                           0x3F // Max Latency Register
+
+#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET          0x3E
+#define PCI_BRIDGE_STATUS_REGISTER_OFFSET           0x1E
+
+#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET      0x18
+#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET    0x19
+#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET  0x1a
+
+typedef union {
+  struct {
+    UINT32  Reg : 8;
+    UINT32  Func : 3;
+    UINT32  Dev : 5;
+    UINT32  Bus : 8;
+    UINT32  Reserved : 7;
+    UINT32  Enable : 1;
+  } Bits;
+  UINT32  Uint32;
+} PCI_CONFIG_ACCESS_CF8;
+
+#pragma pack()
+
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE              0xaa55
+#define PCI_DATA_STRUCTURE_SIGNATURE                    SIGNATURE_32 ('P', 'C', 'I', 'R')
+#define PCI_CODE_TYPE_PCAT_IMAGE                        0x00
+#define PCI_CODE_TYPE_EFI_IMAGE                         0x03
+#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED         0x0001
+
+#define EFI_PCI_COMMAND_IO_SPACE                        0x0001
+#define EFI_PCI_COMMAND_MEMORY_SPACE                    0x0002
+#define EFI_PCI_COMMAND_BUS_MASTER                      0x0004
+#define EFI_PCI_COMMAND_SPECIAL_CYCLE                   0x0008
+#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE     0x0010
+#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP               0x0020
+#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND            0x0040
+#define EFI_PCI_COMMAND_STEPPING_CONTROL                0x0080
+#define EFI_PCI_COMMAND_SERR                            0x0100
+#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK               0x0200
+
+#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE    0x0001
+#define EFI_PCI_BRIDGE_CONTROL_SERR                     0x0002
+#define EFI_PCI_BRIDGE_CONTROL_ISA                      0x0004
+#define EFI_PCI_BRIDGE_CONTROL_VGA                      0x0008
+#define EFI_PCI_BRIDGE_CONTROL_VGA_16                   0x0010
+#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT             0x0020
+#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS      0x0040
+#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK        0x0080
+#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER    0x0100
+#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER  0x0200
+#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS             0x0400
+#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR       0x0800
+
+//
+// Following are the PCI-CARDBUS bridge control bit
+//
+#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE       0x0080
+#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE   0x0100
+#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE   0x0200
+#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400
+
+//
+// Following are the PCI status control bit
+//
+#define EFI_PCI_STATUS_CAPABILITY             0x0010
+#define EFI_PCI_STATUS_66MZ_CAPABLE           0x0020
+#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE     0x0080
+#define EFI_PCI_MASTER_DATA_PARITY_ERROR      0x0100
+
+#define EFI_PCI_CAPABILITY_PTR                0x34
+#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14
+
+#pragma pack(1)
+typedef struct {
+  UINT16  Signature;    // 0xaa55
+  UINT8   Reserved[0x16];
+  UINT16  PcirOffset;
+} PCI_EXPANSION_ROM_HEADER;
+
+typedef struct {
+  UINT16  Signature;    // 0xaa55
+  UINT8   Size512;
+  UINT8   InitEntryPoint[3];
+  UINT8   Reserved[0x12];
+  UINT16  PcirOffset;
+} EFI_LEGACY_EXPANSION_ROM_HEADER;
+
+typedef struct {
+  UINT32  Signature;    // "PCIR"
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  Reserved0;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  Reserved1;
+} PCI_DATA_STRUCTURE;
+
+//
+// PCI Capability List IDs and records
+//
+#define EFI_PCI_CAPABILITY_ID_PMI     0x01
+#define EFI_PCI_CAPABILITY_ID_AGP     0x02
+#define EFI_PCI_CAPABILITY_ID_VPD     0x03
+#define EFI_PCI_CAPABILITY_ID_SLOTID  0x04
+#define EFI_PCI_CAPABILITY_ID_MSI     0x05
+#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06
+#define EFI_PCI_CAPABILITY_ID_PCIX    0x07
+
+typedef struct {
+  UINT8 CapabilityID;
+  UINT8 NextItemPtr;
+} EFI_PCI_CAPABILITY_HDR;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PMI
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  PMC;
+  UINT16                  PMCSR;
+  UINT8                   BridgeExtention;
+  UINT8                   Data;
+} EFI_PCI_CAPABILITY_PMI;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_AGP
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT8                   Rev;
+  UINT8                   Reserved;
+  UINT32                  Status;
+  UINT32                  Command;
+} EFI_PCI_CAPABILITY_AGP;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_VPD
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  AddrReg;
+  UINT32                  DataReg;
+} EFI_PCI_CAPABILITY_VPD;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_SLOTID
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT8                   ExpnsSlotReg;
+  UINT8                   ChassisNo;
+} EFI_PCI_CAPABILITY_SLOTID;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_MSI
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  MsgCtrlReg;
+  UINT32                  MsgAddrReg;
+  UINT16                  MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI32;
+
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  MsgCtrlReg;
+  UINT32                  MsgAddrRegLsdw;
+  UINT32                  MsgAddrRegMsdw;
+  UINT16                  MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI64;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  //
+  // not finished - fields need to go here
+  //
+} EFI_PCI_CAPABILITY_HOTPLUG;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PCIX
+//
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  CommandReg;
+  UINT32                  StatusReg;
+} EFI_PCI_CAPABILITY_PCIX;
+
+typedef struct {
+  EFI_PCI_CAPABILITY_HDR  Hdr;
+  UINT16                  SecStatusReg;
+  UINT32                  StatusReg;
+  UINT32                  SplitTransCtrlRegUp;
+  UINT32                  SplitTransCtrlRegDn;
+} EFI_PCI_CAPABILITY_PCIX_BRDG;
+
+#define DEVICE_ID_NOCARE    0xFFFF
+
+#define PCI_ACPI_UNUSED     0
+#define PCI_BAR_NOCHANGE    0
+#define PCI_BAR_OLD_ALIGN   0xFFFFFFFFFFFFFFFFULL
+#define PCI_BAR_EVEN_ALIGN  0xFFFFFFFFFFFFFFFEULL
+#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL
+#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL
+
+#define PCI_BAR_IDX0        0x00
+#define PCI_BAR_IDX1        0x01
+#define PCI_BAR_IDX2        0x02
+#define PCI_BAR_IDX3        0x03
+#define PCI_BAR_IDX4        0x04
+#define PCI_BAR_IDX5        0x05
+#define PCI_BAR_ALL         0xFF
+
+#pragma pack(pop)
+
+//
+// NOTE: The following header files are included here for
+// compatibility consideration.
+//
+#include "pci23.h"
+#include "pci30.h"
+#include "EfiPci.h"
+
+#endif
diff --git a/EfiRom/Include/IndustryStandard/pci23.h b/EfiRom/Include/IndustryStandard/pci23.h
new file mode 100644
index 0000000..629baa2
--- /dev/null
+++ b/EfiRom/Include/IndustryStandard/pci23.h
@@ -0,0 +1,24 @@
+/** @file
+  Support for PCI 2.3 standard.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI23_H
+#define _PCI23_H
+
+//#include "pci22.h"
+
+#define PCI_EXP_MAX_CONFIG_OFFSET     0x1000
+#define EFI_PCI_CAPABILITY_ID_PCIEXP  0x10
+
+#endif
diff --git a/EfiRom/Include/IndustryStandard/pci30.h b/EfiRom/Include/IndustryStandard/pci30.h
new file mode 100644
index 0000000..74c0fcf
--- /dev/null
+++ b/EfiRom/Include/IndustryStandard/pci30.h
@@ -0,0 +1,44 @@
+/** @file
+  Support for PCI 3.0 standard.
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI30_H
+#define _PCI30_H
+
+//#include "pci23.h"
+
+#define PCI_CLASS_MASS_STORAGE_SATADPA   0x06
+
+#pragma pack(push, 1)
+
+typedef struct {
+  UINT32  Signature;    // "PCIR"
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  DeviceListOffset;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  MaxRuntimeImageLength;
+  UINT16  ConfigUtilityCodeHeaderOffset;
+  UINT16  DMTFCLPEntryPointOffset;
+} PCI_3_0_DATA_STRUCTURE;
+
+#pragma pack(pop)
+
+#endif
diff --git a/EfiRom/Include/X64/ProcessorBind.h b/EfiRom/Include/X64/ProcessorBind.h
new file mode 100644
index 0000000..d3d0ef5
--- /dev/null
+++ b/EfiRom/Include/X64/ProcessorBind.h
@@ -0,0 +1,194 @@
+/** @file
+  Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64).
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+//
+// Define the processor type so other code can make processor based choices
+//
+#define MDE_CPU_X64
+
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+
+#if _MSC_EXTENSIONS 
+    
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
+//
+#pragma warning ( disable : 4127 )
+
+
+#endif
+
+
+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
+  //
+  // No ANSI C 2000 stdint.h integer width declarations, so define equivalents
+  //
+ 
+  #if _MSC_EXTENSIONS 
+    
+
+    //
+    // use Microsoft C complier dependent integer width types 
+    //
+    typedef unsigned __int64    UINT64;
+    typedef __int64             INT64;
+    typedef unsigned __int32    UINT32;
+    typedef __int32             INT32;
+    typedef unsigned short      UINT16;
+    typedef unsigned short      CHAR16;
+    typedef short               INT16;
+    typedef unsigned char       BOOLEAN;
+    typedef unsigned char       UINT8;
+    typedef char                CHAR8;
+    typedef char                INT8;
+  #else
+    #ifdef _EFI_P64 
+      //
+      // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints 
+      //  are 32-bits
+      //
+      typedef unsigned long long  UINT64;
+      typedef long long           INT64;
+      typedef unsigned int        UINT32;
+      typedef int                 INT32;
+      typedef unsigned short      CHAR16;
+      typedef unsigned short      UINT16;
+      typedef short               INT16;
+      typedef unsigned char       BOOLEAN;
+      typedef unsigned char       UINT8;
+      typedef char                CHAR8;
+      typedef char                INT8;
+    #else
+      //
+      // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit.
+      //
+      typedef unsigned long   UINT64;
+      typedef long            INT64;
+      typedef unsigned int    UINT32;
+      typedef int             INT32;
+      typedef unsigned short  UINT16;
+      typedef unsigned short  CHAR16;
+      typedef short           INT16;
+      typedef unsigned char   BOOLEAN;
+      typedef unsigned char   UINT8;
+      typedef char            CHAR8;
+      typedef char            INT8;
+    #endif
+  #endif
+
+  #define UINT8_MAX 0xff
+
+#else
+  //
+  // Use ANSI C 2000 stdint.h integer width declarations
+  //
+  #include <stdint.h>
+  typedef uint8_t   BOOLEAN;
+  typedef int8_t    INT8;
+  typedef uint8_t   UINT8;
+  typedef int16_t   INT16;
+  typedef uint16_t  UINT16;
+  typedef int32_t   INT32;
+  typedef uint32_t  UINT32;
+  typedef int64_t   INT64;
+  typedef uint64_t  UINT64;
+  typedef char      CHAR8;
+  typedef uint16_t  CHAR16;
+
+#endif
+
+typedef UINT64  UINTN;
+typedef INT64   INTN;
+
+
+//
+// Processor specific defines
+//
+#define MAX_BIT     0x8000000000000000ULL
+#define MAX_2_BITS  0xC000000000000000ULL
+
+//
+// Maximum legal Itanium-based address
+//
+#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFFULL
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify thier member functions with EFIAPI.
+//
+#if _MSC_EXTENSIONS 
+  ///
+  /// Define the standard calling convention reguardless of optimization level.
+  /// __cdecl is Microsoft* specific C extension.
+  /// 
+  #define EFIAPI __cdecl  
+#elif __GNUC__
+  ///
+  /// Define the standard calling convention reguardless of optimization level.
+  /// efidecl is an extension to GCC that supports the differnece between x64
+  /// GCC ABI and x64 Microsoft* ABI. EFI is closer to the Microsoft* ABI and
+  /// EFIAPI makes sure the right ABI is used for public interfaces. 
+  /// eficecl is a work in progress and we do not yet have the compiler
+  ///
+  #define EFIAPI 
+#else
+  #define EFIAPI       
+#endif
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+//  if the /OPT:REF linker option is used. We defined a macro as this is a 
+//  a non standard extension
+//
+#if _MSC_EXTENSIONS
+  #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+  #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+#endif
+
diff --git a/EfiRom/License.txt b/EfiRom/License.txt
new file mode 100644
index 0000000..5f530a6
--- /dev/null
+++ b/EfiRom/License.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2013, Intel Corporation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in
+  the documentation and/or other materials provided with the
+  distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
-- 
1.8.3.1