CorebootModulePkg: Remove DuetPkg references
authorLeahy, Leroy P <leroy.p.leahy@intel.com>
Mon, 2 May 2016 19:59:17 +0000 (12:59 -0700)
committerPrince Agyeman <prince.agyeman@intel.com>
Mon, 2 May 2016 22:46:44 +0000 (15:46 -0700)
Remove the references to DuetPkg.  Copy the files from revision
ffea0a2ce21e8e9878587de2419959a7bfea4021 of DuetPkg into
CorebootModulePkg.  The components include:
* PciBusNoEnumerationDxe
* PciRootBridgeNoEnumerationDxe
* SataControllerDxe

TEST=Build and run on Galileo Gen2

Change-Id: Id07185f7e226749e5f7c6b6cb427bcef7eac8496
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Prince Agyeman <prince.agyeman@intel.com>
39 files changed:
CorebootModulePkg/PciBusNoEnumerationDxe/ComponentName.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciBusNoEnumeration.inf [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.h [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.c [new file with mode: 0644]
CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.h [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.h [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ipf/PcatIo.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.h [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridgeDevicePath.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridgeIo.c [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PciRootBridgeNoEnumeration.inf [new file with mode: 0644]
CorebootModulePkg/PciRootBridgeNoEnumerationDxe/X64/PcatIo.c [new file with mode: 0644]
CorebootModulePkg/SataControllerDxe/ComponentName.c [new file with mode: 0644]
CorebootModulePkg/SataControllerDxe/SataController.c [new file with mode: 0644]
CorebootModulePkg/SataControllerDxe/SataController.h [new file with mode: 0644]
CorebootModulePkg/SataControllerDxe/SataControllerDxe.inf [new file with mode: 0644]
CorebootPayloadPkg/CorebootPayloadPkg.fdf
CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc
CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc

diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/ComponentName.c b/CorebootModulePkg/PciBusNoEnumerationDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..9419f9a
--- /dev/null
@@ -0,0 +1,161 @@
+/*++
+
+Copyright (c) 2005 - 2007, 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.
+
+Module Name:
+  ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "PciBus.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  EFI_HANDLE                   ControllerHandle,
+  IN  EFI_HANDLE                   ChildHandle        OPTIONAL,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **ControllerName
+  );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {
+  PciBusComponentNameGetDriverName,
+  PciBusComponentNameGetControllerName,
+  "eng"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) PciBusComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PciBusComponentNameGetControllerName,
+  "en"
+};
+
+
+EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {
+  { "eng;en", L"PCI Bus Driver" },
+  { NULL, NULL }
+};
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+/*++
+
+  Routine Description:
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+  Arguments:
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+    Language   - A pointer to a three character ISO 639-2 language identifier.
+                 This is the language of the driver name that that the caller 
+                 is requesting, and it must match one of the languages specified
+                 in SupportedLanguages.  The number of languages supported by a 
+                 driver is up to the driver writer.
+    DriverName - A pointer to the Unicode string to return.  This Unicode string
+                 is the name of the driver specified by This in the language 
+                 specified by Language.
+
+  Returns:
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This
+                            and the language specified by Language was returned 
+                            in DriverName.
+    EFI_INVALID_PARAMETER - Language is NULL.
+    EFI_INVALID_PARAMETER - DriverName is NULL.
+    EFI_UNSUPPORTED       - The driver specified by This does not support the 
+                            language specified by Language.
+
+--*/
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mPciBusDriverNameTable, 
+           DriverName,
+           (BOOLEAN)(This == &gPciBusComponentName)
+           );
+}
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  EFI_HANDLE                   ControllerHandle,
+  IN  EFI_HANDLE                   ChildHandle        OPTIONAL,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **ControllerName
+  )
+/*++
+
+  Routine Description:
+    Retrieves a Unicode string that is the user readable name of the controller
+    that is being managed by an EFI Driver.
+
+  Arguments:
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+    ControllerHandle - The handle of a controller that the driver specified by
+                       This is managing.  This handle specifies the controller
+                       whose name is to be returned.
+    ChildHandle      - The handle of the child controller to retrieve the name
+                       of.  This is an optional parameter that may be NULL.  It
+                       will be NULL for device drivers.  It will also be NULL 
+                       for a bus drivers that wish to retrieve the name of the 
+                       bus controller.  It will not be NULL for a bus driver 
+                       that wishes to retrieve the name of a child controller.
+    Language         - A pointer to a three character ISO 639-2 language 
+                       identifier.  This is the language of the controller name
+                       that that the caller is requesting, and it must match one
+                       of the languages specified in SupportedLanguages.  The 
+                       number of languages supported by a driver is up to the 
+                       driver writer.
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode
+                       string is the name of the controller specified by 
+                       ControllerHandle and ChildHandle in the language specified
+                       by Language from the point of view of the driver specified
+                       by This. 
+
+  Returns:
+    EFI_SUCCESS           - The Unicode string for the user readable name in the
+                            language specified by Language for the driver 
+                            specified by This was returned in DriverName.
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+    EFI_INVALID_PARAMETER - Language is NULL.
+    EFI_INVALID_PARAMETER - ControllerName is NULL.
+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 
+                            the controller specified by ControllerHandle and 
+                            ChildHandle.
+    EFI_UNSUPPORTED       - The driver specified by This does not support the 
+                            language specified by Language.
+
+--*/
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.c
new file mode 100644 (file)
index 0000000..aa33162
--- /dev/null
@@ -0,0 +1,346 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciBus.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+--*/
+
+#include "PciBus.h"
+
+//
+// PCI Bus Support Function Prototypes
+//
+
+EFI_STATUS
+EFIAPI
+PciBusEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  );
+
+
+//
+// PCI Bus Driver Global Variables
+//
+
+EFI_DRIVER_BINDING_PROTOCOL                   gPciBusDriverBinding = {
+  PciBusDriverBindingSupported,
+  PciBusDriverBindingStart,
+  PciBusDriverBindingStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+BOOLEAN gFullEnumeration;
+
+UINT64 gAllOne    = 0xFFFFFFFFFFFFFFFFULL;
+UINT64 gAllZero   = 0;
+//
+// PCI Bus Driver Support Functions
+//
+EFI_STATUS
+EFIAPI
+PciBusEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Initialize the global variables
+  publish the driver binding protocol
+
+Arguments:
+
+  IN EFI_HANDLE     ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+
+Returns:
+
+  EFI_SUCCESS 
+  EFI_DEVICE_ERROR 
+
+--*/
+{
+  EFI_STATUS         Status;
+
+  //
+  // Initialize the EFI Driver Library
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gPciBusDriverBinding,
+             ImageHandle,
+             &gPciBusComponentName,
+             &gPciBusComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+  
+  InitializePciDevicePool ();
+
+  gFullEnumeration = TRUE;
+  
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+
+  Check to see if pci bus driver supports the given controller
+
+Arguments:
+  
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+
+Returns:
+
+  EFI_SUCCESS
+
+--*/
+{
+  EFI_STATUS                      Status;
+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+  EFI_DEV_PATH_PTR                Node;
+
+  if (RemainingDevicePath != NULL) {
+    Node.DevPath = RemainingDevicePath;
+    if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
+        Node.DevPath->SubType != HW_PCI_DP         ||
+        DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &ParentDevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (Status == EFI_ALREADY_STARTED) {
+    return EFI_SUCCESS;
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiDevicePathProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  (VOID **) &PciRootBridgeIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (Status == EFI_ALREADY_STARTED) {
+    return EFI_SUCCESS;
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciRootBridgeIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+
+  Start to management the controller passed in
+
+Arguments:
+  
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+
+Returns:
+
+--*/
+{
+  EFI_STATUS                          Status;
+
+  //
+  // Enumerate the entire host bridge
+  // After enumeration, a database that records all the device information will be created
+  //
+  //
+  Status = PciEnumerator (Controller);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  //
+  // Enable PCI device specified by remaining device path. BDS or other driver can call the
+  // start more than once.
+  //
+  
+  StartPciDevices (Controller, RemainingDevicePath);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  )
+/*++
+
+Routine Description:
+
+  Stop one or more children created at start of pci bus driver
+  if all the the children get closed, close the protocol
+
+Arguments:
+  
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+
+Returns:
+
+  
+--*/
+{
+  EFI_STATUS  Status;
+  UINTN       Index;
+  BOOLEAN     AllChildrenStopped;
+
+  if (NumberOfChildren == 0) {
+    //
+    // Close the bus driver
+    //
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiDevicePathProtocolGuid,
+           This->DriverBindingHandle,
+           Controller
+           );
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiPciRootBridgeIoProtocolGuid,
+           This->DriverBindingHandle,
+           Controller
+           );
+
+    DestroyRootBridgeByHandle (
+      Controller
+      );
+
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Stop all the children
+  //
+
+  AllChildrenStopped = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren; Index++) {
+
+    //
+    // De register all the pci device
+    //
+    Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
+
+    if (EFI_ERROR (Status)) {
+      AllChildrenStopped = FALSE;
+    }
+  }
+
+  if (!AllChildrenStopped) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciBus.h
new file mode 100644 (file)
index 0000000..9c18208
--- /dev/null
@@ -0,0 +1,225 @@
+/*++
+
+Copyright (c) 2005 - 2007, 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.             
+
+Module Name:
+
+  PciBus.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_BUS_H
+#define _EFI_PCI_BUS_H
+
+#include <PiDxe.h>
+
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Decompress.h>
+#include <Protocol/UgaIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/BusSpecificDriverOverride.h>
+
+#include <Guid/PciOptionRomTable.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffLib.h>
+
+//
+// Driver Produced Protocol Prototypes
+//
+
+#define VGABASE1  0x3B0
+#define VGALIMIT1 0x3BB
+
+#define VGABASE2  0x3C0
+#define VGALIMIT2 0x3DF
+
+#define ISABASE   0x100
+#define ISALIMIT  0x3FF
+
+typedef enum {
+  PciBarTypeUnknown = 0,
+  PciBarTypeIo16,
+  PciBarTypeIo32,
+  PciBarTypeMem32,
+  PciBarTypePMem32,
+  PciBarTypeMem64,
+  PciBarTypePMem64,
+  PciBarTypeIo,
+  PciBarTypeMem,
+  PciBarTypeMaxType
+} PCI_BAR_TYPE;
+
+typedef struct {
+  UINT64        BaseAddress;
+  UINT64        Length;
+  UINT64        Alignment;
+  PCI_BAR_TYPE  BarType;
+  BOOLEAN       Prefetchable;
+  UINT8         MemType;
+  UINT8         Offset;
+} PCI_BAR;
+
+#define PCI_IO_DEVICE_SIGNATURE   SIGNATURE_32 ('p','c','i','o')
+
+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED        0x0001 
+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED      0x0002 
+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED      0x0004 
+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED        0x0008  
+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED   0x0010  
+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED       0x0020
+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED       0x0040
+
+
+typedef struct _PCI_IO_DEVICE {
+  UINT32                                    Signature;
+  EFI_HANDLE                                Handle;
+  EFI_PCI_IO_PROTOCOL                       PciIo;
+  LIST_ENTRY                            Link;
+
+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;
+  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *PciRootBridgeIo;
+
+  //
+  // PCI configuration space header type
+  //
+  PCI_TYPE00                                Pci;
+
+  //
+  // Bus number, Device number, Function number
+  //
+  UINT8                                     BusNumber;
+  UINT8                                     DeviceNumber;
+  UINT8                                     FunctionNumber;
+
+  //
+  // BAR for this PCI Device
+  //
+  PCI_BAR                                   PciBar[PCI_MAX_BAR];
+
+  //
+  // The bridge device this pci device is subject to
+  //
+  struct _PCI_IO_DEVICE                     *Parent;
+
+  //
+  // A linked list for children Pci Device if it is bridge device
+  //
+  LIST_ENTRY                            ChildList;
+
+  //
+  // TURE if the PCI bus driver creates the handle for this PCI device
+  //
+  BOOLEAN                                   Registered;
+
+  //
+  // TRUE if the PCI bus driver successfully allocates the resource required by
+  // this PCI device
+  //
+  BOOLEAN                                   Allocated;
+
+  //
+  // The attribute this PCI device currently set
+  //
+  UINT64                                    Attributes;
+
+  //
+  // The attributes this PCI device actually supports
+  //
+  UINT64                                    Supports;
+
+  //
+  // The resource decode the bridge supports
+  //
+  UINT32                                    Decodes;
+
+  //
+  // The OptionRom Size
+  //
+  UINT64                                    RomSize;
+
+  //
+  // TRUE if there is any EFI driver in the OptionRom
+  //
+  BOOLEAN                                   BusOverride;
+
+  //
+  //  A list tracking reserved resource on a bridge device
+  //
+  LIST_ENTRY                            ReservedResourceList;
+
+  //
+  // A list tracking image handle of platform specific overriding driver
+  //
+  LIST_ENTRY                            OptionRomDriverList;
+
+  BOOLEAN                                   IsPciExp;
+
+} PCI_IO_DEVICE;
+
+
+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
+  CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \
+  CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_LINK(a) \
+  CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gPciBusComponentName2;
+extern EFI_DRIVER_BINDING_PROTOCOL  gPciBusDriverBinding;
+
+extern BOOLEAN                     gFullEnumeration;
+extern UINT64                      gAllOne;
+extern UINT64                      gAllZero;
+
+#include "PciIo.h"
+#include "PciCommand.h"
+#include "PciDeviceSupport.h"
+#include "PciEnumerator.h"
+#include "PciEnumeratorSupport.h"
+#include "PciDriverOverride.h"
+#include "PciRomTable.h"
+#include "PciOptionRomSupport.h"
+#include "PciPowerManagement.h"
+
+
+#define IS_ISA_BRIDGE(_p)       IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA)  
+#define IS_INTEL_ISA_BRIDGE(_p) (IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE) && ((_p)->Hdr.VendorId == 0x8086) && ((_p)->Hdr.DeviceId == 0x7110))
+#define IS_PCI_GFX(_p)     IS_CLASS2 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_OTHER)
+
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciBusNoEnumeration.inf b/CorebootModulePkg/PciBusNoEnumerationDxe/PciBusNoEnumeration.inf
new file mode 100644 (file)
index 0000000..b6ec9c0
--- /dev/null
@@ -0,0 +1,72 @@
+## @file
+# 
+# Copyright (c) 2005 - 2010, 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.             
+#
+#  Module Name:
+#
+#  Abstract:
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PciBusNoEnumerationDxe
+  FILE_GUID                      = 35C0C168-2607-4e51-BB53-448E3ED1A87F
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = PciBusEntryPoint
+
+[Packages]
+  MdePkg/MdePkg.dec
+  DuetPkg/DuetPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  ReportStatusCodeLib
+  DevicePathLib
+  PeCoffLib
+
+[Sources]
+  PciBus.h
+  PciIo.h
+  PciCommand.h
+  PciDeviceSupport.h
+  PciEnumerator.h
+  PciEnumeratorSupport.h
+  PciOptionRomSupport.h
+  PciRomTable.h
+  PciPowerManagement.h
+  PciPowerManagement.c
+  PciRomTable.c
+  PciDriverOverride.h
+  PciDriverOverride.c
+  PciOptionRomSupport.c
+  PciEnumerator.c
+  PciEnumeratorSupport.c
+  PciCommand.c
+  ComponentName.c
+  PciDeviceSupport.c
+  PciBus.c
+  PciIo.c
+
+[Protocols]
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiBusSpecificDriverOverrideProtocolGuid
+  gEfiDecompressProtocolGuid
+  
+[Guids]
+  gEfiPciOptionRomTableGuid
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.c
new file mode 100644 (file)
index 0000000..6682830
--- /dev/null
@@ -0,0 +1,453 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciCommand.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+
+EFI_STATUS 
+PciReadCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  OUT UINT16       *Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  *Command = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  return PciIo->Pci.Read (
+                PciIo, 
+                EfiPciIoWidthUint16, 
+                PCI_COMMAND_OFFSET, 
+                1, 
+                Command
+                );
+}
+  
+EFI_STATUS 
+PciSetCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16                Temp;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  
+  Temp = Command;
+  PciIo = &PciIoDevice->PciIo;
+
+  return PciIo->Pci.Write (
+              PciIo, 
+              EfiPciIoWidthUint16, 
+              PCI_COMMAND_OFFSET, 
+              1, 
+              &Temp
+              );
+  
+}
+
+
+EFI_STATUS 
+PciEnableCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16  OldCommand;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  OldCommand = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  PciIo->Pci.Read (
+          PciIo, 
+          EfiPciIoWidthUint16, 
+          PCI_COMMAND_OFFSET, 
+          1, 
+          &OldCommand
+          );
+
+  OldCommand = (UINT16) (OldCommand | Command);
+
+  return PciIo->Pci.Write (
+              PciIo, 
+              EfiPciIoWidthUint16, 
+              PCI_COMMAND_OFFSET, 
+              1, 
+              &OldCommand
+              );
+  
+}
+
+
+EFI_STATUS 
+PciDisableCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16  OldCommand;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  OldCommand = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  PciIo->Pci.Read (
+          PciIo, 
+          EfiPciIoWidthUint16, 
+          PCI_COMMAND_OFFSET, 
+          1, 
+          &OldCommand
+          );
+
+  OldCommand = (UINT16) (OldCommand & ~(Command));
+
+  return PciIo->Pci.Write (
+            PciIo, 
+            EfiPciIoWidthUint16, 
+            PCI_COMMAND_OFFSET, 
+            1, 
+            &OldCommand
+           );
+  
+}
+
+
+
+EFI_STATUS 
+PciSetBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16                Temp;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  Temp = Command;
+  PciIo = &PciIoDevice->PciIo;
+
+  return PciIo->Pci.Write (
+                PciIo, 
+                EfiPciIoWidthUint16, 
+                PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+                1, 
+                &Temp
+               );
+}
+
+
+EFI_STATUS 
+PciEnableBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16  OldCommand;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  OldCommand = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  PciIo->Pci.Read (
+          PciIo, 
+          EfiPciIoWidthUint16, 
+          PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+          1, 
+          &OldCommand
+          );
+
+  OldCommand = (UINT16) (OldCommand | Command);
+
+  return PciIo->Pci.Write (
+              PciIo, 
+              EfiPciIoWidthUint16, 
+              PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+              1, 
+              &OldCommand
+             );
+  
+}
+
+EFI_STATUS 
+PciDisableBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16  OldCommand;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  OldCommand = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  PciIo->Pci.Read (
+          PciIo, 
+          EfiPciIoWidthUint16, 
+          PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+          1, 
+          &OldCommand
+          );
+
+  OldCommand = (UINT16) (OldCommand & ~(Command));
+
+  return PciIo->Pci.Write (
+              PciIo, 
+              EfiPciIoWidthUint16, 
+              PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+              1, 
+              &OldCommand
+              );
+}
+
+
+
+EFI_STATUS 
+PciReadBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  OUT UINT16       *Command
+)
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+  *Command = 0;
+  PciIo = &PciIoDevice->PciIo;
+
+  return PciIo->Pci.Read (
+                PciIo, 
+                EfiPciIoWidthUint16, 
+                PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 
+                1, 
+                Command
+                );
+}
+
+BOOLEAN
+PciCapabilitySupport (
+  IN PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+  
+  None
+
+--*/
+// TODO:    PciIoDevice - add argument and description to function comment
+{
+
+  if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+LocateCapabilityRegBlock (
+  IN     PCI_IO_DEVICE *PciIoDevice,
+  IN     UINT8         CapId,
+  IN OUT UINT8         *Offset,
+     OUT UINT8         *NextRegBlock OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Locate Capability register.
+
+Arguments:
+
+  PciIoDevice         - A pointer to the PCI_IO_DEVICE.
+  CapId               - The capability ID.
+  Offset              - A pointer to the offset. 
+                        As input: the default offset; 
+                        As output: the offset of the found block.
+  NextRegBlock        - An optional pointer to return the value of next block.
+
+Returns:
+  
+  EFI_UNSUPPORTED     - The Pci Io device is not supported.
+  EFI_NOT_FOUND       - The Pci Io device cannot be found.
+  EFI_SUCCESS         - The Pci Io device is successfully located.
+
+--*/
+{
+  UINT8   CapabilityPtr;
+  UINT16  CapabilityEntry;
+  UINT8   CapabilityID;
+
+  //
+  // To check the capability of this device supports
+  //
+  if (!PciCapabilitySupport (PciIoDevice)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (*Offset != 0) {
+    CapabilityPtr = *Offset;
+  } else {
+
+    CapabilityPtr = 0;
+    if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+
+      PciIoDevice->PciIo.Pci.Read (
+                               &PciIoDevice->PciIo,
+                               EfiPciIoWidthUint8,
+                               EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
+                               1,
+                               &CapabilityPtr
+                               );
+    } else {
+
+      PciIoDevice->PciIo.Pci.Read (
+                               &PciIoDevice->PciIo,
+                               EfiPciIoWidthUint8,
+                               PCI_CAPBILITY_POINTER_OFFSET,
+                               1,
+                               &CapabilityPtr
+                               );
+    }
+  }
+
+  while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
+    PciIoDevice->PciIo.Pci.Read (
+                             &PciIoDevice->PciIo,
+                             EfiPciIoWidthUint16,
+                             CapabilityPtr,
+                             1,
+                             &CapabilityEntry
+                             );
+
+    CapabilityID = (UINT8) CapabilityEntry;
+
+    if (CapabilityID == CapId) {
+      *Offset = CapabilityPtr;
+      if (NextRegBlock != NULL) {
+        *NextRegBlock = (UINT8) (CapabilityEntry >> 8);
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
+  }
+
+  return EFI_NOT_FOUND;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciCommand.h
new file mode 100644 (file)
index 0000000..da67b78
--- /dev/null
@@ -0,0 +1,167 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+  
+    PciCommand.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_COMMAND_H
+#define _EFI_PCI_COMMAND_H
+
+#include "PciBus.h"
+
+//
+// The PCI Command register bits owned by PCI Bus driver.
+//
+// They should be cleared at the beginning. The other registers
+// are owned by chipset, we should not touch them.
+//
+#define EFI_PCI_COMMAND_BITS_OWNED                          ( \
+                EFI_PCI_COMMAND_IO_SPACE                    | \
+                EFI_PCI_COMMAND_MEMORY_SPACE                | \
+                EFI_PCI_COMMAND_BUS_MASTER                  | \
+                EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \
+                EFI_PCI_COMMAND_VGA_PALETTE_SNOOP           | \
+                EFI_PCI_COMMAND_FAST_BACK_TO_BACK             \
+                )
+
+//
+// The PCI Bridge Control register bits owned by PCI Bus driver.
+// 
+// They should be cleared at the beginning. The other registers
+// are owned by chipset, we should not touch them.
+//
+#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED                   ( \
+                EFI_PCI_BRIDGE_CONTROL_ISA                  | \
+                EFI_PCI_BRIDGE_CONTROL_VGA                  | \
+                EFI_PCI_BRIDGE_CONTROL_VGA_16               | \
+                EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK      \
+                )
+
+//
+// The PCCard Bridge Control register bits owned by PCI Bus driver.
+// 
+// They should be cleared at the beginning. The other registers
+// are owned by chipset, we should not touch them.
+//
+#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED                ( \
+                EFI_PCI_BRIDGE_CONTROL_ISA                  | \
+                EFI_PCI_BRIDGE_CONTROL_VGA                  | \
+                EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK      \
+                )
+
+EFI_STATUS 
+PciReadCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  OUT UINT16       *Command
+);
+
+  
+EFI_STATUS 
+PciSetCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+);
+
+EFI_STATUS 
+PciEnableCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+);
+
+EFI_STATUS 
+PciDisableCommandRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+);
+
+EFI_STATUS 
+PciDisableBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+);
+
+
+EFI_STATUS 
+PciEnableBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINT16        Command
+);
+
+EFI_STATUS 
+PciReadBridgeControlRegister (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  OUT UINT16       *Command
+);
+
+BOOLEAN
+PciCapabilitySupport (
+  IN PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+LocateCapabilityRegBlock (
+  IN     PCI_IO_DEVICE *PciIoDevice,
+  IN     UINT8         CapId,
+  IN OUT UINT8         *Offset,
+     OUT UINT8         *NextRegBlock OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Locate Capability register.
+
+Arguments:
+
+  PciIoDevice         - A pointer to the PCI_IO_DEVICE.
+  CapId               - The capability ID.
+  Offset              - A pointer to the offset. 
+                        As input: the default offset; 
+                        As output: the offset of the found block.
+  NextRegBlock        - An optional pointer to return the value of next block.
+
+Returns:
+  
+  EFI_UNSUPPORTED     - The Pci Io device is not supported.
+  EFI_NOT_FOUND       - The Pci Io device cannot be found.
+  EFI_SUCCESS         - The Pci Io device is successfully located.
+
+--*/
+;
+
+
+#endif
+
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.c
new file mode 100644 (file)
index 0000000..97a4e01
--- /dev/null
@@ -0,0 +1,973 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciDeviceSupport.c
+  
+Abstract:
+
+  This file provides routine to support Pci device node manipulation
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+//
+// This device structure is serviced as a header.
+// Its Next field points to the first root bridge device node
+//
+LIST_ENTRY  gPciDevicePool;
+
+EFI_STATUS
+InitializePciDevicePool (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Initialize the gPciDevicePool
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  InitializeListHead (&gPciDevicePool);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InsertRootBridge (
+  IN PCI_IO_DEVICE *RootBridge
+  )
+/*++
+
+Routine Description:
+
+  Insert a root bridge into PCI device pool
+
+Arguments:
+
+  RootBridge    - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+{
+  InsertTailList (&gPciDevicePool, &(RootBridge->Link));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InsertPciDevice (
+  PCI_IO_DEVICE *Bridge,
+  PCI_IO_DEVICE *PciDeviceNode
+  )
+/*++
+
+Routine Description:
+
+  This function is used to insert a PCI device node under
+  a bridge
+
+Arguments:
+  Bridge        - A pointer to the PCI_IO_DEVICE.
+  PciDeviceNode - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+
+{
+
+  InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));
+  PciDeviceNode->Parent = Bridge;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyRootBridge (
+  IN PCI_IO_DEVICE *RootBridge
+  )
+/*++
+
+Routine Description:
+
+  
+Arguments:
+
+  RootBridge   - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+{
+  DestroyPciDeviceTree (RootBridge);
+
+  gBS->FreePool (RootBridge);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyPciDeviceTree (
+  IN PCI_IO_DEVICE *Bridge
+  )
+/*++
+
+Routine Description:
+
+  Destroy all the pci device node under the bridge.
+  Bridge itself is not included.
+
+Arguments:
+
+  Bridge   - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+{
+  LIST_ENTRY  *CurrentLink;
+  PCI_IO_DEVICE   *Temp;
+
+  while (!IsListEmpty (&Bridge->ChildList)) {
+
+    CurrentLink = Bridge->ChildList.ForwardLink;
+
+    //
+    // Remove this node from the linked list
+    //
+    RemoveEntryList (CurrentLink);
+
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    if (IS_PCI_BRIDGE (&(Temp->Pci))) {
+      DestroyPciDeviceTree (Temp);
+    }
+    gBS->FreePool (Temp);
+  }
+  
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyRootBridgeByHandle (
+  EFI_HANDLE Controller
+  )
+/*++
+
+Routine Description:
+
+  Destroy all device nodes under the root bridge
+  specified by Controller. 
+  The root bridge itself is also included.
+
+Arguments:
+
+  Controller   - An efi handle.
+
+Returns:
+
+  None
+
+--*/
+{
+
+  LIST_ENTRY  *CurrentLink;
+  PCI_IO_DEVICE   *Temp;
+
+  CurrentLink = gPciDevicePool.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &gPciDevicePool) {
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    if (Temp->Handle == Controller) {
+
+      RemoveEntryList (CurrentLink);
+
+      DestroyPciDeviceTree (Temp);
+
+      gBS->FreePool(Temp);
+
+      return EFI_SUCCESS;
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+RegisterPciDevice (
+  IN  EFI_HANDLE                     Controller,
+  IN  PCI_IO_DEVICE                  *PciIoDevice,
+  OUT EFI_HANDLE                     *Handle OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  This function registers the PCI IO device. It creates a handle for this PCI IO device 
+  (if the handle does not exist), attaches appropriate protocols onto the handle, does
+  necessary initialization, and sets up parent/child relationship with its bus controller.
+
+Arguments:
+
+  Controller    - An EFI handle for the PCI bus controller.
+  PciIoDevice   - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
+  Handle        - A pointer to hold the EFI handle for the PCI IO device.
+
+Returns:
+
+  EFI_SUCCESS   - The PCI device is successfully registered.
+  Others        - An error occurred when registering the PCI device.
+
+--*/
+{
+  EFI_STATUS          Status;
+  UINT8               PciExpressCapRegOffset;
+
+  //
+  // Install the pciio protocol, device path protocol and 
+  // Bus Specific Driver Override Protocol
+  //
+
+  if (PciIoDevice->BusOverride) {
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                  &PciIoDevice->Handle,             
+                  &gEfiDevicePathProtocolGuid,
+                  PciIoDevice->DevicePath,
+                  &gEfiPciIoProtocolGuid,
+                  &PciIoDevice->PciIo,
+                  &gEfiBusSpecificDriverOverrideProtocolGuid,
+                  &PciIoDevice->PciDriverOverride,
+                  NULL
+                  );
+  } else {
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                  &PciIoDevice->Handle,             
+                  &gEfiDevicePathProtocolGuid,
+                  PciIoDevice->DevicePath,
+                  &gEfiPciIoProtocolGuid,
+                  &PciIoDevice->PciIo,
+                  NULL
+                  );
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  } else {
+    Status = gBS->OpenProtocol (
+                    Controller,           
+                    &gEfiPciRootBridgeIoProtocolGuid, 
+                    (VOID **)&(PciIoDevice->PciRootBridgeIo),
+                    gPciBusDriverBinding.DriverBindingHandle,
+                    PciIoDevice->Handle,   
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  if (Handle != NULL) {
+    *Handle = PciIoDevice->Handle;
+  }
+
+  //
+  // Detect if PCI Express Device
+  //
+  PciExpressCapRegOffset = 0;
+  Status = LocateCapabilityRegBlock (
+             PciIoDevice,
+             EFI_PCI_CAPABILITY_ID_PCIEXP,
+             &PciExpressCapRegOffset,
+             NULL
+             );
+  if (!EFI_ERROR (Status)) {
+    PciIoDevice->IsPciExp = TRUE;
+    DEBUG ((EFI_D_ERROR, "PciExp - %x (B-%x, D-%x, F-%x)\n", PciIoDevice->IsPciExp, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber));
+  }
+  
+  //
+  // Indicate the pci device is registered
+  //
+  PciIoDevice->Registered = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+DeRegisterPciDevice (
+  IN  EFI_HANDLE                     Controller,
+  IN  EFI_HANDLE                     Handle
+  )
+/*++
+
+Routine Description:
+
+  This function is used to de-register the PCI device from the EFI,
+  That includes un-installing PciIo protocol from the specified PCI 
+  device handle.
+
+Arguments:
+
+  Controller   - An efi handle.
+  Handle       - An efi handle.
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_PCI_IO_PROTOCOL             *PciIo;
+  EFI_STATUS                      Status;
+  PCI_IO_DEVICE                   *PciIoDevice;
+  PCI_IO_DEVICE                   *Node;
+  LIST_ENTRY                  *CurrentLink;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+  Status = gBS->OpenProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  gPciBusDriverBinding.DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (!EFI_ERROR (Status)) {
+    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
+
+    //
+    // If it is already de-registered
+    //
+    if (!PciIoDevice->Registered) {
+      return EFI_SUCCESS;
+    }
+
+    //
+    // If it is PPB, first de-register its children
+    //
+
+    if (IS_PCI_BRIDGE (&(PciIoDevice->Pci))) {
+
+      CurrentLink = PciIoDevice->ChildList.ForwardLink;
+
+      while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
+        Node    = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+        Status  = DeRegisterPciDevice (Controller, Node->Handle);
+
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+        CurrentLink = CurrentLink->ForwardLink;
+      }
+    }
+
+    //
+    // First disconnect this device
+    //
+//    PciIoDevice->PciIo.Attributes(&(PciIoDevice->PciIo),
+//                                    EfiPciIoAttributeOperationDisable,
+//                                    EFI_PCI_DEVICE_ENABLE,
+//                                    NULL
+//                                    );
+       
+    //
+    // Close the child handle
+    //
+    Status = gBS->CloseProtocol (
+                    Controller,
+                    &gEfiPciRootBridgeIoProtocolGuid,
+                    gPciBusDriverBinding.DriverBindingHandle,
+                    Handle
+                    );
+
+    //
+    // Un-install the device path protocol and pci io protocol
+    //
+    if (PciIoDevice->BusOverride) {
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Handle,
+                      &gEfiDevicePathProtocolGuid,
+                      PciIoDevice->DevicePath,
+                      &gEfiPciIoProtocolGuid,
+                      &PciIoDevice->PciIo,
+                      &gEfiBusSpecificDriverOverrideProtocolGuid,
+                      &PciIoDevice->PciDriverOverride,
+                      NULL
+                      );
+    } else {
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Handle,
+                      &gEfiDevicePathProtocolGuid,
+                      PciIoDevice->DevicePath,
+                      &gEfiPciIoProtocolGuid,
+                      &PciIoDevice->PciIo,
+                      NULL
+                      );
+    }
+
+    if (EFI_ERROR (Status)) {
+      gBS->OpenProtocol (
+            Controller,
+            &gEfiPciRootBridgeIoProtocolGuid,
+            (VOID **) &PciRootBridgeIo,
+            gPciBusDriverBinding.DriverBindingHandle,
+            Handle,
+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+            );
+      return Status;
+    }
+    
+    //
+    // The Device Driver should disable this device after disconnect
+    // so the Pci Bus driver will not touch this device any more.
+    // Restore the register field to the original value
+    //
+    PciIoDevice->Registered = FALSE;
+    PciIoDevice->Handle     = NULL;
+  } else {
+
+    //
+    // Handle may be closed before
+    //
+    return EFI_SUCCESS;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EnableBridgeAttributes (
+  IN PCI_IO_DEVICE                       *PciIoDevice
+  )
+{
+  PCI_TYPE01                PciData;
+
+  //
+  // NOTE: We should not set EFI_PCI_DEVICE_ENABLE for a bridge
+  //       directly, because some legacy BIOS will NOT assign
+  //       IO or Memory resource for a bridge who has no child
+  //       device. So we add check IO or Memory here.
+  //
+
+  PciIoDevice->PciIo.Pci.Read (
+                           &PciIoDevice->PciIo,
+                           EfiPciIoWidthUint8,
+                           0,
+                           sizeof (PciData),
+                           &PciData
+                           );
+
+  if ((((PciData.Bridge.IoBase & 0xF) == 0) &&
+        (PciData.Bridge.IoBase != 0 || PciData.Bridge.IoLimit != 0)) ||
+      (((PciData.Bridge.IoBase & 0xF) == 1) &&
+        ((PciData.Bridge.IoBase & 0xF0) != 0 || (PciData.Bridge.IoLimit & 0xF0) != 0 || PciData.Bridge.IoBaseUpper16 != 0 || PciData.Bridge.IoLimitUpper16 != 0))) {
+    PciIoDevice->PciIo.Attributes(
+                         &(PciIoDevice->PciIo),
+                         EfiPciIoAttributeOperationEnable,
+                         (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
+                         NULL
+                         );
+  }
+  if ((PciData.Bridge.MemoryBase & 0xFFF0) != 0 || (PciData.Bridge.MemoryLimit & 0xFFF0) != 0) {
+    PciIoDevice->PciIo.Attributes(
+                         &(PciIoDevice->PciIo),
+                         EfiPciIoAttributeOperationEnable,
+                         (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
+                         NULL
+                         );
+  }
+  if ((((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 0) &&
+        (PciData.Bridge.PrefetchableMemoryBase != 0 || PciData.Bridge.PrefetchableMemoryLimit != 0)) ||
+      (((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 1) &&
+        ((PciData.Bridge.PrefetchableMemoryBase & 0xFFF0) != 0 || (PciData.Bridge.PrefetchableMemoryLimit & 0xFFF0) != 0 || PciData.Bridge.PrefetchableBaseUpper32 != 0 || PciData.Bridge.PrefetchableLimitUpper32 != 0))) {
+    PciIoDevice->PciIo.Attributes(
+                         &(PciIoDevice->PciIo),
+                         EfiPciIoAttributeOperationEnable,
+                         (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
+                         NULL
+                         );
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS 
+StartPciDevicesOnBridge (
+  IN EFI_HANDLE                          Controller,
+  IN PCI_IO_DEVICE                       *RootBridge,
+  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath 
+  )
+/*++
+
+Routine Description:
+
+  Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
+
+Arguments:
+
+  Controller          - An efi handle.
+  RootBridge          - A pointer to the PCI_IO_DEVICE.
+  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+  NumberOfChildren    - Children number.
+  ChildHandleBuffer   - A pointer to the child handle buffer.
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE             *Temp;
+  PCI_IO_DEVICE             *PciIoDevice;
+  EFI_DEV_PATH_PTR          Node;
+  EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;
+  EFI_STATUS                Status;
+  LIST_ENTRY            *CurrentLink;
+
+  CurrentLink = RootBridge->ChildList.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
+
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+    if (RemainingDevicePath != NULL) {
+
+      Node.DevPath = RemainingDevicePath;
+
+      if (Node.Pci->Device != Temp->DeviceNumber || 
+          Node.Pci->Function != Temp->FunctionNumber) {
+        CurrentLink = CurrentLink->ForwardLink;
+        continue;
+      }
+
+      //
+      // Check if the device has been assigned with required resource
+      //
+      if (!Temp->Allocated) {
+        return EFI_NOT_READY;
+      }
+      
+      //
+      // Check if the current node has been registered before
+      // If it is not, register it
+      //
+      if (!Temp->Registered) {
+        PciIoDevice = Temp;
+
+        Status = RegisterPciDevice (
+                  Controller,
+                  PciIoDevice,
+                  NULL
+                  );
+
+      }
+      
+      //
+      // Get the next device path
+      //
+      CurrentDevicePath = NextDevicePathNode (RemainingDevicePath);
+      if (IsDevicePathEnd (CurrentDevicePath)) {
+        return EFI_SUCCESS;
+      }
+  
+      //
+      // If it is a PPB
+      //
+      if (IS_PCI_BRIDGE (&(Temp->Pci))) {
+        Status = StartPciDevicesOnBridge (
+                  Controller,
+                  Temp,
+                  CurrentDevicePath
+                  );
+        EnableBridgeAttributes (Temp);
+
+        return Status;
+      } else {
+
+        //
+        // Currently, the PCI bus driver only support PCI-PCI bridge
+        //
+        return EFI_UNSUPPORTED;
+      }
+
+    } else {
+
+      //
+      // If remaining device path is NULL,
+      // try to enable all the pci devices under this bridge
+      //
+
+      if (!Temp->Registered && Temp->Allocated) {
+
+        PciIoDevice = Temp;
+
+        Status = RegisterPciDevice (
+                  Controller,
+                  PciIoDevice,
+                  NULL
+                  );
+
+      }
+
+      if (IS_PCI_BRIDGE (&(Temp->Pci))) {
+        Status = StartPciDevicesOnBridge ( 
+                   Controller,
+                   Temp,
+                   RemainingDevicePath
+                   );
+        EnableBridgeAttributes (Temp);
+      }
+
+      CurrentLink = CurrentLink->ForwardLink;
+      continue;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+StartPciDevices (
+  IN EFI_HANDLE                         Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+
+  Start to manage the PCI device according to RemainingDevicePath
+  If RemainingDevicePath == NULL, the PCI bus driver will start 
+  to manage all the PCI devices it found previously
+
+Arguments:
+  Controller          - An efi handle.
+  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_DEV_PATH_PTR  Node;
+  PCI_IO_DEVICE     *RootBridge;
+  LIST_ENTRY    *CurrentLink;
+
+  if (RemainingDevicePath != NULL) {
+
+    //
+    // Check if the RemainingDevicePath is valid
+    //
+    Node.DevPath = RemainingDevicePath;
+    if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
+        Node.DevPath->SubType != HW_PCI_DP         ||
+        DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)
+        ) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  CurrentLink = gPciDevicePool.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+    RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+    //
+    // Locate the right root bridge to start
+    //
+    if (RootBridge->Handle == Controller) {
+      StartPciDevicesOnBridge (
+        Controller,
+        RootBridge,
+        RemainingDevicePath
+        );
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+CreateRootBridge (
+  IN EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+
+Arguments:
+  RootBridgeHandle   - An efi handle.
+
+Returns:
+
+  None
+
+--*/
+{
+
+  EFI_STATUS                      Status;
+  PCI_IO_DEVICE                   *Dev;
+
+  Dev = NULL;
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  sizeof (PCI_IO_DEVICE),
+                  (VOID **) &Dev
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  ZeroMem (Dev, sizeof (PCI_IO_DEVICE));
+  Dev->Signature  = PCI_IO_DEVICE_SIGNATURE;
+  Dev->Handle     = RootBridgeHandle;
+  InitializeListHead (&Dev->ChildList);
+
+  return Dev;
+}
+
+PCI_IO_DEVICE *
+GetRootBridgeByHandle (
+  EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+  RootBridgeHandle    - An efi handle.
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE   *RootBridgeDev;
+  LIST_ENTRY  *CurrentLink;
+
+  CurrentLink = gPciDevicePool.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+    RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+    if (RootBridgeDev->Handle == RootBridgeHandle) {
+      return RootBridgeDev;
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return NULL;
+}
+
+BOOLEAN
+RootBridgeExisted (
+  IN EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+  This function searches if RootBridgeHandle has already existed
+  in current device pool.
+
+  If so, it means the given root bridge has been already enumerated.
+
+Arguments:
+
+  RootBridgeHandle   - An efi handle.
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE *Bridge;
+
+  Bridge = GetRootBridgeByHandle (RootBridgeHandle);
+
+  if (Bridge != NULL) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+BOOLEAN
+PciDeviceExisted (
+  IN PCI_IO_DEVICE    *Bridge,
+  IN PCI_IO_DEVICE    *PciIoDevice
+  )
+/*++
+
+Routine Description:
+  
+Arguments:
+
+  Bridge       - A pointer to the PCI_IO_DEVICE.
+  PciIoDevice  - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+{
+
+  PCI_IO_DEVICE   *Temp;
+  LIST_ENTRY  *CurrentLink;
+
+  CurrentLink = Bridge->ChildList.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    if (Temp == PciIoDevice) {
+      return TRUE;
+    }
+
+    if (!IsListEmpty (&Temp->ChildList)) {
+      if (PciDeviceExisted (Temp, PciIoDevice)) {
+        return TRUE;
+      }
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return FALSE;
+}
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheSameSegment (
+  IN PCI_IO_DEVICE        *VgaDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  VgaDevice    - A pointer to the PCI_IO_DEVICE.
+  
+Returns:
+
+  None
+
+--*/
+{
+  LIST_ENTRY  *CurrentLink;
+  PCI_IO_DEVICE   *Temp;
+
+  CurrentLink = gPciDevicePool.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {
+
+      Temp = ActiveVGADeviceOnTheRootBridge (Temp);
+
+      if (Temp != NULL) {
+        return Temp;
+      }
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return NULL;
+}
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheRootBridge (
+  IN PCI_IO_DEVICE        *RootBridge
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  RootBridge    - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+  None
+
+--*/
+{
+  LIST_ENTRY  *CurrentLink;
+  PCI_IO_DEVICE   *Temp;
+
+  CurrentLink = RootBridge->ChildList.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
+
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    if (IS_PCI_VGA(&Temp->Pci) && 
+        (Temp->Attributes &
+         (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |
+          EFI_PCI_IO_ATTRIBUTE_VGA_IO     |
+          EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {
+      return Temp;
+    }
+
+    if (IS_PCI_BRIDGE (&Temp->Pci)) {
+
+      Temp = ActiveVGADeviceOnTheRootBridge (Temp);
+
+      if (Temp != NULL) {
+        return Temp;
+      }
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return NULL;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciDeviceSupport.h
new file mode 100644 (file)
index 0000000..07fd54b
--- /dev/null
@@ -0,0 +1,324 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciDeviceSupport.h
+  
+Abstract:
+
+  
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_DEVICE_SUPPORT_H
+#define _EFI_PCI_DEVICE_SUPPORT_H
+
+EFI_STATUS
+InitializePciDevicePool (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InsertPciDevice (
+  PCI_IO_DEVICE *Bridge,
+  PCI_IO_DEVICE *PciDeviceNode
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Bridge        - TODO: add argument description
+  PciDeviceNode - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyPciDeviceTree (
+  IN PCI_IO_DEVICE *Bridge
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Bridge  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyRootBridgeByHandle (
+  EFI_HANDLE Controller
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Controller  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RegisterPciDevice (
+  IN  EFI_HANDLE                     Controller,
+  IN  PCI_IO_DEVICE                  *PciIoDevice,
+  OUT EFI_HANDLE                     *Handle OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  This function registers the PCI IO device. It creates a handle for this PCI IO device 
+  (if the handle does not exist), attaches appropriate protocols onto the handle, does
+  necessary initialization, and sets up parent/child relationship with its bus controller.
+
+Arguments:
+
+  Controller    - An EFI handle for the PCI bus controller.
+  PciIoDevice   - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
+  Handle        - A pointer to hold the EFI handle for the PCI IO device.
+
+Returns:
+
+  EFI_SUCCESS   - The PCI device is successfully registered.
+  Others        - An error occurred when registering the PCI device.
+
+--*/
+;
+
+EFI_STATUS
+DeRegisterPciDevice (
+  IN  EFI_HANDLE                     Controller,
+  IN  EFI_HANDLE                     Handle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Controller  - TODO: add argument description
+  Handle      - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+StartPciDevices (
+  IN EFI_HANDLE                         Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Controller          - TODO: add argument description
+  RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+CreateRootBridge (
+  IN EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  RootBridgeHandle  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+GetRootBridgeByHandle (
+  EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  RootBridgeHandle  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS 
+InsertRootBridge (
+  PCI_IO_DEVICE *RootBridge
+);
+
+EFI_STATUS 
+DestroyRootBridge ( 
+   IN PCI_IO_DEVICE *RootBridge 
+);
+
+BOOLEAN
+RootBridgeExisted (
+  IN EFI_HANDLE RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  RootBridgeHandle  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+PciDeviceExisted (
+  IN PCI_IO_DEVICE    *Bridge,
+  IN PCI_IO_DEVICE    *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Bridge      - TODO: add argument description
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheSameSegment (
+  IN PCI_IO_DEVICE        *VgaDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  VgaDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheRootBridge (
+  IN PCI_IO_DEVICE        *RootBridge
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  RootBridge  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.c
new file mode 100644 (file)
index 0000000..6e936ac
--- /dev/null
@@ -0,0 +1,176 @@
+/*++
+
+Copyright (c) 2005 - 2007, 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.             
+
+Module Name:
+
+  PciDriverOverride.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+EFI_STATUS
+EFIAPI
+GetDriver(
+  IN     EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL          *This,
+  IN OUT EFI_HANDLE                                         *DriverImageHandle
+  );
+
+
+
+EFI_STATUS
+InitializePciDriverOverrideInstance (
+  PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  Initializes a PCI Driver Override Instance
+
+Arguments:
+  
+Returns:
+
+  None
+
+--*/
+
+{
+  PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetDriver (
+  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,
+  IN OUT EFI_HANDLE                                         *DriverImageHandle
+  )
+/*++
+
+Routine Description:
+
+  Get a overriding driver image
+
+Arguments:
+  
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE             *PciIoDevice;
+  LIST_ENTRY            *CurrentLink;
+  PCI_DRIVER_OVERRIDE_LIST  *Node;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
+
+  CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
+
+  while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {
+
+    Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
+
+    if (*DriverImageHandle == NULL) {
+
+      *DriverImageHandle = Node->DriverImageHandle;
+      return EFI_SUCCESS;
+    }
+
+    if (*DriverImageHandle == Node->DriverImageHandle) {
+
+      if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
+          CurrentLink->ForwardLink == NULL) {
+        return EFI_NOT_FOUND;
+      }
+
+      //
+      // Get next node
+      //
+      Node                = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
+      *DriverImageHandle  = Node->DriverImageHandle;
+      return EFI_SUCCESS;
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+AddDriver (
+  IN PCI_IO_DEVICE     *PciIoDevice,
+  IN EFI_HANDLE        DriverImageHandle
+  )
+/*++
+
+Routine Description:
+
+  Add a overriding driver image
+
+Arguments:
+  
+Returns:
+
+  None
+
+--*/
+
+{
+  EFI_STATUS                    Status;
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
+  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
+  PCI_DRIVER_OVERRIDE_LIST      *Node;
+
+  Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
+  if (Node == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Node->Signature         = DRIVER_OVERRIDE_SIGNATURE;
+  Node->DriverImageHandle = DriverImageHandle;
+
+  InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
+
+  PciIoDevice->BusOverride  = TRUE;
+
+
+  ImageContext.Handle    = LoadedImage->ImageBase;
+  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+  //
+  // Get information about the image 
+  //
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);
+  if (EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  if (ImageContext.Machine != EFI_IMAGE_MACHINE_EBC) {
+    return EFI_SUCCESS;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciDriverOverride.h
new file mode 100644 (file)
index 0000000..5fbba2e
--- /dev/null
@@ -0,0 +1,110 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciDriverOverride.h
+  
+Abstract:
+
+  
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H
+#define _EFI_PCI_DRIVER_OVERRRIDE_H
+
+#include "PciBus.h"
+
+#define DRIVER_OVERRIDE_SIGNATURE SIGNATURE_32 ('d', 'r', 'o', 'v')
+
+typedef struct {
+  UINT32          Signature;
+  LIST_ENTRY  Link;
+  EFI_HANDLE      DriverImageHandle;
+} PCI_DRIVER_OVERRIDE_LIST;
+
+
+#define DRIVER_OVERRIDE_FROM_LINK(a) \
+  CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)
+
+
+EFI_STATUS
+InitializePciDriverOverrideInstance (
+  PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+AddDriver (
+  IN PCI_IO_DEVICE     *PciIoDevice,
+  IN EFI_HANDLE        DriverImageHandle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice       - TODO: add argument description
+  DriverImageHandle - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetDriver (
+  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,
+  IN OUT EFI_HANDLE                                         *DriverImageHandle
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  This              - TODO: add argument description
+  DriverImageHandle - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.c
new file mode 100644 (file)
index 0000000..729c567
--- /dev/null
@@ -0,0 +1,57 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciEnumerator.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+EFI_STATUS
+PciEnumerator (
+  IN EFI_HANDLE                    Controller
+  )
+/*++
+
+Routine Description:
+
+  This routine is used to enumerate entire pci bus system 
+  in a given platform
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  //
+  // This PCI bus driver depends on the legacy BIOS
+  // to do the resource allocation
+  //
+  gFullEnumeration = FALSE;
+
+  return PciEnumeratorLight (Controller) ;
+  
+}
+
+
+
+
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumerator.h
new file mode 100644 (file)
index 0000000..09c9d69
--- /dev/null
@@ -0,0 +1,47 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciEnumerator.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ENUMERATOR_H
+#define _EFI_PCI_ENUMERATOR_H
+
+EFI_STATUS
+PciEnumerator (
+  IN EFI_HANDLE                    Controller
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Controller  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c
new file mode 100644 (file)
index 0000000..27311fd
--- /dev/null
@@ -0,0 +1,1385 @@
+/*++
+
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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.             
+
+Module Name:
+
+  PciEnumeratorSupport.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+EFI_STATUS 
+InitializePPB (
+  IN PCI_IO_DEVICE *PciIoDevice 
+);
+
+EFI_STATUS 
+InitializeP2C (
+  IN PCI_IO_DEVICE *PciIoDevice 
+);
+
+PCI_IO_DEVICE* 
+CreatePciIoDevice (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+);
+
+
+PCI_IO_DEVICE*
+GatherP2CInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+);
+
+UINTN
+PciParseBar (
+  IN PCI_IO_DEVICE  *PciIoDevice,
+  IN UINTN          Offset,
+  IN UINTN          BarIndex
+);
+
+
+EFI_STATUS
+PciSearchDevice (
+  IN PCI_IO_DEVICE                      *Bridge,
+  PCI_TYPE00                            *Pci,
+  UINT8                                 Bus,
+  UINT8                                 Device,
+  UINT8                                 Func,
+  PCI_IO_DEVICE                         **PciDevice
+);
+
+
+EFI_STATUS 
+DetermineDeviceAttribute (
+  IN PCI_IO_DEVICE                      *PciIoDevice
+);
+
+EFI_STATUS 
+BarExisted (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINTN         Offset,
+  OUT UINT32       *BarLengthValue,
+  OUT UINT32       *OriginalBarValue
+  );
+
+
+
+EFI_DEVICE_PATH_PROTOCOL*
+CreatePciDevicePath(
+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+  IN  PCI_IO_DEVICE            *PciIoDevice 
+);
+
+PCI_IO_DEVICE* 
+GatherDeviceInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+);
+
+PCI_IO_DEVICE* 
+GatherPPBInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+);
+
+EFI_STATUS
+PciDevicePresent (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  PCI_TYPE00                          *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+  )
+/*++
+
+Routine Description:
+
+  This routine is used to check whether the pci device is present
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT64      Address;
+  EFI_STATUS  Status;
+
+  //
+  // Create PCI address map in terms of Bus, Device and Func
+  //
+  Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+  //
+  // Read the Vendor Id register
+  //
+  Status = PciRootBridgeIo->Pci.Read (
+                                  PciRootBridgeIo,
+                                  EfiPciWidthUint32,
+                                  Address,
+                                  1,
+                                  Pci
+                                  );
+
+  if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {
+
+    //
+    // Read the entire config header for the device
+    //
+
+    Status = PciRootBridgeIo->Pci.Read (
+                                    PciRootBridgeIo,
+                                    EfiPciWidthUint32,
+                                    Address,
+                                    sizeof (PCI_TYPE00) / sizeof (UINT32),
+                                    Pci
+                                    );
+
+    return EFI_SUCCESS;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+PciPciDeviceInfoCollector (
+  IN PCI_IO_DEVICE                      *Bridge,
+  UINT8                                 StartBusNumber
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS          Status;
+  PCI_TYPE00          Pci;
+  UINT8               Device;
+  UINT8               Func;
+  UINT8               SecBus;
+  PCI_IO_DEVICE       *PciIoDevice;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+
+  Status      = EFI_SUCCESS;
+  SecBus      = 0;
+  PciIoDevice = NULL;
+
+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+
+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+      //
+      // Check to see whether PCI device is present
+      //
+
+      Status = PciDevicePresent (
+                Bridge->PciRootBridgeIo,
+                &Pci,
+                (UINT8) StartBusNumber,
+                (UINT8) Device,
+                (UINT8) Func
+                );
+
+      if (EFI_ERROR (Status) && Func == 0) {
+        //
+        // go to next device if there is no Function 0
+        //
+        break;
+      }
+
+      if (!EFI_ERROR (Status)) {
+
+        //
+        // Collect all the information about the PCI device discovered
+        //
+        Status = PciSearchDevice (
+                  Bridge,
+                  &Pci,
+                  (UINT8) StartBusNumber,
+                  Device,
+                  Func,
+                  &PciIoDevice
+                  );
+
+        //
+        // Recursively scan PCI busses on the other side of PCI-PCI bridges
+        //
+        //
+
+        if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {
+
+          //
+          // If it is PPB, we need to get the secondary bus to continue the enumeration
+          //
+          PciIo   = &(PciIoDevice->PciIo);
+
+          Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);
+
+          if (EFI_ERROR (Status)) {
+            return Status;
+          }
+              
+          //
+          // If the PCI bridge is initialized then enumerate the next level bus
+          //
+          if (SecBus != 0) {
+            Status = PciPciDeviceInfoCollector (
+                      PciIoDevice,
+                      (UINT8) (SecBus)
+                      );
+          }
+        }
+
+        if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+
+          //
+          // Skip sub functions, this is not a multi function device
+          //
+          Func = PCI_MAX_FUNC;
+        }
+      }
+
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciSearchDevice (
+  IN  PCI_IO_DEVICE                         *Bridge,
+  IN  PCI_TYPE00                            *Pci,
+  IN  UINT8                                 Bus,
+  IN  UINT8                                 Device,
+  IN  UINT8                                 Func,
+  OUT PCI_IO_DEVICE                         **PciDevice
+  )
+/*++
+
+Routine Description:
+
+  Search required device.
+
+Arguments:
+
+  Bridge     - A pointer to the PCI_IO_DEVICE.
+  Pci        - A pointer to the PCI_TYPE00.
+  Bus        - Bus number.
+  Device     - Device number.
+  Func       - Function number.
+  PciDevice  - The Required pci device.
+
+Returns:
+
+  Status code.
+
+--*/
+{
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = NULL;
+
+  if (!IS_PCI_BRIDGE (Pci)) {
+
+    if (IS_CARDBUS_BRIDGE (Pci)) {
+      PciIoDevice = GatherP2CInfo (
+                      Bridge->PciRootBridgeIo,
+                      Pci,
+                      Bus,
+                      Device,
+                      Func
+                      );
+      if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {
+        InitializeP2C (PciIoDevice);
+      }
+    } else {
+
+      //
+      // Create private data for Pci Device
+      //
+      PciIoDevice = GatherDeviceInfo (
+                      Bridge->PciRootBridgeIo,
+                      Pci,
+                      Bus,
+                      Device,
+                      Func
+                      );
+
+    }
+
+  } else {
+
+    //
+    // Create private data for PPB
+    //
+    PciIoDevice = GatherPPBInfo (
+                    Bridge->PciRootBridgeIo,
+                    Pci,
+                    Bus,
+                    Device,
+                    Func
+                    );
+
+    //
+    // Special initialization for PPB including making the PPB quiet
+    //
+    if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {
+      InitializePPB (PciIoDevice);
+    }
+  }
+
+  if (!PciIoDevice) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  
+  //
+  // Create a device path for this PCI device and store it into its private data
+  //
+  CreatePciDevicePath(
+    Bridge->DevicePath,
+    PciIoDevice 
+    );
+  
+  //
+  // Detect this function has option rom
+  //
+  if (gFullEnumeration) {
+
+    if (!IS_CARDBUS_BRIDGE (Pci)) {
+
+      GetOpRomInfo (PciIoDevice);
+
+    }
+
+    ResetPowerManagementFeature (PciIoDevice);
+    
+  } 
+  else {
+    PciRomGetRomResourceFromPciOptionRomTable (
+      &gPciBusDriverBinding,
+      PciIoDevice->PciRootBridgeIo,
+      PciIoDevice
+      );
+  }
+
+  //
+  // Insert it into a global tree for future reference
+  //
+  InsertPciDevice (Bridge, PciIoDevice);
+
+  //
+  // Determine PCI device attributes
+  //
+  DetermineDeviceAttribute (PciIoDevice);
+
+  if (PciDevice != NULL) {
+    *PciDevice = PciIoDevice;
+  }
+
+  return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+GatherDeviceInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINTN                           Offset;
+  UINTN                           BarIndex;
+  PCI_IO_DEVICE                   *PciIoDevice;
+
+  PciIoDevice = CreatePciIoDevice (
+                  PciRootBridgeIo,
+                  Pci,
+                  Bus,
+                  Device,
+                  Func
+                  );
+
+  if (!PciIoDevice) {
+    return NULL;
+  }
+
+  //
+  // If it is a full enumeration, disconnect the device in advance
+  //
+  if (gFullEnumeration) {
+
+    PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);
+
+  }
+
+  //
+  // Start to parse the bars
+  //
+  for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {
+    Offset = PciParseBar (PciIoDevice, Offset, BarIndex);
+  }
+
+  return PciIoDevice;
+}
+
+PCI_IO_DEVICE *
+GatherPPBInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE                   *PciIoDevice;
+  EFI_STATUS                      Status;
+  UINT8                           Value;
+  EFI_PCI_IO_PROTOCOL             *PciIo;
+  UINT8                           Temp;
+
+  PciIoDevice = CreatePciIoDevice (
+                  PciRootBridgeIo,
+                  Pci,
+                  Bus,
+                  Device,
+                  Func
+                  );
+
+  if (!PciIoDevice) {
+    return NULL;
+  }
+  
+  if (gFullEnumeration) {
+    PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);
+
+    //
+    // Initalize the bridge control register
+    //
+    PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);
+  }
+
+  PciIo = &PciIoDevice->PciIo;
+
+  //
+  // Test whether it support 32 decode or not
+  //
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);
+
+  if (Value) {
+    if (Value & 0x01) {
+      PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;
+    } else {
+      PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;
+    }
+  }
+
+  Status = BarExisted (
+            PciIoDevice,
+            0x24,
+            NULL,
+            NULL
+            );
+
+  //
+  // test if it supports 64 memory or not
+  //
+  if (!EFI_ERROR (Status)) {
+
+    Status = BarExisted (
+              PciIoDevice,
+              0x28,
+              NULL,
+              NULL
+              );
+
+    if (!EFI_ERROR (Status)) {
+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
+    } else {
+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
+    }
+  }
+
+  //
+  // Memory 32 code is required for ppb
+  //
+  PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;
+
+  return PciIoDevice;
+}
+
+PCI_IO_DEVICE *
+GatherP2CInfo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE         *PciIoDevice;
+  
+  PciIoDevice = CreatePciIoDevice (
+                  PciRootBridgeIo,
+                  Pci,
+                  Bus,
+                  Device,
+                  Func
+                  );
+
+  if (!PciIoDevice) {
+    return NULL;
+  }
+
+  if (gFullEnumeration) {
+    PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);
+
+    //
+    // Initalize the bridge control register
+    //
+    PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);
+
+  }
+  //
+  // P2C only has one bar that is in 0x10
+  //
+  PciParseBar(PciIoDevice, 0x10, 0);
+  
+  PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED  |
+                         EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |
+                         EFI_BRIDGE_IO32_DECODE_SUPPORTED;
+
+  return PciIoDevice;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreatePciDevicePath (
+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+  IN  PCI_IO_DEVICE            *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+
+  PCI_DEVICE_PATH PciNode;
+
+  //
+  // Create PCI device path
+  //
+  PciNode.Header.Type     = HARDWARE_DEVICE_PATH;
+  PciNode.Header.SubType  = HW_PCI_DP;
+  SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
+
+  PciNode.Device          = PciIoDevice->DeviceNumber;
+  PciNode.Function        = PciIoDevice->FunctionNumber;
+  PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);
+
+  return PciIoDevice->DevicePath;
+}
+
+EFI_STATUS
+BarExisted (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINTN         Offset,
+  OUT UINT32       *BarLengthValue,
+  OUT UINT32       *OriginalBarValue
+  )
+/*++
+
+Routine Description:
+
+  Check the bar is existed or not.
+
+Arguments:
+
+  PciIoDevice       - A pointer to the PCI_IO_DEVICE.
+  Offset            - The offset.
+  BarLengthValue    - The bar length value.
+  OriginalBarValue  - The original bar value.
+
+Returns:
+
+  EFI_NOT_FOUND     - The bar don't exist.
+  EFI_SUCCESS       - The bar exist.
+
+--*/
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  UINT32              OriginalValue;
+  UINT32              Value;
+  EFI_TPL             OldTpl;
+
+  PciIo = &PciIoDevice->PciIo;
+
+  //
+  // Preserve the original value
+  //
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);
+
+  //
+  // Raise TPL to high level to disable timer interrupt while the BAR is probed
+  //
+  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);
+
+  //
+  // Write back the original value
+  //
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);
+
+  //
+  // Restore TPL to its original level
+  //
+  gBS->RestoreTPL (OldTpl);
+
+  if (BarLengthValue != NULL) {
+    *BarLengthValue = Value;
+  }
+
+  if (OriginalBarValue != NULL) {
+    *OriginalBarValue = OriginalValue;
+  }
+
+  if (Value == 0) {
+    return EFI_NOT_FOUND;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+
+EFI_STATUS
+DetermineDeviceAttribute (
+  IN PCI_IO_DEVICE                      *PciIoDevice
+  )
+/*++
+
+Routine Description:
+  Determine the related attributes of all devices under a Root Bridge
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT16          Command;
+  UINT16          BridgeControl;
+
+  Command = 0;
+
+  PciIoDevice->Supports |= EFI_PCI_DEVICE_ENABLE;
+  PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+
+  if (IS_PCI_VGA (&(PciIoDevice->Pci))){
+
+    //
+    // If the device is VGA, VGA related Attributes are supported
+    //
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY   ;
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_IO    ;
+  }
+
+  if(IS_ISA_BRIDGE(&(PciIoDevice->Pci)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice->Pci))) {
+    //
+    // If the devie is a ISA Bridge, set the two attributes
+    //
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
+  }
+
+  if (IS_PCI_GFX (&(PciIoDevice->Pci))) {
+
+    //
+    // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
+    // attribute
+    //
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO    ;
+  }
+
+
+  //
+  // If the device is IDE, IDE related attributes are supported
+  //
+  if (IS_PCI_IDE (&(PciIoDevice->Pci))) {
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO  ;
+    PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO  ;
+  }
+
+  PciReadCommandRegister(PciIoDevice, &Command);
+
+  
+  if (Command & EFI_PCI_COMMAND_IO_SPACE) {
+    PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;
+  }
+
+  if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
+    PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;
+  }
+
+  if (Command & EFI_PCI_COMMAND_BUS_MASTER) {
+    PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
+  }
+
+  if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) || 
+      IS_CARDBUS_BRIDGE (&(PciIoDevice->Pci))){
+
+    //
+    // If it is a PPB, read the Bridge Control Register to determine
+    // the relevant attributes
+    //
+    BridgeControl = 0;
+    PciReadBridgeControlRegister(PciIoDevice, &BridgeControl);
+
+    //
+    // Determine whether the ISA bit is set
+    // If ISA Enable on Bridge is set, the PPB
+    // will block forwarding 0x100-0x3ff for each 1KB in the 
+    // first 64KB I/O range.
+    //
+    if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) != 0) {
+      PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
+    } 
+
+    //
+    // Determine whether the VGA bit is set
+    // If it is set, the bridge is set to decode VGA memory range
+    // and palette register range
+    //
+    if (IS_PCI_VGA (&(PciIoDevice->Pci)) &&BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {
+      PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
+      PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
+      PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+    }
+
+    //
+    // if the palette snoop bit is set, then the brige is set to 
+    // decode palette IO write
+    //
+    if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
+      PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+    }
+  } 
+
+  return EFI_SUCCESS;
+}
+
+UINTN
+PciParseBar (
+  IN PCI_IO_DEVICE  *PciIoDevice,
+  IN UINTN          Offset,
+  IN UINTN          BarIndex
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT32      Value;
+  UINT32      OriginalValue;
+  UINT32      Mask;
+  EFI_STATUS  Status;
+
+  OriginalValue = 0;
+  Value         = 0;
+
+  Status = BarExisted (
+            PciIoDevice,
+            Offset,
+            &Value,
+            &OriginalValue
+            );
+
+  if (EFI_ERROR (Status)) {
+    PciIoDevice->PciBar[BarIndex].BaseAddress = 0;
+    PciIoDevice->PciBar[BarIndex].Length      = 0;
+    PciIoDevice->PciBar[BarIndex].Alignment   = 0;
+
+    //
+    // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
+    //
+    PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;
+    return Offset + 4;
+  }
+
+  PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;
+  if (Value & 0x01) {
+    //
+    // Device I/Os
+    //
+    Mask = 0xfffffffc;
+
+    if (Value & 0xFFFF0000) {
+      //
+      // It is a IO32 bar
+      //
+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo32;
+      PciIoDevice->PciBar[BarIndex].Length    = ((~(Value & Mask)) + 1);
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+    } else {
+      //
+      // It is a IO16 bar
+      //
+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo16;
+      PciIoDevice->PciBar[BarIndex].Length    = 0x0000FFFF & ((~(Value & Mask)) + 1);
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+    }
+    //
+    // Workaround. Some platforms inplement IO bar with 0 length
+    // Need to treat it as no-bar
+    //
+    if (PciIoDevice->PciBar[BarIndex].Length == 0) {
+      PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;
+    }
+
+    PciIoDevice->PciBar[BarIndex].Prefetchable  = FALSE;
+    PciIoDevice->PciBar[BarIndex].BaseAddress   = OriginalValue & Mask;
+
+  } else {
+
+    Mask  = 0xfffffff0;
+
+    PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;
+
+    switch (Value & 0x07) {
+
+    //
+    //memory space; anywhere in 32 bit address space
+    //
+    case 0x00:
+      if (Value & 0x08) {
+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;
+      } else {
+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;
+      }
+
+      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+      break;
+
+    //
+    // memory space; anywhere in 64 bit address space
+    //
+    case 0x04:
+      if (Value & 0x08) {
+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;
+      } else {
+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;
+      }
+
+      //
+      // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
+      // is regarded as an extension for the first bar. As a result
+      // the sizing will be conducted on combined 64 bit value
+      // Here just store the masked first 32bit value for future size
+      // calculation
+      //
+      PciIoDevice->PciBar[BarIndex].Length    = Value & Mask;
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+      //
+      // Increment the offset to point to next DWORD
+      //
+      Offset += 4;
+
+      Status = BarExisted (
+                PciIoDevice,
+                Offset,
+                &Value,
+                &OriginalValue
+                );
+
+      if (EFI_ERROR (Status)) {
+        return Offset + 4;
+      }
+
+      //
+      // Fix the length to support some spefic 64 bit BAR
+      //
+      Value |= ((UINT32)(-1) << HighBitSet32 (Value)); 
+
+      //
+      // Calculate the size of 64bit bar
+      //
+      PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);
+
+      PciIoDevice->PciBar[BarIndex].Length    = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);
+      PciIoDevice->PciBar[BarIndex].Length    = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+      break;
+
+    //
+    // reserved
+    //
+    default:
+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeUnknown;
+      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;
+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+      break;
+    }
+  }
+  
+  //
+  // Check the length again so as to keep compatible with some special bars
+  //
+  if (PciIoDevice->PciBar[BarIndex].Length == 0) {
+    PciIoDevice->PciBar[BarIndex].BarType     = PciBarTypeUnknown;
+    PciIoDevice->PciBar[BarIndex].BaseAddress = 0;
+    PciIoDevice->PciBar[BarIndex].Alignment   = 0;
+  }
+  
+  //
+  // Increment number of bar
+  //
+  return Offset + 4;
+}
+
+EFI_STATUS
+InitializePPB (
+  IN PCI_IO_DEVICE *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+
+  PciIo = &(PciIoDevice->PciIo);
+
+  //
+  // Put all the resource apertures including IO16
+  // Io32, pMem32, pMem64 to quiescent state
+  // Resource base all ones, Resource limit all zeros
+  //
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);
+
+  //
+  // don't support use io32 as for now
+  //
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeP2C (
+  IN PCI_IO_DEVICE *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+
+  PciIo = &(PciIoDevice->PciIo);
+
+  //
+  // Put all the resource apertures including IO16
+  // Io32, pMem32, pMem64 to quiescent state(
+  // Resource base all ones, Resource limit all zeros
+  //
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);
+
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);
+
+  return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+CreatePciIoDevice (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  IN PCI_TYPE00                       *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = NULL;
+
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  sizeof (PCI_IO_DEVICE),
+                  (VOID **) &PciIoDevice
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));
+
+  PciIoDevice->Signature        = PCI_IO_DEVICE_SIGNATURE;
+  PciIoDevice->Handle           = NULL;
+  PciIoDevice->PciRootBridgeIo  = PciRootBridgeIo;
+  PciIoDevice->DevicePath       = NULL;
+  PciIoDevice->BusNumber        = Bus;
+  PciIoDevice->DeviceNumber     = Device;
+  PciIoDevice->FunctionNumber   = Func;
+  PciIoDevice->Decodes          = 0;
+  if (gFullEnumeration) {
+    PciIoDevice->Allocated = FALSE;
+  } else {
+    PciIoDevice->Allocated = TRUE;
+  }
+
+  PciIoDevice->Attributes         = 0;
+  PciIoDevice->Supports           = 0;
+  PciIoDevice->BusOverride        = FALSE;
+  PciIoDevice->IsPciExp           = FALSE;
+
+  CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));
+
+  //
+  // Initialize the PCI I/O instance structure
+  //
+
+  Status  = InitializePciIoInstance (PciIoDevice);
+  Status  = InitializePciDriverOverrideInstance (PciIoDevice);
+
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (PciIoDevice);
+    return NULL;
+  }
+
+  //
+  // Initialize the reserved resource list
+  //
+  InitializeListHead (&PciIoDevice->ReservedResourceList);
+
+  //
+  // Initialize the driver list
+  //
+  InitializeListHead (&PciIoDevice->OptionRomDriverList);
+
+  //
+  // Initialize the child list
+  //
+  InitializeListHead (&PciIoDevice->ChildList);
+
+  return PciIoDevice;
+}
+
+EFI_STATUS
+PciEnumeratorLight (
+  IN EFI_HANDLE                    Controller
+  )
+/*++
+
+Routine Description:
+
+  This routine is used to enumerate entire pci bus system 
+  in a given platform
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+
+  EFI_STATUS                        Status;
+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;
+  PCI_IO_DEVICE                     *RootBridgeDev;
+  UINT16                            MinBus;
+  UINT16                            MaxBus;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+
+  MinBus      = 0;
+  MaxBus      = PCI_MAX_BUS;
+  Descriptors = NULL;
+
+  //
+  // If this host bridge has been already enumerated, then return successfully
+  //
+  if (RootBridgeExisted (Controller)) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test
+  //
+  Status = gBS->OpenProtocol (
+                  Controller      ,   
+                  &gEfiDevicePathProtocolGuid,  
+                  (VOID **)&ParentDevicePath,
+                  gPciBusDriverBinding.DriverBindingHandle,     
+                  Controller,   
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+    return Status;
+  }
+
+  //
+  // Open pci root bridge io protocol
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  (VOID **) &PciRootBridgeIo,
+                  gPciBusDriverBinding.DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+    return Status;
+  }
+
+  //
+  // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge 
+  //
+  Status = PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);
+
+  Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {
+
+    //
+    // Create a device node for root bridge device with a NULL host bridge controller handle
+    //
+    RootBridgeDev = CreateRootBridge (Controller);
+
+    //
+    // Record the root bridge device path
+    //
+    RootBridgeDev->DevicePath = ParentDevicePath;
+
+    //
+    // Record the root bridge io protocol
+    //
+    RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;
+
+    Status = PciPciDeviceInfoCollector (
+              RootBridgeDev,
+              (UINT8) MinBus
+              );
+
+    if (!EFI_ERROR (Status)) {
+
+      //
+      // If successfully, insert the node into device pool
+      //
+      InsertRootBridge (RootBridgeDev);
+    } else {
+
+      //
+      // If unsuccessly, destroy the entire node
+      //
+      DestroyRootBridge (RootBridgeDev);
+    }
+
+    Descriptors++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciGetBusRange (
+  IN     EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
+  OUT    UINT16                             *MinBus,
+  OUT    UINT16                             *MaxBus,
+  OUT    UINT16                             *BusRange
+  )
+/*++
+
+Routine Description:
+
+  Get the bus range.
+
+Arguments:
+
+  Descriptors     - A pointer to the address space descriptor.
+  MinBus          - The min bus.
+  MaxBus          - The max bus.
+  BusRange        - The bus range.
+  
+Returns:
+  
+  Status Code.
+
+--*/
+{
+
+  while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
+    if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
+      if (MinBus != NULL) {
+        *MinBus = (UINT16)(*Descriptors)->AddrRangeMin;
+      }
+
+      if (MaxBus != NULL) {
+        *MaxBus = (UINT16)(*Descriptors)->AddrRangeMax;
+      }
+
+      if (BusRange != NULL) {
+        *BusRange = (UINT16)(*Descriptors)->AddrLen;
+      }
+      return EFI_SUCCESS;
+    }
+
+    (*Descriptors)++;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.h
new file mode 100644 (file)
index 0000000..aa2aba2
--- /dev/null
@@ -0,0 +1,108 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciEnumeratorSupport.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H
+#define _EFI_PCI_ENUMERATOR_SUPPORT_H
+
+#include "PciBus.h"
+
+EFI_STATUS
+PciPciDeviceInfoCollector (
+  IN PCI_IO_DEVICE                      *Bridge,
+  UINT8                                 StartBusNumber
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Bridge          - TODO: add argument description
+  StartBusNumber  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciDevicePresent(
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  PCI_TYPE00                          *Pci,
+  UINT8                               Bus,
+  UINT8                               Device,
+  UINT8                               Func
+);
+
+EFI_STATUS
+PciEnumeratorLight (
+  IN EFI_HANDLE                    Controller
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Controller  - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciGetBusRange (
+  IN     EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
+  OUT    UINT16                             *MinBus,
+  OUT    UINT16                             *MaxBus,
+  OUT    UINT16                             *BusRange
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  Descriptors - TODO: add argument description
+  MinBus      - TODO: add argument description
+  MaxBus      - TODO: add argument description
+  BusRange    - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.c
new file mode 100644 (file)
index 0000000..bf3c1a6
--- /dev/null
@@ -0,0 +1,1852 @@
+/*++
+
+Copyright (c) 2005 - 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.             
+
+Module Name:
+
+  PciIo.c
+  
+Abstract:
+
+  PCI I/O Abstraction Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+//
+// PCI I/O Support Function Prototypes
+//
+//
+
+BOOLEAN 
+PciDevicesOnTheSamePath (
+  IN PCI_IO_DEVICE       *PciDevice1,
+  IN PCI_IO_DEVICE       *PciDevice2
+);
+
+
+EFI_STATUS 
+UpStreamBridgesAttributes (
+  IN  PCI_IO_DEVICE                            *PciIoDevice,
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,
+  IN  UINT64                                   Attributes
+);
+
+
+BOOLEAN 
+CheckBarType ( 
+  IN PCI_IO_DEVICE  *PciIoDevice,
+  UINT8             BarIndex,
+  PCI_BAR_TYPE      BarType
+);
+
+
+EFI_STATUS 
+SetBootVGA ( 
+  IN  PCI_IO_DEVICE                  *PciIoDevice
+);
+
+EFI_STATUS 
+DisableBootVGA ( 
+  IN  PCI_IO_DEVICE                  *PciIoDevice
+);
+
+
+EFI_STATUS
+PciIoVerifyBarAccess (
+  PCI_IO_DEVICE                 *PciIoDevice,
+  UINT8                         BarIndex,
+  PCI_BAR_TYPE                  Type,
+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN UINTN                      Count,
+  UINT64                        *Offset
+);
+
+EFI_STATUS
+PciIoVerifyConfigAccess (
+  PCI_IO_DEVICE                 *PciIoDevice,
+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN UINTN                      Count,
+  IN UINT64                     *Offset
+);
+
+EFI_STATUS
+EFIAPI
+PciIoPollMem (
+  IN  EFI_PCI_IO_PROTOCOL        *This,
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT8                      BarIndex,
+  IN  UINT64                     Offset,
+  IN  UINT64                     Mask,
+  IN  UINT64                     Value,
+  IN  UINT64                     Delay,
+  OUT UINT64                     *Result
+);
+  
+EFI_STATUS
+EFIAPI
+PciIoPollIo (
+  IN  EFI_PCI_IO_PROTOCOL        *This,
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT8                      BarIndex,
+  IN  UINT64                     Offset,
+  IN  UINT64                     Mask,
+  IN  UINT64                     Value,
+  IN  UINT64                     Delay,
+  OUT UINT64                     *Result
+);    
+
+EFI_STATUS
+EFIAPI
+PciIoMemRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoMemWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoIoRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoIoWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoConfigRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT32                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoConfigWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT32                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+PciIoCopyMem (
+  IN     EFI_PCI_IO_PROTOCOL  *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT8                        DestBarIndex,
+  IN     UINT64                       DestOffset,
+  IN     UINT8                        SrcBarIndex,
+  IN     UINT64                       SrcOffset,
+  IN     UINTN                        Count
+);
+
+EFI_STATUS
+EFIAPI
+PciIoMap (
+  IN     EFI_PCI_IO_PROTOCOL            *This,
+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                           *HostAddress,
+  IN OUT UINTN                          *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,
+  OUT    VOID                           **Mapping
+);
+
+EFI_STATUS
+EFIAPI
+PciIoUnmap (
+  IN  EFI_PCI_IO_PROTOCOL  *This,
+  IN  VOID                 *Mapping
+);
+
+EFI_STATUS
+EFIAPI
+PciIoAllocateBuffer (
+  IN  EFI_PCI_IO_PROTOCOL    *This,
+  IN  EFI_ALLOCATE_TYPE      Type,
+  IN  EFI_MEMORY_TYPE        MemoryType,
+  IN  UINTN                  Pages,
+  OUT VOID                   **HostAddress,
+  IN  UINT64                 Attributes
+);
+
+EFI_STATUS
+EFIAPI
+PciIoFreeBuffer (
+  IN  EFI_PCI_IO_PROTOCOL   *This,
+  IN  UINTN                 Pages,
+  IN  VOID                  *HostAddress
+  );
+
+EFI_STATUS
+EFIAPI
+PciIoFlush (
+  IN  EFI_PCI_IO_PROTOCOL  *This
+  );
+
+EFI_STATUS
+EFIAPI
+PciIoGetLocation (
+  IN  EFI_PCI_IO_PROTOCOL  *This,
+  OUT UINTN                *Segment,
+  OUT UINTN                *Bus,
+  OUT UINTN                *Device,
+  OUT UINTN                *Function
+  );
+
+EFI_STATUS
+EFIAPI
+PciIoAttributes (
+  IN  EFI_PCI_IO_PROTOCOL              *This,
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,
+  IN  UINT64                                   Attributes,
+  OUT UINT64                                   *Result   OPTIONAL
+  );
+
+EFI_STATUS
+EFIAPI
+PciIoGetBarAttributes(
+  IN  EFI_PCI_IO_PROTOCOL    *This,
+  IN  UINT8                          BarIndex,
+  OUT UINT64                         *Supports,   OPTIONAL
+  OUT VOID                           **Resources  OPTIONAL
+  );
+
+EFI_STATUS
+EFIAPI
+PciIoSetBarAttributes(
+  IN     EFI_PCI_IO_PROTOCOL  *This,
+  IN     UINT64                       Attributes,
+  IN     UINT8                        BarIndex,
+  IN OUT UINT64                       *Offset,
+  IN OUT UINT64                       *Length
+  );
+
+
+//
+// Pci Io Protocol Interface
+//
+EFI_PCI_IO_PROTOCOL  PciIoInterface = {
+  PciIoPollMem,
+  PciIoPollIo,
+  {
+    PciIoMemRead,
+    PciIoMemWrite
+  },
+  {
+    PciIoIoRead,
+    PciIoIoWrite
+  },
+  {
+    PciIoConfigRead,
+    PciIoConfigWrite
+  },
+  PciIoCopyMem,
+  PciIoMap,
+  PciIoUnmap,
+  PciIoAllocateBuffer,
+  PciIoFreeBuffer,
+  PciIoFlush,
+  PciIoGetLocation,
+  PciIoAttributes,
+  PciIoGetBarAttributes,
+  PciIoSetBarAttributes,
+  0,
+  NULL
+};
+
+
+EFI_STATUS
+InitializePciIoInstance (
+  PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  Initializes a PCI I/O Instance
+
+Arguments:
+  
+Returns:
+
+  None
+
+--*/
+
+{
+  CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoVerifyBarAccess (
+  PCI_IO_DEVICE                   *PciIoDevice,
+  UINT8                           BarIndex,
+  PCI_BAR_TYPE                    Type,
+  IN EFI_PCI_IO_PROTOCOL_WIDTH    Width,
+  IN UINTN                        Count,
+  UINT64                          *Offset
+  )
+/*++
+
+Routine Description:
+
+  Verifies access to a PCI Base Address Register (BAR)
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // BarIndex 0-5 is legal
+  //
+  if (BarIndex >= PCI_MAX_BAR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!CheckBarType (PciIoDevice, BarIndex, Type)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX
+  // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+  //
+  if (Width >= EfiPciIoWidthFifoUint8 && Width <= EfiPciIoWidthFifoUint64) {
+    Count = 1;
+  }
+
+  Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoVerifyConfigAccess (
+  PCI_IO_DEVICE                 *PciIoDevice,
+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN UINTN                      Count,
+  IN UINT64                     *Offset
+  )
+/*++
+
+Routine Description:
+
+  Verifies access to a PCI Config Header
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT64  ExtendOffset;
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX
+  // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+  //
+  Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+  if (PciIoDevice->IsPciExp) {
+    if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {
+      return EFI_UNSUPPORTED;
+    }
+
+    ExtendOffset  = LShiftU64 (*Offset, 32);
+    *Offset       = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);
+    *Offset       = (*Offset) | ExtendOffset;
+
+  } else {
+    if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {
+      return EFI_UNSUPPORTED;
+    }
+
+    *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoPollMem (
+  IN  EFI_PCI_IO_PROTOCOL        *This,
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT8                      BarIndex,
+  IN  UINT64                     Offset,
+  IN  UINT64                     Mask,
+  IN  UINT64                     Value,
+  IN  UINT64                     Delay,
+  OUT UINT64                     *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll PCI Memmory
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Width > EfiPciIoWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->PollMem (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                          Offset,
+                                          Mask,
+                                          Value,
+                                          Delay,
+                                          Result
+                                          );
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoPollIo (
+  IN  EFI_PCI_IO_PROTOCOL        *This,
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT8                      BarIndex,
+  IN  UINT64                     Offset,
+  IN  UINT64                     Mask,
+  IN  UINT64                     Value,
+  IN  UINT64                     Delay,
+  OUT UINT64                     *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll PCI IO
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width > EfiPciIoWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->PollIo (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                          Offset,
+                                          Mask,
+                                          Value,
+                                          Delay,
+                                          Result
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMemRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI Memory Read Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  if (Buffer == NULL){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Mem.Read (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Offset,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMemWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI Memory Write Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  if (Buffer == NULL){
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Mem.Write (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Offset,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoIoRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI I/O Read Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  if (Buffer == NULL){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Io.Read (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Offset,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoIoWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT8                      BarIndex,
+  IN     UINT64                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI I/O Write Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  if (Buffer == NULL){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Io.Write (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Offset,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoConfigRead (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT32                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI Configuration Read Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+  UINT64        Address;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  Address     = Offset;
+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Pci.Read (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Address,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoConfigWrite (
+  IN     EFI_PCI_IO_PROTOCOL        *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT32                     Offset,
+  IN     UINTN                      Count,
+  IN OUT VOID                       *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Performs a PCI Configuration Write Cycle
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+  UINT64        Address;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  Address     = Offset;
+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Pci.Write (
+                                              PciIoDevice->PciRootBridgeIo,
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                              Address,
+                                              Count,
+                                              Buffer
+                                              );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoCopyMem (
+  IN EFI_PCI_IO_PROTOCOL              *This,
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT8                        DestBarIndex,
+  IN     UINT64                       DestOffset,
+  IN     UINT8                        SrcBarIndex,
+  IN     UINT64                       SrcOffset,
+  IN     UINTN                        Count
+  )
+/*++
+
+Routine Description:
+
+  Copy PCI Memory
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == EfiPciIoWidthFifoUint8  ||
+      Width == EfiPciIoWidthFifoUint16 ||
+      Width == EfiPciIoWidthFifoUint32 ||
+      Width == EfiPciIoWidthFifoUint64 ||
+      Width == EfiPciIoWidthFillUint8  ||
+      Width == EfiPciIoWidthFillUint16 ||
+      Width == EfiPciIoWidthFillUint32 ||
+      Width == EfiPciIoWidthFillUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->CopyMem (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                          DestOffset,
+                                          SrcOffset,
+                                          Count
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMap (
+  IN     EFI_PCI_IO_PROTOCOL            *This,
+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                           *HostAddress,
+  IN OUT UINTN                          *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,
+  OUT    VOID                           **Mapping
+  )
+/*++
+
+Routine Description:
+
+  Maps a memory region for DMA
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if ((UINT32)Operation >= EfiPciIoOperationMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
+    Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->Map (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
+                                          HostAddress,
+                                          NumberOfBytes,
+                                          DeviceAddress,
+                                          Mapping
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoUnmap (
+  IN  EFI_PCI_IO_PROTOCOL  *This,
+  IN  VOID                 *Mapping
+  )
+/*++
+
+Routine Description:
+
+  Unmaps a memory region for DMA
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  Status = PciIoDevice->PciRootBridgeIo->Unmap (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          Mapping
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoAllocateBuffer (
+  IN  EFI_PCI_IO_PROTOCOL   *This,
+  IN  EFI_ALLOCATE_TYPE     Type,
+  IN  EFI_MEMORY_TYPE       MemoryType,
+  IN  UINTN                 Pages,
+  OUT VOID                  **HostAddress,
+  IN  UINT64                Attributes
+  )
+/*++
+
+Routine Description:
+
+  Allocates a common buffer for DMA
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+
+  if (Attributes &
+      (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
+    Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+  }
+
+  Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          Type,
+                                          MemoryType,
+                                          Pages,
+                                          HostAddress,
+                                          Attributes
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoFreeBuffer (
+  IN  EFI_PCI_IO_PROTOCOL   *This,
+  IN  UINTN                 Pages,
+  IN  VOID                  *HostAddress
+  )
+/*++
+
+Routine Description:
+
+  Frees a common buffer 
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+  
+  if( HostAddress == NULL ){
+     return EFI_INVALID_PARAMETER;
+  } 
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (
+                                          PciIoDevice->PciRootBridgeIo,
+                                          Pages,
+                                          HostAddress
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoFlush (
+  IN  EFI_PCI_IO_PROTOCOL  *This
+  )
+/*++
+
+Routine Description:
+
+  Flushes a DMA buffer
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+
+{
+  EFI_STATUS    Status;
+  UINT32         Register;
+  PCI_IO_DEVICE  *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  //
+  // If the device is behind a PCI-PCI Bridge, then perform a read cycles to the device to 
+  // flush the posted write cycles through the PCI-PCI bridges
+  //
+  if (PciIoDevice->Parent != NULL) {
+    Status = This->Pci.Read (This, EfiPciIoWidthUint32, 0, 1, &Register);
+  }
+
+  //
+  // Call the PCI Root Bridge I/O Protocol to flush the posted write cycles through the chipset
+  //
+  Status = PciIoDevice->PciRootBridgeIo->Flush (
+                                           PciIoDevice->PciRootBridgeIo
+                                           );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoGetLocation (
+  IN  EFI_PCI_IO_PROTOCOL  *This,
+  OUT UINTN                *Segment,
+  OUT UINTN                *Bus,
+  OUT UINTN                *Device,
+  OUT UINTN                *Function
+  )
+/*++
+
+Routine Description:
+
+  Gets a PCI device's current bus number, device number, and function number.
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE *PciIoDevice;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Segment  = PciIoDevice->PciRootBridgeIo->SegmentNumber;
+  *Bus      = PciIoDevice->BusNumber;
+  *Device   = PciIoDevice->DeviceNumber;
+  *Function = PciIoDevice->FunctionNumber;
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+CheckBarType (
+  IN PCI_IO_DEVICE       *PciIoDevice,
+  UINT8                  BarIndex,
+  PCI_BAR_TYPE           BarType
+  )
+/*++
+
+Routine Description:
+
+  Sets a PCI controllers attributes on a resource range
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  switch (BarType) {
+
+  case PciBarTypeMem:
+
+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32  &&
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64    ) {
+      return FALSE;
+    }
+
+    return TRUE;
+
+  case PciBarTypeIo:
+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){
+      return FALSE;
+    }
+
+    return TRUE;
+
+  default:
+    break;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoAttributes (
+  IN EFI_PCI_IO_PROTOCOL                       * This,
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,
+  IN  UINT64                                   Attributes,
+  OUT UINT64                                   *Result OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+
+  PCI_IO_DEVICE *PciIoDevice;
+  PCI_IO_DEVICE *Temp;
+  UINT64         NewAttributes;
+  UINT64         PciRootBridgeSupports;
+  UINT64         PciRootBridgeAttributes;
+  UINT64         NewPciRootBridgeAttributes;
+  UINT64         NewUpStreamBridgeAttributes;
+  UINT64         ModifiedPciRootBridgeAttributes;
+  UINT16         EnableCommand;
+  UINT16         DisableCommand;
+  UINT16         EnableBridge;
+  UINT16         DisableBridge;
+  UINT16         Command;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+  NewUpStreamBridgeAttributes = 0;
+
+  EnableCommand   = 0;
+  DisableCommand  = 0;
+  EnableBridge    = 0;
+  DisableBridge   = 0;
+
+  switch (Operation) {
+  case EfiPciIoAttributeOperationGet:
+    if (Result == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    *Result = PciIoDevice->Attributes;
+    return EFI_SUCCESS;
+
+  case EfiPciIoAttributeOperationSupported:
+    if (Result == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    *Result = PciIoDevice->Supports;
+    return EFI_SUCCESS;
+
+  case EfiPciIoAttributeOperationEnable:
+    if(Attributes & ~(PciIoDevice->Supports)) {
+      return EFI_UNSUPPORTED;
+    }
+    NewAttributes = PciIoDevice->Attributes | Attributes;
+    break;
+  case EfiPciIoAttributeOperationDisable:
+    if(Attributes & ~(PciIoDevice->Supports)) {
+      return EFI_UNSUPPORTED;
+    }
+    NewAttributes = PciIoDevice->Attributes & (~Attributes);
+    break;
+  case EfiPciIoAttributeOperationSet:
+    if(Attributes & ~(PciIoDevice->Supports)) {
+      return EFI_UNSUPPORTED;
+    }
+    NewAttributes = Attributes;
+    break;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If VGA_IO is set, then set VGA_MEMORY too.  This driver can not enable them seperately.
+  //
+  if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {
+    NewAttributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
+  }
+
+  //
+  // If VGA_MEMORY is set, then set VGA_IO too.  This driver can not enable them seperately.
+  //
+  if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY) {
+    NewAttributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
+  }
+
+  //
+  // If the attributes are already set correctly, then just return EFI_SUCCESS;
+  //
+  if ((NewAttributes ^ PciIoDevice->Attributes) == 0) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // This driver takes care of EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_MEMORY, and
+  // EFI_PCI_IO_ATTRIBUTE_BUS_MASTER.  Strip these 3 bits off the new attribute mask so
+  // a call to the PCI Root Bridge I/O Protocol can be made
+  //
+
+  if (!IS_PCI_BRIDGE(&PciIoDevice->Pci)) {
+    NewPciRootBridgeAttributes = NewAttributes & (~(EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE));
+
+    //  
+    // Get the current attributes of this PCI device's PCI Root Bridge
+    //
+    Status = PciIoDevice->PciRootBridgeIo->GetAttributes (
+                                            PciIoDevice->PciRootBridgeIo,
+                                            &PciRootBridgeSupports,
+                                            &PciRootBridgeAttributes
+                                            );
+
+    //
+    // Check to see if any of the PCI Root Bridge attributes are being modified
+    //
+    ModifiedPciRootBridgeAttributes = NewPciRootBridgeAttributes ^ PciRootBridgeAttributes;
+    if (ModifiedPciRootBridgeAttributes) {
+
+      //
+      // Check to see if the PCI Root Bridge supports modifiying the attributes that are changing
+      //
+      if ((ModifiedPciRootBridgeAttributes & PciRootBridgeSupports) != ModifiedPciRootBridgeAttributes) {
+  //     return EFI_UNSUPPORTED;
+      }
+      //
+      // Call the PCI Root Bridge to attempt to modify the attributes
+      //
+      Status = PciIoDevice->PciRootBridgeIo->SetAttributes (
+                                             PciIoDevice->PciRootBridgeIo,
+                                             NewPciRootBridgeAttributes,
+                                             NULL,
+                                             NULL
+                                             );
+      if (EFI_ERROR (Status)) {
+      //
+      // The PCI Root Bridge could not modify the attributes, so return the error.
+      //
+        return Status;
+      }
+    }
+  }
+
+
+  if (IS_PCI_BRIDGE(&PciIoDevice->Pci)) {
+
+
+    //
+    // Check to see if an VGA related attributes are being set.
+    //
+    if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)) {
+
+      if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {
+        EnableBridge  |= EFI_PCI_BRIDGE_CONTROL_VGA;
+      } else {
+        DisableBridge  |= EFI_PCI_BRIDGE_CONTROL_VGA;
+      }
+    }
+
+    //
+    // Check to see if an VGA related attributes are being set.
+    // If ISA Enable on the PPB is set, the PPB will block the
+    // 0x100-0x3FF for each 1KB block in the first 64K I/O block
+    //
+    if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO)) {
+
+      if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {
+        DisableBridge  |= EFI_PCI_BRIDGE_CONTROL_ISA;
+      } else {
+        EnableBridge  |= EFI_PCI_BRIDGE_CONTROL_ISA;
+      }
+    }
+
+    //
+    // Check to see if an VGA related attributes are being set.
+    //
+    if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {
+
+      if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {
+        EnableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+      } else {
+        DisableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+      }
+    }
+
+  } else {
+
+    if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)) {
+
+      if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {
+
+        //
+        //Check if there have been an active VGA device on the same segment
+        //
+        Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
+
+        if (Temp && Temp != PciIoDevice) {
+          return EFI_UNSUPPORTED;
+        }
+      }
+    }
+
+    if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {
+      if (IS_PCI_GFX(&PciIoDevice->Pci)) {
+
+        //
+        //Get the boot VGA on the same segement
+        //
+        Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
+
+        if (!Temp) {
+
+          //
+          // If there is no VGA device on the segement, set
+          // this graphics card to decode the palette range
+          //
+          DisableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+        } else {
+
+          //
+          // Check these two agents are on the same path
+          //
+          if (PciDevicesOnTheSamePath(Temp, PciIoDevice)) {
+
+            //
+            // Check if they are on the same bus
+            //
+            if (Temp->Parent == PciIoDevice->Parent) {
+
+              PciReadCommandRegister (Temp, &Command);
+
+              //
+              // If they are on the same bus, either one can
+              // be set to snoop, the other set to decode
+              //
+              if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
+                DisableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+              } else {
+                EnableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+              }
+            } else {
+
+              //
+              // If they are on  the same path but on the different bus
+              // The first agent is set to snoop, the second one set to
+              // decode
+              //
+              if (Temp->BusNumber > PciIoDevice->BusNumber) {
+                PciEnableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
+                DisableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+              } else {
+                PciDisableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
+                EnableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+              }
+            }
+          } else {
+
+            EnableCommand  |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+          }
+        }
+      }
+    }
+  }
+
+  //
+  // Check to see of the I/O enable is being modified
+  //
+  if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_IO)) {
+    if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) {
+      EnableCommand |= EFI_PCI_COMMAND_IO_SPACE;
+    } else {
+      DisableCommand |= EFI_PCI_COMMAND_IO_SPACE;
+    }
+  }
+
+  //
+  // Check to see of the Memory enable is being modified
+  //
+  if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)) {
+    if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {
+      EnableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;
+    } else {
+      DisableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;
+    }
+  }
+
+  //
+  // Check to see of the Bus Master enable is being modified
+  //
+  if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)) {
+    if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {
+      EnableCommand  |= EFI_PCI_COMMAND_BUS_MASTER;
+    } else {
+      DisableCommand |= EFI_PCI_COMMAND_BUS_MASTER;
+    }
+  }
+
+  Status = EFI_SUCCESS;
+  if (EnableCommand) {
+    Status = PciEnableCommandRegister(PciIoDevice, EnableCommand);
+  } 
+
+  if (DisableCommand) {
+    Status = PciDisableCommandRegister(PciIoDevice, DisableCommand);
+  }
+
+  if (EFI_ERROR(Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (EnableBridge) {
+    Status = PciEnableBridgeControlRegister(PciIoDevice, EnableBridge);
+  }
+
+  if (DisableBridge) {
+    Status = PciDisableBridgeControlRegister(PciIoDevice, DisableBridge);
+  }
+   
+  if (EFI_ERROR(Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Set the upstream bridge attributes
+  //
+  if (Operation != EfiPciIoAttributeOperationGet && Operation != EfiPciIoAttributeOperationSupported) {
+
+    //
+    // EFI_PCI_IO_ATTRIBUTE_MEMORY, EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
+    // EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED
+    // EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE will not effect to upstream bridge
+    // 
+    NewUpStreamBridgeAttributes = Attributes & \
+                                (~(EFI_PCI_IO_ATTRIBUTE_IO | \
+                                EFI_PCI_IO_ATTRIBUTE_MEMORY | \
+                                EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | \
+                                EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | \
+                                EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | \
+                                EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE));
+
+    if (NewUpStreamBridgeAttributes){
+      UpStreamBridgesAttributes(PciIoDevice, Operation, NewUpStreamBridgeAttributes);
+    }
+  }
+  
+  PciIoDevice->Attributes = NewAttributes;
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoGetBarAttributes (
+  IN EFI_PCI_IO_PROTOCOL             * This,
+  IN  UINT8                          BarIndex,
+  OUT UINT64                         *Supports, OPTIONAL
+  OUT VOID                           **Resources OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT8                             *Configuration;
+  PCI_IO_DEVICE                     *PciIoDevice;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AddressSpace;
+  EFI_ACPI_END_TAG_DESCRIPTOR       *End;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  if (Supports == NULL && Resources == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((BarIndex >= PCI_MAX_BAR) || (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // This driver does not support modifications to the WRITE_COMBINE or
+  // CACHED attributes for BAR ranges.
+  //
+  if (Supports != NULL) {
+    *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
+  }
+
+  if (Resources != NULL) {
+    Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+    if (Configuration == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    AddressSpace = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+
+    AddressSpace->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+    AddressSpace->Len          = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
+
+    AddressSpace->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;
+    AddressSpace->AddrLen      = PciIoDevice->PciBar[BarIndex].Length;
+    AddressSpace->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;
+
+    switch (PciIoDevice->PciBar[BarIndex].BarType) {
+    case PciBarTypeIo16:
+    case PciBarTypeIo32:
+      //
+      // Io
+      //
+      AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+      break;
+
+    case PciBarTypeMem32:
+      //
+      // Mem
+      //
+      AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      //
+      // 32 bit
+      //
+      AddressSpace->AddrSpaceGranularity = 32;
+      break;
+
+    case PciBarTypePMem32:
+      //
+      // Mem
+      //
+      AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      //
+      // prefechable
+      //
+      AddressSpace->SpecificFlag = 0x6;
+      //
+      // 32 bit
+      //
+      AddressSpace->AddrSpaceGranularity = 32;
+      break;
+
+    case PciBarTypeMem64:
+      //
+      // Mem
+      //
+      AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      //
+      // 64 bit
+      //
+      AddressSpace->AddrSpaceGranularity = 64;
+      break;
+
+    case PciBarTypePMem64:
+      //
+      // Mem
+      //
+      AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      //
+      // prefechable
+      //
+      AddressSpace->SpecificFlag = 0x6;
+      //
+      // 64 bit
+      //
+      AddressSpace->AddrSpaceGranularity = 64;
+      break;
+
+    default:
+      break;
+    }
+
+    //
+    // put the checksum
+    //
+    End           = (EFI_ACPI_END_TAG_DESCRIPTOR *) (AddressSpace + 1);
+    End->Desc     = ACPI_END_TAG_DESCRIPTOR;
+    End->Checksum = 0;
+
+    *Resources    = Configuration;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoSetBarAttributes (
+  IN EFI_PCI_IO_PROTOCOL              *This,
+  IN     UINT64                       Attributes,
+  IN     UINT8                        BarIndex,
+  IN OUT UINT64                       *Offset,
+  IN OUT UINT64                       *Length
+  )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS    Status;
+  PCI_IO_DEVICE *PciIoDevice;
+  UINT64        NonRelativeOffset;
+  UINT64        Supports;
+
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+  //
+  // Make sure Offset and Length are not NULL
+  //
+  if (Offset == NULL || Length == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.
+  // If Attributes is not 0, then return EFI_UNSUPPORTED.
+  //
+  Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
+
+  if (Attributes != (Attributes & Supports)) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Attributes must be supported.  Make sure the BAR range describd by BarIndex, Offset, and
+  // Length are valid for this PCI device.
+  //
+  NonRelativeOffset = *Offset;
+  Status = PciIoVerifyBarAccess (
+            PciIoDevice,
+            BarIndex,
+            PciBarTypeMem,
+            EfiPciIoWidthUint8,
+            (UINT32) *Length,
+            &NonRelativeOffset
+            );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpStreamBridgesAttributes (
+  IN  PCI_IO_DEVICE                            *PciIoDevice,
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,
+  IN  UINT64                                   Attributes
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  PCI_IO_DEVICE       *Parent;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+
+  Parent = PciIoDevice->Parent;
+
+  while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {
+
+    //
+    // Get the PciIo Protocol
+    //
+    PciIo = &Parent->PciIo;
+
+    PciIo->Attributes (PciIo, Operation, Attributes, NULL);
+
+    Parent = Parent->Parent;
+  }
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+PciDevicesOnTheSamePath (
+  IN PCI_IO_DEVICE        *PciDevice1,
+  IN PCI_IO_DEVICE        *PciDevice2
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  PciDevice1  -  The pointer to the first PCI_IO_DEVICE.
+  PciDevice2  -  The pointer to the second PCI_IO_DEVICE.
+
+Returns:
+
+  TRUE   -  The two Pci devices are on the same path.
+  FALSE  -  The two Pci devices are not on the same path.
+
+--*/
+{
+
+  if (PciDevice1->Parent == PciDevice2->Parent) {
+    return TRUE;
+  }
+
+  return (BOOLEAN) ((PciDeviceExisted (PciDevice1->Parent, PciDevice2)|| PciDeviceExisted (PciDevice2->Parent, PciDevice1)));
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciIo.h
new file mode 100644 (file)
index 0000000..b0d465a
--- /dev/null
@@ -0,0 +1,48 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciIo.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_IO_PROTOCOL_H
+#define _EFI_PCI_IO_PROTOCOL_H
+
+EFI_STATUS
+InitializePciIoInstance (
+  PCI_IO_DEVICE  *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c
new file mode 100644 (file)
index 0000000..df0ae4e
--- /dev/null
@@ -0,0 +1,557 @@
+/*++
+
+Copyright (c) 2005 - 2012, 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.             
+
+Module Name:
+
+  PciOptionRomSupport.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+
+EFI_STATUS
+RomDecode (
+  IN PCI_IO_DEVICE   *PciDevice,
+  IN UINT8           RomBarIndex,
+  IN UINT32          RomBar,
+  IN BOOLEAN         Enable
+);
+
+EFI_STATUS
+GetOpRomInfo (
+  IN PCI_IO_DEVICE    *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  UINT8                           RomBarIndex;
+  UINT32                          AllOnes;
+  UINT64                          Address;
+  EFI_STATUS                      Status;
+  UINT8                           Bus;
+  UINT8                           Device;
+  UINT8                           Function;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+  Bus             = PciIoDevice->BusNumber;
+  Device          = PciIoDevice->DeviceNumber;
+  Function        = PciIoDevice->FunctionNumber;
+
+  PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;
+
+  //
+  // offset is 0x30 if is not ppb
+  //
+
+  //
+  // 0x30
+  //
+  RomBarIndex = PCI_EXPANSION_ROM_BASE;
+
+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
+    //
+    // if is ppb
+    //
+
+    //
+    // 0x38
+    //
+    RomBarIndex = PCI_BRIDGE_ROMBAR;
+  }
+  //
+  // the bit0 is 0 to prevent the enabling of the Rom address decoder
+  //
+  AllOnes = 0xfffffffe;
+  Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);
+
+  Status = PciRootBridgeIo->Pci.Write (
+                                  PciRootBridgeIo,
+                                  EfiPciWidthUint32,
+                                  Address,
+                                  1,
+                                  &AllOnes
+                                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  //
+  // read back
+  //
+  Status = PciRootBridgeIo->Pci.Read (
+                                  PciRootBridgeIo,
+                                  EfiPciWidthUint32,
+                                  Address,
+                                  1,
+                                  &AllOnes
+                                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Bits [1, 10] are reserved
+  //
+  AllOnes &= 0xFFFFF800;
+  if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {
+    return EFI_NOT_FOUND;
+  }
+  
+  DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: OPROM detected!\n"));
+  DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: B-%x, D-%x, F-%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Function));
+
+  PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadOpRomImage (
+  IN PCI_IO_DEVICE   *PciDevice,
+  IN UINT64          ReservedMemoryBase
+  )
+/*++
+
+Routine Description:
+    Load option rom image for specified PCI device
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  UINT8                     RomBarIndex;
+  UINT8                     Indicator;
+  UINT16                    OffsetPcir;
+  UINT32                    RomBarOffset;
+  UINT32                    RomBar;
+  EFI_STATUS                retStatus;
+  BOOLEAN                   FirstCheck;
+  UINT8                     *Image;
+  PCI_EXPANSION_ROM_HEADER  *RomHeader;
+  PCI_DATA_STRUCTURE        *RomPcir;
+  UINT64                    RomSize;
+  UINT64                    RomImageSize;
+  UINT32                    LegacyImageLength;
+  UINT8                     *RomInMemory;
+  UINT8                     CodeType;
+
+  RomSize       = PciDevice->RomSize;
+
+  Indicator     = 0;
+  RomImageSize  = 0;
+  RomInMemory   = NULL;
+  CodeType      = 0xFF;
+
+  //
+  // Get the RomBarIndex
+  //
+
+  //
+  // 0x30
+  //
+  RomBarIndex = PCI_EXPANSION_ROM_BASE;
+  if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {
+    //
+    // if is ppb
+    //
+
+    //
+    // 0x38
+    //
+    RomBarIndex = PCI_BRIDGE_ROMBAR;
+  }
+  //
+  // Allocate memory for Rom header and PCIR
+  //
+  RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));
+  if (RomHeader == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));
+  if (RomPcir == NULL) {
+    gBS->FreePool (RomHeader);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  RomBar = (UINT32)ReservedMemoryBase;  
+
+  //
+  // Enable RomBar
+  //
+  RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);
+
+  RomBarOffset  = RomBar;
+  retStatus     = EFI_NOT_FOUND;
+  FirstCheck    = TRUE;
+  LegacyImageLength = 0;
+
+  do {
+    PciDevice->PciRootBridgeIo->Mem.Read (
+                                      PciDevice->PciRootBridgeIo,
+                                      EfiPciWidthUint8,
+                                      RomBarOffset,
+                                      sizeof (PCI_EXPANSION_ROM_HEADER),
+                                      (UINT8 *) RomHeader
+                                      );
+
+    if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+      RomBarOffset = RomBarOffset + 512;
+      if (FirstCheck) {
+        break;
+      } else {
+        RomImageSize = RomImageSize + 512;
+        continue;
+      }
+    }
+
+    FirstCheck  = FALSE;
+    OffsetPcir  = RomHeader->PcirOffset;
+    //
+    // If the pointer to the PCI Data Structure is invalid, no further images can be located. 
+    // The PCI Data Structure must be DWORD aligned. 
+    //
+    if (OffsetPcir == 0 ||
+       (OffsetPcir & 3) != 0 ||
+       RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > RomSize) {
+      break;
+    }
+    PciDevice->PciRootBridgeIo->Mem.Read (
+                                      PciDevice->PciRootBridgeIo,
+                                      EfiPciWidthUint8,
+                                      RomBarOffset + OffsetPcir,
+                                      sizeof (PCI_DATA_STRUCTURE),
+                                      (UINT8 *) RomPcir
+                                      );
+    //
+    // If a valid signature is not present in the PCI Data Structure, no further images can be located.
+    //
+    if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+      break;
+    }
+    if (RomImageSize + RomPcir->ImageLength * 512 > RomSize) {
+      break;
+    }
+    if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
+      CodeType = PCI_CODE_TYPE_PCAT_IMAGE;
+      LegacyImageLength = ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512) * 512;
+    }
+    Indicator     = RomPcir->Indicator;
+    RomImageSize  = RomImageSize + RomPcir->ImageLength * 512;
+    RomBarOffset  = RomBarOffset + RomPcir->ImageLength * 512;
+  } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));
+
+  //
+  // Some Legacy Cards do not report the correct ImageLength so used the maximum
+  // of the legacy length and the PCIR Image Length
+  //
+  if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
+    RomImageSize = MAX (RomImageSize, LegacyImageLength);
+  }
+
+  if (RomImageSize > 0) {
+    retStatus = EFI_SUCCESS;
+    Image     = AllocatePool ((UINT32) RomImageSize);
+    if (Image == NULL) {
+      RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
+      gBS->FreePool (RomHeader);
+      gBS->FreePool (RomPcir);
+      return EFI_OUT_OF_RESOURCES;
+    }
+    
+    //
+    // Copy Rom image into memory
+    //
+    PciDevice->PciRootBridgeIo->Mem.Read (
+                                      PciDevice->PciRootBridgeIo,
+                                      EfiPciWidthUint8,
+                                      RomBar,
+                                      (UINT32) RomImageSize,
+                                      Image
+                                      );
+    RomInMemory = Image;
+  }
+
+  RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
+
+  PciDevice->PciIo.RomSize  = RomImageSize;
+  PciDevice->PciIo.RomImage = RomInMemory;
+
+  //
+  // Free allocated memory
+  //
+  gBS->FreePool (RomHeader);
+  gBS->FreePool (RomPcir);
+
+  return retStatus;
+}
+
+EFI_STATUS
+RomDecode (
+  IN PCI_IO_DEVICE   *PciDevice,
+  IN UINT8           RomBarIndex,
+  IN UINT32          RomBar,
+  IN BOOLEAN         Enable
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  UINT16                          CommandValue;
+  UINT32                          Value32;
+  UINT64                          Address;
+  //EFI_STATUS                      Status;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+  
+  PciRootBridgeIo = PciDevice->PciRootBridgeIo;
+  if (Enable) {
+    Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);
+    //
+    // set the Rom base address: now is hardcode
+    //
+    PciRootBridgeIo->Pci.Write(
+                               PciRootBridgeIo, 
+                               EfiPciWidthUint32, 
+                               Address, 
+                               1, 
+                               &RomBar);
+  
+    //
+    // enable its decoder
+    //
+    Value32 = RomBar | 0x1;
+    PciRootBridgeIo->Pci.Write(
+                               PciRootBridgeIo, 
+                               EfiPciWidthUint32, 
+                               Address, 
+                               1, 
+                               &Value32);
+    
+    //
+    //setting the memory space bit in the function's command register
+    //
+    Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, 0x04);
+    PciRootBridgeIo->Pci.Read(
+                              PciRootBridgeIo, 
+                              EfiPciWidthUint16, 
+                              Address, 
+                              1, 
+                              &CommandValue);
+    
+    CommandValue = (UINT16)(CommandValue | 0x0002); //0x0003
+    PciRootBridgeIo->Pci.Write(
+                               PciRootBridgeIo, 
+                               EfiPciWidthUint16, 
+                               Address, 
+                               1, 
+                               &CommandValue);
+  } else {
+    //
+    // disable rom decode
+    //  
+    Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);
+    Value32 = 0xfffffffe;
+    PciRootBridgeIo->Pci.Write(
+                               PciRootBridgeIo, 
+                               EfiPciWidthUint32, 
+                               Address, 
+                               1, 
+                               &Value32);
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+ProcessOpRomImage (
+  PCI_IO_DEVICE   *PciDevice
+  )
+/*++
+
+Routine Description:
+
+  Process the oprom image.
+  
+Arguments:
+  PciDevice       A pointer to a pci device.
+
+Returns:
+
+  EFI Status.
+  
+--*/
+{
+  UINT8                         Indicator;
+  UINT32                        ImageSize;
+  UINT16                        ImageOffset;
+  VOID                          *RomBar;
+  UINT8                         *RomBarOffset;
+  EFI_HANDLE                    ImageHandle;
+  EFI_STATUS                    Status;
+  EFI_STATUS                    retStatus;
+  BOOLEAN                       SkipImage;
+  UINT32                        DestinationSize;
+  UINT32                        ScratchSize;
+  UINT8                         *Scratch;
+  VOID                          *ImageBuffer;
+  VOID                          *DecompressedImageBuffer;
+  UINT32                        ImageLength;
+  EFI_DECOMPRESS_PROTOCOL       *Decompress;
+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;
+  PCI_DATA_STRUCTURE            *Pcir;
+  UINT32                        InitializationSize;
+
+  Indicator = 0;
+
+  //
+  // Get the Address of the Rom image
+  //
+  RomBar        = PciDevice->PciIo.RomImage;
+  RomBarOffset  = (UINT8 *) RomBar;
+  retStatus     = EFI_NOT_FOUND;
+
+  if (RomBarOffset == NULL) {
+    return retStatus;
+  }
+  ASSERT (((EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset)->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE);
+
+  do {
+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;
+    if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+      RomBarOffset = RomBarOffset + 512;
+      continue;
+    }
+
+    Pcir        = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);
+    ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE);
+    ImageSize   = (UINT32) (Pcir->ImageLength * 512);
+    Indicator   = Pcir->Indicator;
+
+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
+        ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
+         (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {
+
+      ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;
+      InitializationSize      = EfiRomHeader->InitializationSize * 512;
+
+      if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {
+
+        ImageBuffer             = (VOID *) (RomBarOffset + ImageOffset);
+        ImageLength             =  InitializationSize - (UINT32)ImageOffset;
+        DecompressedImageBuffer = NULL;
+
+        //
+        // decompress here if needed
+        //
+        SkipImage = FALSE;
+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+          SkipImage = TRUE;
+        }
+
+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
+          if (EFI_ERROR (Status)) {
+            SkipImage = TRUE;
+          } else {
+            SkipImage = TRUE;
+            Status = Decompress->GetInfo (
+                                  Decompress,
+                                  ImageBuffer,
+                                  ImageLength,
+                                  &DestinationSize,
+                                  &ScratchSize
+                                  );
+            if (!EFI_ERROR (Status)) {
+              DecompressedImageBuffer = NULL;
+              DecompressedImageBuffer = AllocatePool (DestinationSize);
+              if (DecompressedImageBuffer != NULL) {
+                Scratch = AllocatePool (ScratchSize);
+                if (Scratch != NULL) {
+                  Status = Decompress->Decompress (
+                                        Decompress,
+                                        ImageBuffer,
+                                        ImageLength,
+                                        DecompressedImageBuffer,
+                                        DestinationSize,
+                                        Scratch,
+                                        ScratchSize
+                                        );
+                  if (!EFI_ERROR (Status)) {
+                    ImageBuffer = DecompressedImageBuffer;
+                    ImageLength = DestinationSize;
+                    SkipImage   = FALSE;
+                  }
+
+                  gBS->FreePool (Scratch);
+                }
+              }
+            }
+          }
+        }
+
+        if (!SkipImage) {
+          //
+          // load image and start image
+          //
+          Status = gBS->LoadImage (
+                          FALSE,
+                          gPciBusDriverBinding.DriverBindingHandle,
+                          NULL,
+                          ImageBuffer,
+                          ImageLength,
+                          &ImageHandle
+                          );
+          if (!EFI_ERROR (Status)) {
+            Status = gBS->StartImage (ImageHandle, NULL, NULL);
+            if (!EFI_ERROR (Status)) {
+              AddDriver (PciDevice, ImageHandle);
+              retStatus = EFI_SUCCESS;
+            }
+          }
+        }
+
+        RomBarOffset = RomBarOffset + ImageSize;
+      } else {
+        RomBarOffset = RomBarOffset + ImageSize;
+      }
+    } else {
+      RomBarOffset = RomBarOffset + ImageSize;
+    }
+
+  } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));
+
+  return retStatus;
+
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciOptionRomSupport.h
new file mode 100644 (file)
index 0000000..60c4989
--- /dev/null
@@ -0,0 +1,92 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciOptionRomSupport.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_OP_ROM_SUPPORT_H
+#define _EFI_PCI_OP_ROM_SUPPORT_H
+
+EFI_STATUS
+GetOpRomInfo (
+  IN PCI_IO_DEVICE    *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+LoadOpRomImage (
+  IN PCI_IO_DEVICE   *PciDevice,
+  IN UINT64          ReservedMemoryBase
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciDevice - TODO: add argument description
+  RomBase   - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProcessOpRomImage (
+  PCI_IO_DEVICE   *PciDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.c
new file mode 100644 (file)
index 0000000..0e239ce
--- /dev/null
@@ -0,0 +1,100 @@
+/*++
+
+Copyright (c) 2005 - 2012, 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.             
+
+Module Name:
+
+  PciPowerManagement.c
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+EFI_STATUS
+EFIAPI
+ResetPowerManagementFeature (
+  IN PCI_IO_DEVICE *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  This function is intended to turn off PWE assertion and
+  put the device to D0 state if the device supports
+  PCI Power Management.
+
+Arguments:
+
+Returns:
+  
+  None
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT8       PowerManagementRegBlock;
+  UINT16      PowerManagementCSR;
+
+  PowerManagementRegBlock = 0;
+
+  Status = LocateCapabilityRegBlock (
+            PciIoDevice,
+            EFI_PCI_CAPABILITY_ID_PMI,
+            &PowerManagementRegBlock,
+            NULL
+            );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Turn off the PWE assertion and put the device into D0 State
+  //
+
+  //
+  // Read PMCSR
+  //
+  Status = PciIoDevice->PciIo.Pci.Read (
+                                    &PciIoDevice->PciIo,
+                                    EfiPciIoWidthUint16,
+                                    PowerManagementRegBlock + 4,
+                                    1,
+                                    &PowerManagementCSR
+                                    );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Clear PME_Status bit
+    //
+    PowerManagementCSR |= BIT15;
+    //
+    // Clear PME_En bit. PowerState = D0.
+    //
+    PowerManagementCSR &= ~(BIT8 | BIT1 | BIT0);
+
+    //
+    // Write PMCSR
+    //
+    Status = PciIoDevice->PciIo.Pci.Write (
+                                      &PciIoDevice->PciIo,
+                                      EfiPciIoWidthUint16,
+                                      PowerManagementRegBlock + 4,
+                                      1,
+                                      &PowerManagementCSR
+                                      );
+  }
+  return Status;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciPowerManagement.h
new file mode 100644 (file)
index 0000000..98738b3
--- /dev/null
@@ -0,0 +1,49 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciPowerManagement.h
+  
+Abstract:
+
+  PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_POWER_MANAGEMENT_H
+#define _EFI_PCI_POWER_MANAGEMENT_H
+
+EFI_STATUS
+EFIAPI
+ResetPowerManagementFeature (
+  IN PCI_IO_DEVICE *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  PciIoDevice - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.c b/CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.c
new file mode 100644 (file)
index 0000000..5123b0f
--- /dev/null
@@ -0,0 +1,393 @@
+/*++
+
+Copyright (c) 2005 - 2012, 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.             
+
+Module Name:
+
+  PciRomTable.c
+  
+Abstract:
+
+  Option Rom Support for PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+typedef struct {
+  EFI_HANDLE  ImageHandle;
+  UINTN       Seg;
+  UINT8       Bus;
+  UINT8       Dev;
+  UINT8       Func;
+} EFI_PCI_ROM_IMAGE_MAPPING;
+
+UINTN                      mNumberOfPciRomImages     = 0;
+UINTN                      mMaxNumberOfPciRomImages  = 0;
+EFI_PCI_ROM_IMAGE_MAPPING  *mRomImageTable           = NULL;
+
+CHAR16 mHexDigit[17] = L"0123456789ABCDEF";
+
+VOID
+PciRomAddImageMapping (
+  IN EFI_HANDLE  ImageHandle,
+  IN UINTN       Seg,
+  IN UINT8       Bus,
+  IN UINT8       Dev,
+  IN UINT8       Func
+  )
+
+{
+  EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;
+
+  if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {
+
+    mMaxNumberOfPciRomImages += 0x20;
+
+    TempMapping = NULL;
+    TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
+    if (TempMapping == NULL) {
+      return ;
+    }
+
+    CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
+
+    if (mRomImageTable != NULL) {
+      gBS->FreePool (mRomImageTable);
+    }
+
+    mRomImageTable = TempMapping;
+  }
+
+  mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;
+  mRomImageTable[mNumberOfPciRomImages].Seg         = Seg;
+  mRomImageTable[mNumberOfPciRomImages].Bus         = Bus;
+  mRomImageTable[mNumberOfPciRomImages].Dev         = Dev;
+  mRomImageTable[mNumberOfPciRomImages].Func        = Func;
+  mNumberOfPciRomImages++;
+}
+
+VOID
+HexToString (
+  CHAR16  *String,
+  UINTN   Value,
+  UINTN   Digits
+  )
+
+{
+  for (; Digits > 0; Digits--, String++) {
+    *String = mHexDigit[((Value >> (4*(Digits-1))) & 0x0f)];
+  }
+}
+
+EFI_STATUS
+PciRomLoadEfiDriversFromRomImage (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_PCI_OPTION_ROM_DESCRIPTOR  *PciOptionRomDescriptor
+  )
+/*++
+
+Routine Description:
+  Command entry point. 
+
+Arguments:
+  ImageHandle     The image handle. 
+  SystemTable     The system table.
+
+Returns:
+  EFI_SUCCESS             - The command completed successfully
+  EFI_INVALID_PARAMETER   - Command usage error
+  EFI_UNSUPPORTED         - Protocols unsupported
+  EFI_OUT_OF_RESOURCES    - Out of memory
+  Other value             - Unknown error
+
+--*/
+{
+  VOID                          *RomBar;
+  UINTN                         RomSize;
+  CHAR16                        *FileName;
+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;
+  PCI_DATA_STRUCTURE            *Pcir;
+  UINTN                         ImageIndex;
+  UINTN                         RomBarOffset;
+  UINT32                        ImageSize;
+  UINT16                        ImageOffset;
+  EFI_HANDLE                    ImageHandle;
+  EFI_STATUS                    Status;
+  EFI_STATUS                    retStatus;
+  EFI_DEVICE_PATH_PROTOCOL      *FilePath;
+  BOOLEAN                       SkipImage;
+  UINT32                        DestinationSize;
+  UINT32                        ScratchSize;
+  UINT8                         *Scratch;
+  VOID                          *ImageBuffer;
+  VOID                          *DecompressedImageBuffer;
+  UINT32                        ImageLength;
+  EFI_DECOMPRESS_PROTOCOL       *Decompress;
+  UINT32                        InitializationSize;
+
+  RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
+  RomSize = (UINTN) PciOptionRomDescriptor->RomLength;
+  FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";
+
+  HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);
+  HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);
+  HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);
+  HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);
+
+  ImageIndex    = 0;
+  retStatus     = EFI_NOT_FOUND;
+  RomBarOffset  = (UINTN) RomBar;
+
+  do {
+
+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;
+
+
+    if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+      return retStatus;
+    }
+
+    //
+    // If the pointer to the PCI Data Structure is invalid, no further images can be located. 
+    // The PCI Data Structure must be DWORD aligned. 
+    //
+    if (EfiRomHeader->PcirOffset == 0 ||
+        (EfiRomHeader->PcirOffset & 3) != 0 ||
+        RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) {
+      break;
+    }
+    Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);
+    //
+    // If a valid signature is not present in the PCI Data Structure, no further images can be located.
+    //
+    if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+      break;
+    }
+    ImageSize = Pcir->ImageLength * 512;
+    if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {
+      break;
+    }
+
+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
+        ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
+         (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {
+
+      ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;
+      InitializationSize      = EfiRomHeader->InitializationSize * 512;
+
+      if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {
+
+        ImageBuffer             = (VOID *) (UINTN) (RomBarOffset + ImageOffset);
+        ImageLength             = InitializationSize - ImageOffset;
+        DecompressedImageBuffer = NULL;
+
+        //
+        // decompress here if needed
+        //
+        SkipImage = FALSE;
+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+          SkipImage = TRUE;
+        }
+
+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
+          if (EFI_ERROR (Status)) {
+            SkipImage = TRUE;
+          } else {
+            SkipImage = TRUE;
+            Status = Decompress->GetInfo (
+                                  Decompress,
+                                  ImageBuffer,
+                                  ImageLength,
+                                  &DestinationSize,
+                                  &ScratchSize
+                                  );
+            if (!EFI_ERROR (Status)) {
+              DecompressedImageBuffer = NULL;
+              DecompressedImageBuffer = AllocatePool (DestinationSize);
+              if (DecompressedImageBuffer != NULL) {
+                Scratch = AllocatePool (ScratchSize);
+                if (Scratch != NULL) {
+                  Status = Decompress->Decompress (
+                                        Decompress,
+                                        ImageBuffer,
+                                        ImageLength,
+                                        DecompressedImageBuffer,
+                                        DestinationSize,
+                                        Scratch,
+                                        ScratchSize
+                                        );
+                  if (!EFI_ERROR (Status)) {
+                    ImageBuffer = DecompressedImageBuffer;
+                    ImageLength = DestinationSize;
+                    SkipImage   = FALSE;
+                  }
+
+                  gBS->FreePool (Scratch);
+                }
+              }
+            }
+          }
+        }
+
+        if (!SkipImage) {
+
+          //
+          // load image and start image
+          //
+
+          HexToString (&FileName[48], ImageIndex, 4);
+          FilePath = FileDevicePath (NULL, FileName);
+
+          Status = gBS->LoadImage (
+                          FALSE,
+                          This->ImageHandle,
+                          FilePath,
+                          ImageBuffer,
+                          ImageLength,
+                          &ImageHandle
+                          );
+          if (!EFI_ERROR (Status)) {
+            Status = gBS->StartImage (ImageHandle, NULL, NULL);
+            if (!EFI_ERROR (Status)) {
+              PciRomAddImageMapping (
+                ImageHandle,
+                PciOptionRomDescriptor->Seg,
+                PciOptionRomDescriptor->Bus,
+                PciOptionRomDescriptor->Dev,
+                PciOptionRomDescriptor->Func
+                );
+              retStatus = Status;
+            }
+          }
+          if (FilePath != NULL) {
+            gBS->FreePool (FilePath);
+          }
+        }
+
+        if (DecompressedImageBuffer != NULL) {
+          gBS->FreePool (DecompressedImageBuffer);
+        }
+
+      }
+    }
+
+    RomBarOffset = RomBarOffset + ImageSize;
+    ImageIndex++;
+  } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));
+
+  return retStatus;
+}
+
+EFI_STATUS
+PciRomLoadEfiDriversFromOptionRomTable (
+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  EFI_STATUS                        Status;
+  EFI_PCI_OPTION_ROM_TABLE          *PciOptionRomTable;
+  EFI_PCI_OPTION_ROM_DESCRIPTOR     *PciOptionRomDescriptor;
+  UINTN                             Index;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+  UINT16                            MinBus;
+  UINT16                            MaxBus;
+
+  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = EFI_NOT_FOUND;
+
+  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
+    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
+    if (!PciOptionRomDescriptor->DontLoadEfiRom) {
+      if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {
+        Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+        PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);
+        if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {
+          Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);
+          PciOptionRomDescriptor->DontLoadEfiRom |= 2;
+        }
+      }
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+PciRomGetRomResourceFromPciOptionRomTable (
+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  PCI_IO_DEVICE                       *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  EFI_STATUS                    Status;
+  EFI_PCI_OPTION_ROM_TABLE      *PciOptionRomTable;
+  EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
+  UINTN                         Index;
+
+  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
+    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
+    if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&
+        PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber         &&
+        PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber      &&
+        PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {
+
+      PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
+      PciIoDevice->PciIo.RomSize  = (UINTN) PciOptionRomDescriptor->RomLength;
+    }
+  }
+
+  for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
+    if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&
+        mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&
+        mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&
+        mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {
+
+      AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.h b/CorebootModulePkg/PciBusNoEnumerationDxe/PciRomTable.h
new file mode 100644 (file)
index 0000000..773fe80
--- /dev/null
@@ -0,0 +1,58 @@
+/*++
+
+Copyright (c) 2005 - 2006, 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.             
+
+Module Name:
+
+  PciRomTable.h
+  
+Abstract:
+
+  Option Rom Support for PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ROM_TABLE_H
+#define _EFI_PCI_ROM_TABLE_H
+
+
+EFI_STATUS
+PciRomLoadEfiDriversFromOptionRomTable (
+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo
+  );
+
+EFI_STATUS
+PciRomGetRomResourceFromPciOptionRomTable (
+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
+  PCI_IO_DEVICE                       *PciIoDevice
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  This            - TODO: add argument description
+  PciRootBridgeIo - TODO: add argument description
+  PciIoDevice     - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+;
+#endif
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
new file mode 100644 (file)
index 0000000..e924b44
--- /dev/null
@@ -0,0 +1,845 @@
+/*++
+
+Copyright (c) 2006 - 2012, 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.             
+
+Module Name:
+
+    DeviceIo.c
+    
+Abstract:
+
+    EFI PC-AT PCI Device IO driver
+
+--*/
+#include "PcatPciRootBridge.h"
+#include "DeviceIo.h"
+
+EFI_STATUS
+DeviceIoConstructor (
+  IN EFI_HANDLE                      Handle,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+  IN EFI_DEVICE_PATH_PROTOCOL        *DevicePath,
+  IN UINT16                          PrimaryBus,
+  IN UINT16                          SubordinateBus
+  )
+/*++
+
+Routine Description:
+  
+  Initialize and install a Device IO protocol on a empty device path handle.
+
+Arguments:
+  
+  Handle               - Handle of PCI RootBridge IO instance
+  PciRootBridgeIo      - PCI RootBridge IO instance
+  DevicePath           - Device Path of PCI RootBridge IO instance
+  PrimaryBus           - Primary Bus
+  SubordinateBus       - Subordinate Bus
+
+Returns:
+  
+  EFI_SUCCESS          -  This driver is added to ControllerHandle.  
+  EFI_ALREADY_STARTED  -  This driver is already running on ControllerHandle.   
+  Others               -  This driver does not support this device.
+
+--*/
+{
+  EFI_STATUS                      Status;
+  DEVICE_IO_PRIVATE_DATA          *Private;
+
+  //
+  // Initialize the Device IO device instance.
+  //
+  Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA));
+  if (Private == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Private->Signature                = DEVICE_IO_PRIVATE_DATA_SIGNATURE;
+  Private->Handle                   = Handle;
+  Private->PciRootBridgeIo          = PciRootBridgeIo;
+  Private->DevicePath               = DevicePath;
+  Private->PrimaryBus               = PrimaryBus;
+  Private->SubordinateBus           = SubordinateBus;
+
+  Private->DeviceIo.Mem.Read        = DeviceIoMemRead;
+  Private->DeviceIo.Mem.Write       = DeviceIoMemWrite;
+  Private->DeviceIo.Io.Read         = DeviceIoIoRead;
+  Private->DeviceIo.Io.Write        = DeviceIoIoWrite;
+  Private->DeviceIo.Pci.Read        = DeviceIoPciRead;
+  Private->DeviceIo.Pci.Write       = DeviceIoPciWrite;
+  Private->DeviceIo.PciDevicePath   = DeviceIoPciDevicePath;
+  Private->DeviceIo.Map             = DeviceIoMap;
+  Private->DeviceIo.Unmap           = DeviceIoUnmap;
+  Private->DeviceIo.AllocateBuffer  = DeviceIoAllocateBuffer;
+  Private->DeviceIo.Flush           = DeviceIoFlush;
+  Private->DeviceIo.FreeBuffer      = DeviceIoFreeBuffer;
+
+  //
+  // Install protocol interfaces for the Device IO device.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Private->Handle,
+                  &gEfiDeviceIoProtocolGuid,
+                  &Private->DeviceIo,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoMemRead (
+  IN     EFI_DEVICE_IO_PROTOCOL   *This,
+  IN     EFI_IO_WIDTH             Width,
+  IN     UINT64                   Address,
+  IN     UINTN                    Count,
+  IN OUT VOID                     *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading memory mapped I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations.  
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.           
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.  
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if (Width > MMIO_COPY_UINT64) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Width >= MMIO_COPY_UINT8) {
+    Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
+    Status = Private->PciRootBridgeIo->CopyMem (
+                                         Private->PciRootBridgeIo,
+                                         (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                         (UINT64)(UINTN) Buffer,
+                                         Address,
+                                         Count
+                                         );
+  } else {
+    Status = Private->PciRootBridgeIo->Mem.Read (
+                                             Private->PciRootBridgeIo,
+                                             (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                             Address,
+                                             Count,
+                                             Buffer
+                                             );
+  }
+
+  return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DeviceIoMemWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL    *This,
+  IN     EFI_IO_WIDTH              Width,
+  IN     UINT64                    Address,
+  IN     UINTN                     Count,
+  IN OUT VOID                      *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing memory mapped I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.  
+  Address  -  The base address of I/O operations.   
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.            
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if (Width > MMIO_COPY_UINT64) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Width >= MMIO_COPY_UINT8) {
+    Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
+    Status = Private->PciRootBridgeIo->CopyMem (
+                                         Private->PciRootBridgeIo,
+                                         (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                         Address,
+                                         (UINT64)(UINTN) Buffer,
+                                         Count
+                                         );
+  } else {
+    Status = Private->PciRootBridgeIo->Mem.Write (
+                                             Private->PciRootBridgeIo,
+                                             (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                             Address,
+                                             Count,
+                                             Buffer
+                                             );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoIoRead (
+  IN     EFI_DEVICE_IO_PROTOCOL   *This,
+  IN     EFI_IO_WIDTH             Width,
+  IN     UINT64                   Address,
+  IN     UINTN                    Count,
+  IN OUT VOID                     *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.          
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if (Width >= MMIO_COPY_UINT8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Private->PciRootBridgeIo->Io.Read (
+                                          Private->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                          Address,
+                                          Count,
+                                          Buffer
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoIoWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL    *This,
+  IN     EFI_IO_WIDTH              Width,
+  IN     UINT64                    Address,
+  IN     UINTN                     Count,
+  IN OUT VOID                      *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations.
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.        
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if (Width >= MMIO_COPY_UINT8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Private->PciRootBridgeIo->Io.Write (
+                                          Private->PciRootBridgeIo,
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                          Address,
+                                          Count,
+                                          Buffer
+                                          );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciRead (
+  IN     EFI_DEVICE_IO_PROTOCOL   *This,
+  IN     EFI_IO_WIDTH             Width,
+  IN     UINT64                   Address,
+  IN     UINTN                    Count,
+  IN OUT VOID                     *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading PCI configuration space of device
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations. 
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.           
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if ((UINT32)Width >= MMIO_COPY_UINT8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Private->PciRootBridgeIo->Pci.Read (
+                                           Private->PciRootBridgeIo,
+                                           (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                           Address,
+                                           Count,
+                                           Buffer
+                                           );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL    *This,
+  IN     EFI_IO_WIDTH              Width,
+  IN     UINT64                    Address,
+  IN     UINTN                     Count,
+  IN OUT VOID                      *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing PCI configuration space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.   
+  Width    -  Width of I/O operations. 
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.         
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if ((UINT32)Width >= MMIO_COPY_UINT8) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Private->PciRootBridgeIo->Pci.Write (
+                                           Private->PciRootBridgeIo,
+                                           (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+                                           Address,
+                                           Count,
+                                           Buffer
+                                           );
+
+  return Status;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendPciDevicePath (
+  IN     DEVICE_IO_PRIVATE_DATA    *Private,
+  IN     UINT8                     Bus,
+  IN     UINT8                     Device,
+  IN     UINT8                     Function,
+  IN     EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
+  IN OUT UINT16                    *BridgePrimaryBus,
+  IN OUT UINT16                    *BridgeSubordinateBus
+  )
+/*++
+
+Routine Description:
+  
+  Append a PCI device path node to another device path.
+
+Arguments:
+  
+  Private               -  A pointer to DEVICE_IO_PRIVATE_DATA instance.  
+  Bus                   -  PCI bus number of the device.
+  Device                -  PCI device number of the device.
+  Function              -  PCI function number of the device.
+  DevicePath            -  Original device path which will be appended a PCI device path node.
+  BridgePrimaryBus      -  Primary bus number of the bridge.
+  BridgeSubordinateBus  -  Subordinate bus number of the bridge.
+
+Returns:
+  
+  Pointer to the appended PCI device path.
+
+--*/
+{
+  UINT16                    ThisBus;
+  UINT8                     ThisDevice;
+  UINT8                     ThisFunc;
+  UINT64                    Address;
+  PCI_TYPE01                PciBridge;
+  PCI_TYPE01                *PciPtr;
+  EFI_DEVICE_PATH_PROTOCOL  *ReturnDevicePath;
+  PCI_DEVICE_PATH           PciNode;
+
+  PciPtr = &PciBridge;
+  for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {
+    for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {
+      for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {
+        Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);
+        ZeroMem (PciPtr, sizeof (PCI_TYPE01));
+        Private->DeviceIo.Pci.Read (
+                                &Private->DeviceIo,
+                                IO_UINT32,
+                                Address,
+                                1,
+                                &(PciPtr->Hdr.VendorId)
+                                );
+        if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {
+          break;
+        }
+        if (PciPtr->Hdr.VendorId == 0xffff) {
+          continue;
+        }
+
+        Private->DeviceIo.Pci.Read (
+                                &Private->DeviceIo,
+                                IO_UINT32,
+                                Address,
+                                sizeof (PCI_TYPE01) / sizeof (UINT32),
+                                PciPtr
+                                );
+        if (IS_PCI_BRIDGE (PciPtr)) {
+          if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {
+
+            PciNode.Header.Type     = HARDWARE_DEVICE_PATH;
+            PciNode.Header.SubType  = HW_PCI_DP;
+            SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
+
+            PciNode.Device        = ThisDevice;
+            PciNode.Function      = ThisFunc;
+            ReturnDevicePath      = AppendDevicePathNode (DevicePath, &PciNode.Header);
+
+            *BridgePrimaryBus     = PciPtr->Bridge.SecondaryBus;
+            *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;
+            return ReturnDevicePath;
+          }
+        }
+
+        if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) {
+          //
+          // Skip sub functions, this is not a multi function device
+          //
+          break;
+        }
+      }
+    }
+  }
+
+  ZeroMem (&PciNode, sizeof (PciNode));
+  PciNode.Header.Type     = HARDWARE_DEVICE_PATH;
+  PciNode.Header.SubType  = HW_PCI_DP;
+  SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
+  PciNode.Device        = Device;
+  PciNode.Function      = Function;
+
+  ReturnDevicePath      = AppendDevicePathNode (DevicePath, &PciNode.Header);
+
+  *BridgePrimaryBus     = 0xffff;
+  *BridgeSubordinateBus = 0xffff;
+  return ReturnDevicePath;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciDevicePath (
+  IN     EFI_DEVICE_IO_PROTOCOL        *This,
+  IN     UINT64                        Address,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL      **PciDevicePath
+  )
+/*++
+
+Routine Description:
+  
+  Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
+
+Arguments:
+  
+  This           -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.  
+  Address        -  The PCI configuration space address of the device whose Device Path
+                    is going to be returned.           
+  PciDevicePath  -  A pointer to the pointer for the EFI Device Path for PciAddress.
+                    Memory for the Device Path is allocated from the pool.
+
+Returns:
+  
+  EFI_SUCCESS           -  The PciDevicePath returns a pointer to a valid EFI Device Path.
+  EFI_UNSUPPORTED       -  The PciAddress does not map to a valid EFI Device Path. 
+  EFI_OUT_OF_RESOURCES  -  The request could not be completed due to a lack of resources.
+
+--*/
+{
+  DEVICE_IO_PRIVATE_DATA  *Private;
+  UINT16                  PrimaryBus;
+  UINT16                  SubordinateBus;
+  UINT8                   Bus;
+  UINT8                   Device;
+  UINT8                   Func;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  Bus     = (UINT8) (((UINT32) Address >> 24) & 0xff);
+  Device  = (UINT8) (((UINT32) Address >> 16) & 0xff);
+  Func    = (UINT8) (((UINT32) Address >> 8) & 0xff);
+
+  if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *PciDevicePath  = Private->DevicePath;
+  PrimaryBus      = Private->PrimaryBus;
+  SubordinateBus  = Private->SubordinateBus;
+  do {
+    *PciDevicePath = AppendPciDevicePath (
+                       Private,
+                       Bus,
+                       Device,
+                       Func,
+                       *PciDevicePath,
+                       &PrimaryBus,
+                       &SubordinateBus
+                       );
+    if (*PciDevicePath == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  } while (PrimaryBus != 0xffff);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoMap (
+  IN     EFI_DEVICE_IO_PROTOCOL   *This,
+  IN     EFI_IO_OPERATION_TYPE    Operation,
+  IN     EFI_PHYSICAL_ADDRESS     *HostAddress,
+  IN OUT UINTN                    *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS     *DeviceAddress,
+  OUT    VOID                     **Mapping
+  )
+/*++
+
+Routine Description:
+  
+  Provides the device-specific addresses needed to access system memory.
+
+Arguments:
+  
+  This           -  A pointer to the EFI_DEVICE_IO_INTERFACE instance. 
+  Operation      -  Indicates if the bus master is going to read or write to system memory.  
+  HostAddress    -  The system memory address to map to the device.
+  NumberOfBytes  -  On input the number of bytes to map. On output the number of bytes
+                    that were mapped.
+  DeviceAddress  -  The resulting map address for the bus master device to use to access the
+                    hosts HostAddress.
+  Mapping        -  A resulting value to pass to Unmap().
+
+Returns:
+  
+  EFI_SUCCESS            -  The range was mapped for the returned NumberOfBytes. 
+  EFI_INVALID_PARAMETER  -  The Operation or HostAddress is undefined. 
+  EFI_UNSUPPORTED        -  The HostAddress cannot be mapped as a common buffer.
+  EFI_DEVICE_ERROR       -  The system hardware could not map the requested address. 
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of resources.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  if ((UINT32)Operation > EfiBusMasterCommonBuffer) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = Private->PciRootBridgeIo->Map (
+                                       Private->PciRootBridgeIo,
+                                       (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
+                                       (VOID *) (UINTN) (*HostAddress),
+                                       NumberOfBytes,
+                                       DeviceAddress,
+                                       Mapping
+                                       );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoUnmap (
+  IN EFI_DEVICE_IO_PROTOCOL   *This,
+  IN VOID                     *Mapping
+  )
+/*++
+
+Routine Description:
+  
+  Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+  
+  This     -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Mapping  -  The mapping value returned from Map().
+
+Returns:
+  
+  EFI_SUCCESS       -  The range was unmapped.
+  EFI_DEVICE_ERROR  -  The data was not committed to the target system memory.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  Status = Private->PciRootBridgeIo->Unmap (
+                                       Private->PciRootBridgeIo,
+                                       Mapping
+                                       );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoAllocateBuffer (
+  IN     EFI_DEVICE_IO_PROTOCOL    *This,
+  IN     EFI_ALLOCATE_TYPE         Type,
+  IN     EFI_MEMORY_TYPE           MemoryType,
+  IN     UINTN                     Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS      *PhysicalAddress
+  )
+/*++
+
+Routine Description:
+  
+  Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
+
+Arguments:
+  
+  This             -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Type             -  The type allocation to perform.
+  MemoryType       -  The type of memory to allocate, EfiBootServicesData or
+                      EfiRuntimeServicesData.
+  Pages            -  The number of pages to allocate.
+  PhysicalAddress  -  A pointer to store the base address of the allocated range.
+
+Returns:
+  
+  EFI_SUCCESS            -  The requested memory pages were allocated.
+  EFI_OUT_OF_RESOURCES   -  The memory pages could not be allocated.
+  EFI_INVALID_PARAMETER  -  The requested memory type is invalid.
+  EFI_UNSUPPORTED        -  The requested PhysicalAddress is not supported on
+                            this platform.
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  HostAddress;
+
+  HostAddress = *PhysicalAddress;
+
+  if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((UINT32)Type >= MaxAllocateType) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {
+    Type        = AllocateMaxAddress;
+    HostAddress = MAX_COMMON_BUFFER;
+  }
+
+  Status = gBS->AllocatePages (
+                  Type,
+                  MemoryType,
+                  Pages,
+                  &HostAddress
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+
+  *PhysicalAddress = HostAddress;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoFlush (
+  IN EFI_DEVICE_IO_PROTOCOL  *This
+  )
+/*++
+
+Routine Description:
+  
+  Flushes any posted write data to the device.
+
+Arguments:
+  
+  This  -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+
+Returns:
+  
+  EFI_SUCCESS       -  The buffers were flushed.
+  EFI_DEVICE_ERROR  -  The buffers were not flushed due to a hardware error.
+
+--*/
+{
+  EFI_STATUS              Status;
+  DEVICE_IO_PRIVATE_DATA  *Private;
+
+  Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  Status  = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DeviceIoFreeBuffer (
+  IN EFI_DEVICE_IO_PROTOCOL   *This,
+  IN UINTN                    Pages,
+  IN EFI_PHYSICAL_ADDRESS     HostAddress
+  )
+/*++
+
+Routine Description:
+  
+  Frees pages that were allocated with AllocateBuffer().
+
+Arguments:
+  
+  This         -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Pages        -  The number of pages to free.
+  HostAddress  -  The base address of the range to free.
+
+Returns:
+  
+  EFI_SUCCESS            -  The requested memory pages were freed.
+  EFI_NOT_FOUND          -  The requested memory pages were not allocated with
+                            AllocateBuffer().               
+  EFI_INVALID_PARAMETER  -  HostAddress is not page aligned or Pages is invalid.
+
+--*/
+{
+  if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return gBS->FreePages (HostAddress, Pages);
+}
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.h b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.h
new file mode 100644 (file)
index 0000000..9b48374
--- /dev/null
@@ -0,0 +1,449 @@
+/*++
+
+Copyright (c) 2006, 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.             
+
+Module Name:
+
+    DeviceIo.h
+    
+Abstract:
+
+    Private Data definition for Device IO driver
+
+--*/
+
+#ifndef _DEVICE_IO_H
+#define _DEVICE_IO_H
+
+
+
+#define DEVICE_IO_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('d', 'e', 'v', 'I')
+
+#define MAX_COMMON_BUFFER                 0x00000000FFFFFFFF
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_DEVICE_IO_PROTOCOL          DeviceIo;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
+  UINT16                          PrimaryBus;
+  UINT16                          SubordinateBus;
+} DEVICE_IO_PRIVATE_DATA;
+
+#define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)
+
+EFI_STATUS
+DeviceIoConstructor (
+  IN EFI_HANDLE                      Handle,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+  IN EFI_DEVICE_PATH_PROTOCOL        *DevicePath,
+  IN UINT16                          PrimaryBus,
+  IN UINT16                          SubordinateBus
+  )
+/*++
+
+Routine Description:
+
+  Initialize and install a Device IO protocol on a empty device path handle.
+
+Arguments:
+
+  Handle               - Handle of PCI RootBridge IO instance
+  PciRootBridgeIo      - PCI RootBridge IO instance
+  DevicePath           - Device Path of PCI RootBridge IO instance
+  PrimaryBus           - Primary Bus
+  SubordinateBus       - Subordinate Bus
+
+Returns:
+
+  EFI_SUCCESS          -  This driver is added to ControllerHandle.  
+  EFI_ALREADY_STARTED  -  This driver is already running on ControllerHandle.   
+  Others               -  This driver does not support this device.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoMemRead (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading memory mapped I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations.  
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.           
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.  
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoMemWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing memory mapped I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.  
+  Address  -  The base address of I/O operations.   
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.            
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoIoRead (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.          
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoIoWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing I/O space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations.
+  Address  -  The base address of I/O operations.
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.        
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciRead (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform reading PCI configuration space of device
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.  
+  Width    -  Width of I/O operations. 
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.           
+  Buffer   -  The destination buffer to store results.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was read from the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciWrite (
+  IN     EFI_DEVICE_IO_PROTOCOL *This,
+  IN     EFI_IO_WIDTH           Width,
+  IN     UINT64                 Address,
+  IN     UINTN                  Count,
+  IN OUT VOID                   *Buffer
+  )
+/*++
+
+Routine Description:
+  
+  Perform writing PCI configuration space of device.
+
+Arguments:
+  
+  This     -  A pointer to EFI_DEVICE_IO protocol instance.   
+  Width    -  Width of I/O operations. 
+  Address  -  The base address of I/O operations. 
+  Count    -  The number of I/O operations to perform. 
+              Bytes moves is Width size * Count, starting at Address.         
+  Buffer   -  The source buffer of data to be written.
+
+Returns:
+    
+  EFI_SUCCESS            -  The data was written to the device.
+  EFI_INVALID_PARAMETER  -  Width is invalid.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoPciDevicePath (
+  IN     EFI_DEVICE_IO_PROTOCOL        *This,
+  IN     UINT64                        Address,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL      **PciDevicePath
+  )
+/*++
+
+Routine Description:
+  
+  Append a PCI device path node to another device path.
+
+Arguments:
+  
+  This                  -  A pointer to EFI_DEVICE_IO_PROTOCOL.  
+  Address               -  PCI bus,device, function.
+  PciDevicePath         -  PCI device path.
+
+Returns:
+  
+  Pointer to the appended PCI device path.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoMap (
+  IN     EFI_DEVICE_IO_PROTOCOL   *This,
+  IN     EFI_IO_OPERATION_TYPE    Operation,
+  IN     EFI_PHYSICAL_ADDRESS     *HostAddress,
+  IN OUT UINTN                    *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS     *DeviceAddress,
+  OUT    VOID                     **Mapping
+  )
+/*++
+
+Routine Description:
+  
+  Provides the device-specific addresses needed to access system memory.
+
+Arguments:
+  
+  This           -  A pointer to the EFI_DEVICE_IO_INTERFACE instance. 
+  Operation      -  Indicates if the bus master is going to read or write to system memory.  
+  HostAddress    -  The system memory address to map to the device.
+  NumberOfBytes  -  On input the number of bytes to map. On output the number of bytes
+                    that were mapped.
+  DeviceAddress  -  The resulting map address for the bus master device to use to access the
+                    hosts HostAddress.
+  Mapping        -  A resulting value to pass to Unmap().
+
+Returns:
+  
+  EFI_SUCCESS            -  The range was mapped for the returned NumberOfBytes. 
+  EFI_INVALID_PARAMETER  -  The Operation or HostAddress is undefined. 
+  EFI_UNSUPPORTED        -  The HostAddress cannot be mapped as a common buffer.
+  EFI_DEVICE_ERROR       -  The system hardware could not map the requested address. 
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoUnmap (
+  IN EFI_DEVICE_IO_PROTOCOL   *This,
+  IN VOID                     *Mapping
+  )
+/*++
+
+Routine Description:
+  
+  Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+  
+  This     -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Mapping  -  The mapping value returned from Map().
+
+Returns:
+  
+  EFI_SUCCESS       -  The range was unmapped.
+  EFI_DEVICE_ERROR  -  The data was not committed to the target system memory.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoAllocateBuffer (
+  IN     EFI_DEVICE_IO_PROTOCOL    *This,
+  IN     EFI_ALLOCATE_TYPE         Type,
+  IN     EFI_MEMORY_TYPE           MemoryType,
+  IN     UINTN                     Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS      *HostAddress
+  )
+/*++
+
+Routine Description:
+  
+  Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
+
+Arguments:
+  
+  This             -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Type             -  The type allocation to perform.
+  MemoryType       -  The type of memory to allocate, EfiBootServicesData or
+                      EfiRuntimeServicesData.
+  Pages            -  The number of pages to allocate.
+  HostAddress      -  A pointer to store the base address of the allocated range.
+
+Returns:
+  
+  EFI_SUCCESS            -  The requested memory pages were allocated.
+  EFI_OUT_OF_RESOURCES   -  The memory pages could not be allocated.
+  EFI_INVALID_PARAMETER  -  The requested memory type is invalid.
+  EFI_UNSUPPORTED        -  The requested PhysicalAddress is not supported on
+                            this platform.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoFlush (
+  IN EFI_DEVICE_IO_PROTOCOL  *This
+  )
+/*++
+
+Routine Description:
+  
+  Flushes any posted write data to the device.
+
+Arguments:
+  
+  This  -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+
+Returns:
+  
+  EFI_SUCCESS       -  The buffers were flushed.
+  EFI_DEVICE_ERROR  -  The buffers were not flushed due to a hardware error.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+DeviceIoFreeBuffer (
+  IN EFI_DEVICE_IO_PROTOCOL   *This,
+  IN UINTN                    Pages,
+  IN EFI_PHYSICAL_ADDRESS     HostAddress
+  )
+/*++
+
+Routine Description:
+  
+  Frees pages that were allocated with AllocateBuffer().
+
+Arguments:
+  
+  This         -  A pointer to the EFI_DEVICE_IO_INTERFACE instance.
+  Pages        -  The number of pages to free.
+  HostAddress  -  The base address of the range to free.
+
+Returns:
+  
+  EFI_SUCCESS            -  The requested memory pages were freed.
+  EFI_NOT_FOUND          -  The requested memory pages were not allocated with
+                            AllocateBuffer().               
+  EFI_INVALID_PARAMETER  -  HostAddress is not page aligned or Pages is invalid.
+
+--*/
+;
+
+#endif
+
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c
new file mode 100644 (file)
index 0000000..63ea892
--- /dev/null
@@ -0,0 +1,738 @@
+/*++
+
+Copyright (c) 2005 - 2012, 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.             
+
+Module Name:
+    PcatPciRootBridgeIo.c
+    
+Abstract:
+
+    EFI PC AT PCI Root Bridge Io Protocol
+
+Revision History
+
+--*/
+
+#include "PcatPciRootBridge.h"
+
+BOOLEAN                  mPciOptionRomTableInstalled = FALSE;
+EFI_PCI_OPTION_ROM_TABLE mPciOptionRomTable          = {0, NULL};
+
+EFI_STATUS
+EFIAPI
+PcatRootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *UserBuffer
+  )
+{
+  return gCpuIo->Io.Read (
+                      gCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      UserAddress,
+                      Count,
+                      UserBuffer
+                      );
+}
+
+EFI_STATUS
+EFIAPI
+PcatRootBridgeIoIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                                 UserAddress,
+  IN UINTN                                  Count,
+  IN OUT VOID                               *UserBuffer
+  )
+{
+  return gCpuIo->Io.Write (
+                      gCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      UserAddress,
+                      Count,
+                      UserBuffer
+                      );
+
+}
+
+EFI_STATUS
+PcatRootBridgeIoGetIoPortMapping (
+  OUT EFI_PHYSICAL_ADDRESS  *IoPortMapping,
+  OUT EFI_PHYSICAL_ADDRESS  *MemoryPortMapping
+  )
+/*++
+
+  Get the IO Port Mapping.  For IA-32 it is always 0.
+  
+--*/
+{
+  *IoPortMapping = 0;
+  *MemoryPortMapping = 0;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PcatRootBridgeIoPciRW (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN BOOLEAN                                Write,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                                 UserAddress,
+  IN UINTN                                  Count,
+  IN OUT VOID                               *UserBuffer
+  )
+{
+  PCI_CONFIG_ACCESS_CF8             Pci;
+  PCI_CONFIG_ACCESS_CF8             PciAligned;
+  UINT32                            InStride;
+  UINT32                            OutStride;
+  UINTN                             PciData;
+  UINTN                             PciDataStride;
+  PCAT_PCI_ROOT_BRIDGE_INSTANCE     *PrivateData;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  PciAddress;
+  UINT64                            PciExpressRegAddr;
+  BOOLEAN                           UsePciExpressAccess;
+
+  if ((UINT32)Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  if ((Width & 0x03) >= EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  InStride    = 1 << (Width & 0x03);
+  OutStride   = InStride;
+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    InStride = 0;
+  }
+
+  if (Width >= EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
+    OutStride = 0;
+  }
+
+  UsePciExpressAccess = FALSE;
+
+  CopyMem (&PciAddress, &UserAddress, sizeof(UINT64));
+
+  if (PciAddress.ExtendedRegister > 0xFF) {
+    //
+    // Check PciExpressBaseAddress
+    //
+    if ((PrivateData->PciExpressBaseAddress == 0) ||
+        (PrivateData->PciExpressBaseAddress >= MAX_ADDRESS)) {
+      return EFI_UNSUPPORTED;
+    } else {
+      UsePciExpressAccess = TRUE;
+    }
+  } else {
+    if (PciAddress.ExtendedRegister != 0) {
+      Pci.Bits.Reg = PciAddress.ExtendedRegister & 0xFF;
+    } else {
+      Pci.Bits.Reg = PciAddress.Register;
+    }
+    //
+    // Note: We can also use PciExpress access here, if wanted.
+    //
+  }
+
+  if (!UsePciExpressAccess) {
+    Pci.Bits.Func     = PciAddress.Function;
+    Pci.Bits.Dev      = PciAddress.Device;
+    Pci.Bits.Bus      = PciAddress.Bus;
+    Pci.Bits.Reserved = 0;
+    Pci.Bits.Enable   = 1;
+
+    //
+    // PCI Config access are all 32-bit alligned, but by accessing the
+    //  CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
+    //  are possible on PCI.
+    //
+    // To read a byte of PCI config space you load 0xcf8 and 
+    //  read 0xcfc, 0xcfd, 0xcfe, 0xcff
+    //
+    PciDataStride = Pci.Bits.Reg & 0x03;
+
+    while (Count) {
+      PciAligned = Pci;
+      PciAligned.Bits.Reg &= 0xfc;
+      PciData = (UINTN)PrivateData->PciData + PciDataStride;
+      EfiAcquireLock(&PrivateData->PciLock);
+      This->Io.Write (This, EfiPciWidthUint32, PrivateData->PciAddress, 1, &PciAligned);
+      if (Write) {
+        This->Io.Write (This, Width, PciData, 1, UserBuffer);
+      } else {
+        This->Io.Read (This, Width, PciData, 1, UserBuffer);
+      }
+      EfiReleaseLock(&PrivateData->PciLock);
+      UserBuffer = ((UINT8 *)UserBuffer) + OutStride;
+      PciDataStride = (PciDataStride + InStride) % 4;
+      Pci.Bits.Reg += InStride;
+      Count -= 1;
+    }
+  } else {
+    //
+    // Access PCI-Express space by using memory mapped method.
+    //
+    PciExpressRegAddr = (PrivateData->PciExpressBaseAddress) |
+                        (PciAddress.Bus      << 20) |
+                        (PciAddress.Device   << 15) |
+                        (PciAddress.Function << 12);
+    if (PciAddress.ExtendedRegister != 0) {
+      PciExpressRegAddr += PciAddress.ExtendedRegister;
+    } else {
+      PciExpressRegAddr += PciAddress.Register;
+    }
+    while (Count) {
+      if (Write) {
+        This->Mem.Write (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
+      } else {
+        This->Mem.Read (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
+      }
+
+      UserBuffer = ((UINT8 *) UserBuffer) + OutStride;
+      PciExpressRegAddr += InStride;
+      Count -= 1;
+    }
+  }
+  
+  return EFI_SUCCESS;
+}
+
+VOID
+ScanPciBus(
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev,
+  UINT16                           MinBus,
+  UINT16                           MaxBus,
+  UINT16                           MinDevice,
+  UINT16                           MaxDevice,
+  UINT16                           MinFunc,
+  UINT16                           MaxFunc,
+  EFI_PCI_BUS_SCAN_CALLBACK        Callback,
+  VOID                             *Context
+  )
+  
+{
+  UINT16      Bus;
+  UINT16      Device;
+  UINT16      Func;
+  UINT64      Address;
+  PCI_TYPE00  PciHeader;
+
+  //
+  // Loop through all busses
+  //
+  for (Bus = MinBus; Bus <= MaxBus; Bus++) {
+    //  
+    // Loop 32 devices per bus
+    //
+    for (Device = MinDevice; Device <= MaxDevice; Device++) {
+      //
+      // Loop through 8 functions per device
+      //
+      for (Func = MinFunc; Func <= MaxFunc; Func++) {
+
+        //
+        // Compute the EFI Address required to access the PCI Configuration Header of this PCI Device
+        //
+        Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+        //
+        // Read the VendorID from this PCI Device's Confioguration Header
+        //
+        IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &PciHeader.Hdr.VendorId);
+    
+        //
+        // If VendorId = 0xffff, there does not exist a device at this 
+        // location. For each device, if there is any function on it, 
+        // there must be 1 function at Function 0. So if Func = 0, there
+        // will be no more functions in the same device, so we can break
+        // loop to deal with the next device.
+        //  
+        if (PciHeader.Hdr.VendorId == 0xffff && Func == 0) {
+          break;
+        }
+        
+        if (PciHeader.Hdr.VendorId != 0xffff) {
+
+          //
+          // Read the HeaderType to determine if this is a multi-function device
+          //
+          IoDev->Pci.Read (IoDev, EfiPciWidthUint8, Address + 0x0e, 1, &PciHeader.Hdr.HeaderType);
+
+          //
+          // Call the callback function for the device that was found
+          //
+          Callback(
+            IoDev, 
+            MinBus, MaxBus,
+            MinDevice, MaxDevice,
+            MinFunc, MaxFunc,
+            Bus,
+            Device,
+            Func,
+            Context
+            );
+
+          //
+          // If this is not a multi-function device, we can leave the loop 
+          // to deal with the next device.
+          //
+          if ((PciHeader.Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00 && Func == 0) {
+            break;
+          }
+        }  
+      }
+    }
+  }
+}
+
+VOID
+CheckForRom (
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev,
+  UINT16                           MinBus,
+  UINT16                           MaxBus,
+  UINT16                           MinDevice,
+  UINT16                           MaxDevice,
+  UINT16                           MinFunc,
+  UINT16                           MaxFunc,
+  UINT16                           Bus,
+  UINT16                           Device,
+  UINT16                           Func,
+  IN VOID                          *VoidContext
+  )
+{
+  EFI_STATUS                                 Status;
+  PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT  *Context;
+  UINT64                                     Address;
+  PCI_TYPE00                                 PciHeader;
+  PCI_TYPE01                                 *PciBridgeHeader;
+  UINT32                                     Register;
+  UINT32                                     RomBar;
+  UINT32                                     RomBarSize;
+  EFI_PHYSICAL_ADDRESS                       RomBuffer;
+  UINT32                                     MaxRomSize;
+  EFI_PCI_EXPANSION_ROM_HEADER               EfiRomHeader;
+  PCI_DATA_STRUCTURE                         Pcir;
+  EFI_PCI_OPTION_ROM_DESCRIPTOR              *TempPciOptionRomDescriptors;
+  BOOLEAN                                    LastImage;
+
+  Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
+
+  Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+  //
+  // Save the contents of the PCI Configuration Header
+  //
+  IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
+
+  if (IS_PCI_BRIDGE(&PciHeader)) {
+
+    PciBridgeHeader = (PCI_TYPE01 *)(&PciHeader);
+
+    //
+    // See if the PCI-PCI Bridge has its secondary interface enabled.
+    //
+    if (PciBridgeHeader->Bridge.SubordinateBus >= PciBridgeHeader->Bridge.SecondaryBus) {
+
+      //
+      // Disable the Prefetchable Memory Window
+      //
+      Register = 0x00000000;
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x26, 1, &Register);
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x2c, 1, &Register);
+      Register = 0xffffffff;
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x24, 1, &Register);
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x28, 1, &Register);
+
+      //
+      // Program Memory Window to the PCI Root Bridge Memory Window
+      //
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x20, 4, &Context->PpbMemoryWindow);
+
+      //
+      // Enable the Memory decode for the PCI-PCI Bridge
+      //
+      IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+      Register |= 0x02;
+      IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+
+      //
+      // Recurse on the Secondary Bus Number
+      //
+      ScanPciBus(
+        IoDev,
+        PciBridgeHeader->Bridge.SecondaryBus, PciBridgeHeader->Bridge.SecondaryBus, 
+        0, PCI_MAX_DEVICE, 
+        0, PCI_MAX_FUNC, 
+        CheckForRom, Context
+        );
+    }
+  } else {
+
+    //
+    // Check if an Option ROM Register is present and save the Option ROM Window Register
+    //
+    RomBar = 0xffffffff;
+    IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
+    IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
+
+    RomBarSize = (~(RomBar & 0xfffff800)) + 1;
+
+    //
+    // Make sure the size of the ROM is between 0 and 16 MB
+    //
+    if (RomBarSize > 0 && RomBarSize <= 0x01000000) {
+
+      //
+      // Program Option ROM Window Register to the PCI Root Bridge Window and Enable the Option ROM Window
+      //
+      RomBar = (Context->PpbMemoryWindow & 0xffff) << 16;
+      RomBar = ((RomBar - 1) & (~(RomBarSize - 1))) + RomBarSize;
+      if (RomBar < (Context->PpbMemoryWindow & 0xffff0000)) {
+        MaxRomSize = (Context->PpbMemoryWindow & 0xffff0000) - RomBar;
+        RomBar = RomBar + 1;
+        IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
+        IoDev->Pci.Read  (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
+        RomBar = RomBar - 1;
+
+        //
+        // Enable the Memory decode for the PCI Device
+        //
+        IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+        Register |= 0x02;
+        IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+
+        //
+        // Follow the chain of images to determine the size of the Option ROM present
+        // Keep going until the last image is found by looking at the Indicator field
+        // or the size of an image is 0, or the size of all the images is bigger than the
+        // size of the window programmed into the PPB.
+        //
+        RomBarSize = 0;
+        do {
+
+          LastImage = TRUE;
+
+          ZeroMem (&EfiRomHeader, sizeof(EfiRomHeader));
+          IoDev->Mem.Read (
+            IoDev, 
+            EfiPciWidthUint8, 
+            RomBar + RomBarSize, 
+            sizeof(EfiRomHeader),
+            &EfiRomHeader
+            );
+
+          Pcir.ImageLength = 0;
+
+          if (EfiRomHeader.Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE &&
+              EfiRomHeader.PcirOffset != 0 &&
+              (EfiRomHeader.PcirOffset & 3) == 0 &&
+              RomBarSize + EfiRomHeader.PcirOffset + sizeof (PCI_DATA_STRUCTURE) <= MaxRomSize) {
+            ZeroMem (&Pcir, sizeof(Pcir));
+            IoDev->Mem.Read (
+              IoDev, 
+              EfiPciWidthUint8, 
+              RomBar + RomBarSize + EfiRomHeader.PcirOffset, 
+              sizeof(Pcir),
+              &Pcir
+              );
+
+            if (Pcir.Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+              break;
+            }
+            if (RomBarSize + Pcir.ImageLength * 512 > MaxRomSize) {
+              break;
+            }
+            if ((Pcir.Indicator & 0x80) == 0x00) {
+              LastImage = FALSE;
+            }
+
+            RomBarSize += Pcir.ImageLength * 512;
+          }
+        } while (!LastImage && RomBarSize < MaxRomSize && Pcir.ImageLength !=0);
+
+        if (RomBarSize > 0) {
+
+          //
+          // Allocate a memory buffer for the Option ROM contents.
+          //
+          Status = gBS->AllocatePages(
+                          AllocateAnyPages,
+                          EfiBootServicesData,
+                          EFI_SIZE_TO_PAGES(RomBarSize),
+                          &RomBuffer
+                          );
+
+          if (!EFI_ERROR (Status)) {
+
+            //
+            // Copy the contents of the Option ROM to the memory buffer
+            //
+            IoDev->Mem.Read (IoDev, EfiPciWidthUint32, RomBar, RomBarSize / sizeof(UINT32), (VOID *)(UINTN)RomBuffer);
+
+            Status = gBS->AllocatePool(
+                            EfiBootServicesData,
+                            ((UINT32)mPciOptionRomTable.PciOptionRomCount + 1) * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR),
+                            (VOID*)&TempPciOptionRomDescriptors
+                            );
+            if (mPciOptionRomTable.PciOptionRomCount > 0) {
+              CopyMem(
+                TempPciOptionRomDescriptors, 
+                mPciOptionRomTable.PciOptionRomDescriptors, 
+                (UINT32)mPciOptionRomTable.PciOptionRomCount * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR)
+                );
+
+              gBS->FreePool(mPciOptionRomTable.PciOptionRomDescriptors);
+            }
+
+            mPciOptionRomTable.PciOptionRomDescriptors = TempPciOptionRomDescriptors; 
+
+            TempPciOptionRomDescriptors = &(mPciOptionRomTable.PciOptionRomDescriptors[(UINT32)mPciOptionRomTable.PciOptionRomCount]);
+
+            TempPciOptionRomDescriptors->RomAddress              = RomBuffer;
+            TempPciOptionRomDescriptors->MemoryType              = EfiBootServicesData;
+            TempPciOptionRomDescriptors->RomLength               = RomBarSize;
+            TempPciOptionRomDescriptors->Seg                     = (UINT32)IoDev->SegmentNumber;
+            TempPciOptionRomDescriptors->Bus                     = (UINT8)Bus;
+            TempPciOptionRomDescriptors->Dev                     = (UINT8)Device;
+            TempPciOptionRomDescriptors->Func                    = (UINT8)Func;
+            TempPciOptionRomDescriptors->ExecutedLegacyBiosImage = TRUE;
+            TempPciOptionRomDescriptors->DontLoadEfiRom          = FALSE;
+
+            mPciOptionRomTable.PciOptionRomCount++;
+          }
+        }
+
+        //
+        // Disable the Memory decode for the PCI-PCI Bridge
+        //
+        IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+        Register &= (~0x02);
+        IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
+      }
+    }
+  }
+
+  //
+  // Restore the PCI Configuration Header 
+  //
+  IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
+}
+
+VOID
+SaveCommandRegister (
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev,
+  UINT16                           MinBus,
+  UINT16                           MaxBus,
+  UINT16                           MinDevice,
+  UINT16                           MaxDevice,
+  UINT16                           MinFunc,
+  UINT16                           MaxFunc,
+  UINT16                           Bus,
+  UINT16                           Device,
+  UINT16                           Func,
+  IN VOID                          *VoidContext
+  )
+
+{
+  PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT  *Context;
+  UINT64  Address;
+  UINTN   Index;
+  UINT16  Command;
+
+  Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
+
+  Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
+
+  Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
+
+  IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
+
+  //
+  // Clear the memory enable bit
+  //
+  Command = (UINT16) (Context->CommandRegisterBuffer[Index] & (~0x02));
+
+  IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Command);
+}
+
+VOID
+RestoreCommandRegister (
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev,
+  UINT16                           MinBus,
+  UINT16                           MaxBus,
+  UINT16                           MinDevice,
+  UINT16                           MaxDevice,
+  UINT16                           MinFunc,
+  UINT16                           MaxFunc,
+  UINT16                           Bus,
+  UINT16                           Device,
+  UINT16                           Func,
+  IN VOID                          *VoidContext
+  )
+
+{
+  PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT  *Context;
+  UINT64                                     Address;
+  UINTN                                      Index;
+
+  Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
+
+  Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
+
+  Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
+
+  IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
+}
+
+EFI_STATUS
+ScanPciRootBridgeForRoms(
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev
+  )
+  
+{
+  EFI_STATUS                                 Status;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR          *Descriptors; 
+  UINT16                                     MinBus;
+  UINT16                                     MaxBus;
+  UINT64                                     RootWindowBase;
+  UINT64                                     RootWindowLimit;
+  PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT  Context;
+
+  if (mPciOptionRomTableInstalled == FALSE) {
+    gBS->InstallConfigurationTable(&gEfiPciOptionRomTableGuid, &mPciOptionRomTable);
+    mPciOptionRomTableInstalled = TRUE;
+  }
+
+  Status = IoDev->Configuration(IoDev, (VOID **)&Descriptors);
+  if (EFI_ERROR (Status) || Descriptors == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  MinBus = 0xffff;
+  MaxBus = 0xffff;
+  RootWindowBase  = 0;
+  RootWindowLimit = 0;
+  while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {
+    //
+    // Find bus range
+    //
+    if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
+      MinBus = (UINT16)Descriptors->AddrRangeMin;
+      MaxBus = (UINT16)Descriptors->AddrRangeMax;
+    }
+    //
+    // Find memory descriptors that are not prefetchable
+    //
+    if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM && Descriptors->SpecificFlag == 0) {
+      //
+      // Find Memory Descriptors that are less than 4GB, so the PPB Memory Window can be used for downstream devices
+      //
+      if (Descriptors->AddrRangeMax < 0x100000000ULL) {
+        //
+        // Find the largest Non-Prefetchable Memory Descriptor that is less than 4GB
+        //
+        if ((Descriptors->AddrRangeMax - Descriptors->AddrRangeMin) > (RootWindowLimit - RootWindowBase)) {
+          RootWindowBase  = Descriptors->AddrRangeMin;
+          RootWindowLimit = Descriptors->AddrRangeMax;
+        }
+      }
+    }
+    Descriptors ++;
+  }
+
+  //
+  // Make sure a bus range was found
+  //
+  if (MinBus == 0xffff || MaxBus == 0xffff) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Make sure a non-prefetchable memory region was found
+  //
+  if (RootWindowBase == 0 && RootWindowLimit == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Round the Base and Limit values to 1 MB boudaries
+  //
+  RootWindowBase  = ((RootWindowBase - 1) & 0xfff00000) + 0x00100000;
+  RootWindowLimit = ((RootWindowLimit + 1) & 0xfff00000) - 1;
+
+  //
+  // Make sure that the size of the rounded window is greater than zero
+  //
+  if (RootWindowLimit <= RootWindowBase) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Allocate buffer to save the Command register from all the PCI devices
+  //
+  Context.CommandRegisterBuffer = NULL;
+  Status = gBS->AllocatePool(
+                  EfiBootServicesData,
+                  sizeof(UINT16) * (MaxBus - MinBus + 1) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1),
+                  (VOID **)&Context.CommandRegisterBuffer
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Context.PpbMemoryWindow   = (((UINT32)RootWindowBase) >> 16) | ((UINT32)RootWindowLimit & 0xffff0000);
+
+  //
+  // Save the Command register from all the PCI devices, and disable the I/O, Mem, and BusMaster bits
+  //
+  ScanPciBus(
+    IoDev,
+    MinBus, MaxBus, 
+    0, PCI_MAX_DEVICE, 
+    0, PCI_MAX_FUNC, 
+    SaveCommandRegister, &Context
+    );
+
+  //
+  // Recursively scan all the busses for PCI Option ROMs
+  //
+  ScanPciBus(
+    IoDev,
+    MinBus, MinBus, 
+    0, PCI_MAX_DEVICE, 
+    0, PCI_MAX_FUNC, 
+    CheckForRom, &Context
+    );
+
+  //
+  // Restore the Command register in all the PCI devices
+  //
+  ScanPciBus(
+    IoDev,
+    MinBus, MaxBus, 
+    0, PCI_MAX_DEVICE, 
+    0, PCI_MAX_FUNC, 
+    RestoreCommandRegister, &Context
+    );
+
+  //
+  // Free the buffer used to save all the Command register values
+  //
+  gBS->FreePool(Context.CommandRegisterBuffer);
+
+  return EFI_SUCCESS;
+}
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ipf/PcatIo.c b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/Ipf/PcatIo.c
new file mode 100644 (file)
index 0000000..f4a7ffa
--- /dev/null
@@ -0,0 +1,459 @@
+/*++
+
+Copyright (c) 2005 - 2012, 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.             
+
+Module Name:
+    PcatPciRootBridgeIo.c
+    
+Abstract:
+
+    EFI PC AT PCI Root Bridge Io Protocol
+
+Revision History
+
+--*/
+
+#include "PcatPciRootBridge.h"
+#include <IndustryStandard/Pci.h>
+#include "SalProc.h"
+
+#include EFI_GUID_DEFINITION (SalSystemTable)
+
+//
+// Might be good to put this in an include file, but people may start
+//  using it! They should always access the EFI abstraction that is
+//  contained in this file. Just a little information hiding.
+//
+#define PORT_TO_MEM(_Port) ( ((_Port) & 0xffffffffffff0000) | (((_Port) & 0xfffc) << 10) | ((_Port) & 0x0fff) )
+                                                                           
+//                                                                  
+// Macro's with casts make this much easier to use and read.
+//
+#define PORT_TO_MEM8(_Port)     (*(UINT8  *)(PORT_TO_MEM(_Port)))
+#define PORT_TO_MEM16(_Port)    (*(UINT16 *)(PORT_TO_MEM(_Port)))
+#define PORT_TO_MEM32(_Port)    (*(UINT32 *)(PORT_TO_MEM(_Port)))
+
+#define EFI_PCI_ADDRESS_IA64(_seg, _bus,_dev,_func,_reg) \
+    ( (UINT64) ( (((UINTN)_seg) << 24) + (((UINTN)_bus) << 16) + (((UINTN)_dev) << 11) + (((UINTN)_func) << 8) + ((UINTN)_reg)) )
+
+//
+// Local variables for performing SAL Proc calls
+//
+PLABEL         mSalProcPlabel;
+CALL_SAL_PROC  mGlobalSalProc;
+
+EFI_STATUS
+PcatRootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *UserBuffer
+  )
+{
+  PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+  UINTN                         InStride;
+  UINTN                         OutStride;
+  UINTN                         AlignMask;
+  UINTN                         Address;
+  PTR                           Buffer;
+  UINT16                        Data16;
+  UINT32                        Data32;
+  
+  if ( UserBuffer == NULL ) {
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  Address    = (UINTN)  UserAddress;
+  Buffer.buf = (UINT8 *)UserBuffer;
+
+  if ( Address < PrivateData->IoBase || Address > PrivateData->IoLimit ) {
+    return EFI_INVALID_PARAMETER;
+  }
+    
+  if ((UINT32)Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Width & 0x03) == EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AlignMask = (1 << (Width & 0x03)) - 1;
+  if ( Address & AlignMask ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InStride  = 1 << (Width & 0x03);
+  OutStride = InStride;
+  if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    InStride = 0;
+  }
+  if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
+    OutStride = 0;
+  }
+  Width = Width & 0x03;
+
+  Address += PrivateData->PhysicalIoBase;
+
+  //
+  // Loop for each iteration and move the data
+  //
+
+  switch (Width) {
+  case EfiPciWidthUint8:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      *Buffer.ui8 = PORT_TO_MEM8(Address);
+      MEMORY_FENCE();
+    }
+    break;
+
+  case EfiPciWidthUint16:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      if (Buffer.ui & 0x1) {
+        Data16 = PORT_TO_MEM16(Address);
+        *Buffer.ui8     = (UINT8)(Data16 & 0xff);
+        *(Buffer.ui8+1) = (UINT8)((Data16 >> 8) & 0xff);
+      } else {
+        *Buffer.ui16 = PORT_TO_MEM16(Address);
+      }
+      MEMORY_FENCE();
+    }
+    break;
+
+  case EfiPciWidthUint32:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      if (Buffer.ui & 0x3) {
+        Data32 = PORT_TO_MEM32(Address);
+        *Buffer.ui8     = (UINT8)(Data32 & 0xff);
+        *(Buffer.ui8+1) = (UINT8)((Data32 >> 8) & 0xff);
+        *(Buffer.ui8+2) = (UINT8)((Data32 >> 16) & 0xff);
+        *(Buffer.ui8+3) = (UINT8)((Data32 >> 24) & 0xff);
+      } else {
+        *Buffer.ui32 = PORT_TO_MEM32(Address);
+      }
+      MEMORY_FENCE();
+    }
+    break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PcatRootBridgeIoIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                                 UserAddress,
+  IN UINTN                                  Count,
+  IN OUT VOID                               *UserBuffer
+  )
+{
+  PCAT_PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  UINTN                          InStride;
+  UINTN                          OutStride;
+  UINTN                          AlignMask;
+  UINTN                          Address;
+  PTR                            Buffer;
+  UINT16                         Data16;
+  UINT32                         Data32;
+
+  if ( UserBuffer == NULL ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  Address    = (UINTN)  UserAddress;
+  Buffer.buf = (UINT8 *)UserBuffer;
+
+  if ( Address < PrivateData->IoBase || Address > PrivateData->IoLimit ) {
+    return EFI_INVALID_PARAMETER;
+  }
+    
+  if (Width < 0 || Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Width & 0x03) == EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AlignMask = (1 << (Width & 0x03)) - 1;
+  if ( Address & AlignMask ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InStride  = 1 << (Width & 0x03);
+  OutStride = InStride;
+  if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    InStride = 0;
+  }
+  if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
+    OutStride = 0;
+  }
+  Width = Width & 0x03;
+
+  Address += PrivateData->PhysicalIoBase;
+
+  //
+  // Loop for each iteration and move the data
+  //
+
+  switch (Width) {
+  case EfiPciWidthUint8:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      PORT_TO_MEM8(Address) = *Buffer.ui8;
+      MEMORY_FENCE();
+    }
+    break;
+
+  case EfiPciWidthUint16:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      if (Buffer.ui & 0x1) {
+        Data16 = *Buffer.ui8;
+        Data16 = Data16 | (*(Buffer.ui8+1) << 8);
+        PORT_TO_MEM16(Address) = Data16;
+      } else {
+        PORT_TO_MEM16(Address) = *Buffer.ui16;
+      }
+      MEMORY_FENCE();
+    }
+    break;
+  case EfiPciWidthUint32:
+    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
+      MEMORY_FENCE();
+      if (Buffer.ui & 0x3) {
+        Data32 = *Buffer.ui8;
+        Data32 = Data32 | (*(Buffer.ui8+1) << 8);
+        Data32 = Data32 | (*(Buffer.ui8+2) << 16);
+        Data32 = Data32 | (*(Buffer.ui8+3) << 24);
+        PORT_TO_MEM32(Address) = Data32;
+      } else {
+        PORT_TO_MEM32(Address) = *Buffer.ui32;
+      }
+      MEMORY_FENCE();
+    }
+    break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PcatRootBridgeIoGetIoPortMapping (
+  OUT EFI_PHYSICAL_ADDRESS  *IoPortMapping,
+  OUT EFI_PHYSICAL_ADDRESS  *MemoryPortMapping
+  )
+/*++
+
+  Get the IO Port Map from the SAL System Table.
+  
+--*/
+{
+  SAL_SYSTEM_TABLE_ASCENDING_ORDER    *SalSystemTable;
+  SAL_ST_MEMORY_DESCRIPTOR_ENTRY      *SalMemDesc;
+  EFI_STATUS                          Status;
+
+  //
+  // On all Itanium architectures, bit 63 is the I/O bit for performming Memory Mapped I/O operations
+  //
+  *MemoryPortMapping = 0x8000000000000000;
+
+  Status = EfiLibGetSystemConfigurationTable(&gEfiSalSystemTableGuid, &SalSystemTable);
+  if (EFI_ERROR(Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // BugBug: Add code to test checksum on the Sal System Table
+  //
+  if (SalSystemTable->Entry0.Type != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  mSalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry; 
+  mSalProcPlabel.GP             = SalSystemTable->Entry0.GlobalDataPointer;
+  mGlobalSalProc                = (CALL_SAL_PROC)&mSalProcPlabel.ProcEntryPoint;
+
+  //
+  // The SalSystemTable pointer includes the Type 0 entry.
+  //  The SalMemDesc is Type 1 so it comes next.
+  //
+  SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
+  while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
+    if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) {
+      *IoPortMapping = SalMemDesc->PhysicalMemoryAddress;
+      *IoPortMapping |= 0x8000000000000000;
+      return EFI_SUCCESS;
+    }
+    SalMemDesc++;
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PcatRootBridgeIoPciRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     BOOLEAN                                Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN OUT UINT8                                  *UserBuffer
+  )
+{
+  PCAT_PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  UINTN                          AlignMask;
+  UINTN                          InStride;
+  UINTN                          OutStride;
+  UINT64                         Address;
+  DEFIO_PCI_ADDR                 *Defio;
+  PTR                            Buffer;
+  UINT32                         Data32;
+  UINT16                         Data16;
+  rArg                           Return;
+
+  if (Width < 0 || Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Width & 0x03) == EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AlignMask = (1 << (Width & 0x03)) - 1;
+  if ( UserAddress & AlignMask ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InStride  = 1 << (Width & 0x03);
+  OutStride = InStride;
+  if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    InStride = 0;
+  }
+  if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
+    OutStride = 0;
+  }
+  Width = Width & 0x03;
+
+  Defio = (DEFIO_PCI_ADDR *)&UserAddress;
+
+  if ((Defio->Function > PCI_MAX_FUNC) || (Defio->Device > PCI_MAX_DEVICE)) {
+    return EFI_UNSUPPORTED;
+  }
+  
+  Buffer.buf = (UINT8 *)UserBuffer;
+  
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  Address = EFI_PCI_ADDRESS_IA64(
+              This->SegmentNumber, 
+              Defio->Bus, 
+              Defio->Device, 
+              Defio->Function, 
+              Defio->Register
+              );
+
+  //
+  // PCI Config access are all 32-bit alligned, but by accessing the
+  //  CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
+  //  are possible on PCI.
+  //
+  // SalProc takes care of reading the proper register depending on stride
+  //
+
+  EfiAcquireLock(&PrivateData->PciLock);
+
+  while (Count) {
+
+    if(Write) {
+
+      if (Buffer.ui & 0x3) {
+        Data32  = (*(Buffer.ui8+0) << 0);
+        Data32 |= (*(Buffer.ui8+1) << 8);
+        Data32 |= (*(Buffer.ui8+2) << 16);
+        Data32 |= (*(Buffer.ui8+3) << 24);
+      } else {
+        Data32 = *Buffer.ui32;
+      }
+
+      Return.p0 = -3;
+      Return    = mGlobalSalProc((UINT64) SAL_PCI_CONFIG_WRITE,
+                                 Address, 1 << Width, Data32, 0, 0, 0, 0);
+        
+      if(Return.p0) {
+        EfiReleaseLock(&PrivateData->PciLock);
+        return EFI_UNSUPPORTED;
+      }
+
+    } else {
+
+      Return.p0 = -3;
+      Return    = mGlobalSalProc((UINT64) SAL_PCI_CONFIG_READ,
+                                 Address, 1 << Width, 0, 0, 0, 0, 0);
+
+      if(Return.p0) {
+        EfiReleaseLock(&PrivateData->PciLock);
+        return EFI_UNSUPPORTED;
+      }
+
+      switch (Width) {
+      case EfiPciWidthUint8:
+        *Buffer.ui8 = (UINT8)Return.p1;
+        break;
+      case EfiPciWidthUint16:
+        if (Buffer.ui & 0x1) {
+          Data16 = (UINT16)Return.p1;
+          *(Buffer.ui8 + 0) = Data16 & 0xff;
+          *(Buffer.ui8 + 1) = (Data16 >> 8) & 0xff;
+        } else {
+          *Buffer.ui16 = (UINT16)Return.p1;
+        }
+        break;
+      case EfiPciWidthUint32:
+        if (Buffer.ui & 0x3) {
+          Data32 = (UINT32)Return.p1;
+          *(Buffer.ui8 + 0) = (UINT8)(Data32 & 0xff);
+          *(Buffer.ui8 + 1) = (UINT8)((Data32 >> 8) & 0xff);
+          *(Buffer.ui8 + 2) = (UINT8)((Data32 >> 16) & 0xff);
+          *(Buffer.ui8 + 3) = (UINT8)((Data32 >> 24) & 0xff);
+        } else {
+          *Buffer.ui32 = (UINT32)Return.p1;
+        }
+        break;
+      }
+    }
+
+    Address += InStride;
+    Buffer.buf += OutStride;
+    Count -= 1;
+  }
+  
+  EfiReleaseLock(&PrivateData->PciLock);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScanPciRootBridgeForRoms(
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *IoDev
+  )
+  
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.c b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.c
new file mode 100644 (file)
index 0000000..e76db54
--- /dev/null
@@ -0,0 +1,1009 @@
+/*++
+
+Copyright (c) 2005 - 2009, 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.             
+
+Module Name:
+  PcatPciRootBridge.c
+    
+Abstract:
+
+    EFI PC-AT PCI Root Bridge Controller
+
+--*/
+
+#include "PcatPciRootBridge.h"
+#include "DeviceIo.h"
+
+EFI_CPU_IO2_PROTOCOL *gCpuIo;
+
+EFI_STATUS
+EFIAPI
+InitializePcatPciRootBridge (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+/*++
+
+Routine Description:
+  Initializes the PCI Root Bridge Controller
+
+Arguments:
+  ImageHandle -
+  SystemTable -
+    
+Returns:
+    None
+
+--*/
+{
+  EFI_STATUS                     Status;
+  PCAT_PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  UINTN                          PciSegmentIndex;
+  UINTN                          PciRootBridgeIndex;
+  UINTN                          PrimaryBusIndex;
+  UINTN                          NumberOfPciRootBridges;
+  UINTN                          NumberOfPciDevices;
+  UINTN                          Device;
+  UINTN                          Function;
+  UINT16                         VendorId;
+  PCI_TYPE01                     PciConfigurationHeader;
+  UINT64                         Address;
+  UINT64                         Value;
+  UINT64                         Base;
+  UINT64                         Limit;
+
+  //
+  // Initialize gCpuIo now since the chipset init code requires it.
+  //
+  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)&gCpuIo);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize variables required to search all PCI segments for PCI devices
+  //
+  PciSegmentIndex        = 0;
+  PciRootBridgeIndex     = 0;
+  NumberOfPciRootBridges = 0;
+  PrimaryBusIndex        = 0;
+
+  while (PciSegmentIndex <= PCI_MAX_SEGMENT) {
+
+    PrivateData = NULL;
+    Status = gBS->AllocatePool(
+                    EfiBootServicesData,
+                    sizeof (PCAT_PCI_ROOT_BRIDGE_INSTANCE),
+                    (VOID **)&PrivateData
+                    );
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    ZeroMem (PrivateData, sizeof (PCAT_PCI_ROOT_BRIDGE_INSTANCE));
+
+    //
+    // Initialize the signature of the private data structure
+    //
+    PrivateData->Signature  = PCAT_PCI_ROOT_BRIDGE_SIGNATURE;
+    PrivateData->Handle     = NULL;
+    PrivateData->DevicePath = NULL;
+    InitializeListHead (&PrivateData->MapInfo);
+
+    //
+    // Initialize the PCI root bridge number and the bus range for that root bridge
+    //
+    PrivateData->RootBridgeNumber = (UINT32)PciRootBridgeIndex;
+    PrivateData->PrimaryBus      &n