public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "duke.zhai via groups.io" <duke.zhai=amd.com@groups.io>
To: <devel@edk2.groups.io>
Cc: Eric Xing <eric.xing@amd.com>, Ken Yao <ken.yao@amd.com>,
	Igniculus Fu <igniculus.fu@amd.com>,
	Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [PATCH 18/33] AMD/VanGoghBoard: Check in PciHostBridge module.
Date: Thu, 18 Jan 2024 14:50:31 +0800	[thread overview]
Message-ID: <20240118065046.961-19-duke.zhai@amd.com> (raw)
In-Reply-To: <20240118065046.961-1-duke.zhai@amd.com>

From: Duke Zhai <Duke.Zhai@amd.com>


BZ #:4640

Initial PciHostBridge module. Provides the basic interfaces to abstract

a PCI Host Bridge Resource Allocation.



Signed-off-by: Duke Zhai <duke.zhai@amd.com>

Cc: Eric Xing <eric.xing@amd.com>

Cc: Ken Yao <ken.yao@amd.com>

Cc: Igniculus Fu <igniculus.fu@amd.com>

Cc: Abner Chang <abner.chang@amd.com>

---

 .../Bus/Pci/PciHostBridgeDxe/IoFifo.h         |  184 ++

 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 1431 +++++++++

 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h  |  652 ++++

 .../Pci/PciHostBridgeDxe/PciHostBridge.uni    |  Bin 0 -> 2558 bytes

 .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   68 +

 .../PciHostBridgeDxe/PciHostBridgeExtra.uni   |  Bin 0 -> 1914 bytes

 .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 2686 +++++++++++++++++

 7 files changed, 5021 insertions(+)

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/IoFifo.h

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.uni

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeExtra.uni

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c



diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/IoFifo.h b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/IoFifo.h

new file mode 100644

index 0000000000..051a80753b

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/IoFifo.h

@@ -0,0 +1,184 @@

+/** @file

+  Implementation of IoFifo.h

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  I/O FIFO routines

+

+  Copyright (c) 2008 - 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.

+

+**/

+

+#ifndef _IO_FIFO_H_INCLUDED_

+#define _IO_FIFO_H_INCLUDED_

+

+/**

+  Reads an 8-bit I/O port fifo into a block of memory.

+

+  Reads the 8-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo8 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+/**

+  Reads a 16-bit I/O port fifo into a block of memory.

+

+  Reads the 16-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo16 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+/**

+  Reads a 32-bit I/O port fifo into a block of memory.

+

+  Reads the 32-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo32 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+/**

+  Writes a block of memory into an 8-bit I/O port fifo.

+

+  Writes the 8-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo8 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+/**

+  Writes a block of memory into a 16-bit I/O port fifo.

+

+  Writes the 16-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo16 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+/**

+  Writes a block of memory into a 32-bit I/O port fifo.

+

+  Writes the 32-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo32 (

+  IN      UINTN  Port,

+  IN      UINTN  Count,

+  OUT     VOID   *Buffer

+  );

+

+#endif

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c

new file mode 100644

index 0000000000..4a03e68c20

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c

@@ -0,0 +1,1431 @@

+/** @file

+  Implementation of PciHostBridge.c

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  Provides the basic interfaces to abstract a PCI Host Bridge Resource

+  Allocation

+

+  Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>

+

+  This program and the accompanying materials are licensed and made available

+  under the terms and conditions of the BSD License which accompanies this

+  distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include "PciHostBridge.h"

+#define TOP_MEM  0xC001001Aul

+

+//

+// Hard code: Root Bridge Number within the host bridge

+//            Root Bridge's attribute

+//            Root Bridge's device path

+//            Root Bridge's resource aperture

+//

+UINTN  RootBridgeNumber[1] = { 1 };

+

+UINT64  RootBridgeAttribute[1][1] = {

+  { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM }

+};

+

+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH  mEfiPciRootBridgeDevicePath[1][1] = {

+  {

+    {

+      {

+        {

+          ACPI_DEVICE_PATH,

+          ACPI_DP,

+          {

+            (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),

+            (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)

+          }

+        },

+        EISA_PNP_ID (0x0A03),

+        0

+      },

+

+      {

+        END_DEVICE_PATH_TYPE,

+        END_ENTIRE_DEVICE_PATH_SUBTYPE,

+        {

+          END_DEVICE_PATH_LENGTH,

+          0

+        }

+      }

+    }

+  }

+};

+

+PCI_ROOT_BRIDGE_RESOURCE_APERTURE  mResAperture[1][1] = {

+  {

+    { 0, 0xff, 0xE0000000, 0xffffffff, 0, 0xffff }

+  }

+};

+

+EFI_HANDLE  mDriverImageHandle;

+

+PCI_HOST_BRIDGE_INSTANCE  mPciHostBridgeInstanceTemplate = {

+  PCI_HOST_BRIDGE_SIGNATURE,  // Signature

+  NULL,                       // HostBridgeHandle

+  0,                          // RootBridgeNumber

+  { NULL, NULL },             // Head

+  FALSE,                      // ResourceSubiteed

+  TRUE,                       // CanRestarted

+  {

+    NotifyPhase,

+    GetNextRootBridge,

+    GetAttributes,

+    StartBusEnumeration,

+    SetBusNumbers,

+    SubmitResources,

+    GetProposedResources,

+    PreprocessController

+  }

+};

+

+//

+// Implementation

+//

+

+/**

+  Entry point of this driver

+

+  @param ImageHandle     Handle of driver image

+  @param SystemTable     Point to EFI_SYSTEM_TABLE

+

+  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource

+  @retval EFI_DEVICE_ERROR      Can not install the protocol instance

+  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.

+**/

+EFI_STATUS

+EFIAPI

+InitializePciHostBridge (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     Loop1;

+  UINTN                     Loop2;

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridge;

+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;

+  EFI_PHYSICAL_ADDRESS      TopOfLowMem;

+

+  mDriverImageHandle         = ImageHandle;

+  TopOfLowMem                = AsmReadMsr64 (TOP_MEM);

+  mResAperture[0][0].MemBase = TopOfLowMem;

+

+  //

+  // Create Host Bridge Device Handle

+  //

+  for (Loop1 = 0; Loop1 < HOST_BRIDGE_NUMBER; Loop1++) {

+    HostBridge = AllocateCopyPool (

+                   sizeof (PCI_HOST_BRIDGE_INSTANCE),

+                   &mPciHostBridgeInstanceTemplate

+                   );

+    if (HostBridge == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];

+    InitializeListHead (&HostBridge->Head);

+

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &HostBridge->HostBridgeHandle,

+                    &gEfiPciHostBridgeResourceAllocationProtocolGuid,

+                    &HostBridge->ResAlloc,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      FreePool (HostBridge);

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Create Root Bridge Device Handle in this Host Bridge

+    //

+

+    for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {

+      PrivateData = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));

+      if (PrivateData == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      PrivateData->Signature  = PCI_ROOT_BRIDGE_SIGNATURE;

+      PrivateData->DevicePath =

+        (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];

+

+      RootBridgeConstructor (

+        &PrivateData->Io,

+        HostBridge->HostBridgeHandle,

+        RootBridgeAttribute[Loop1][Loop2],

+        &mResAperture[Loop1][Loop2]

+        );

+

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &PrivateData->Handle,

+                      &gEfiDevicePathProtocolGuid,

+                      PrivateData->DevicePath,

+                      &gEfiPciRootBridgeIoProtocolGuid,

+                      &PrivateData->Io,

+                      NULL

+                      );

+      if (EFI_ERROR (Status)) {

+        FreePool (PrivateData);

+        return EFI_DEVICE_ERROR;

+      }

+

+      InsertTailList (&HostBridge->Head, &PrivateData->Link);

+    }

+  }

+

+  Status = gDS->AddIoSpace (

+                  EfiGcdIoTypeIo,

+                  0x2000,

+                  0xFFFF-0x2000

+                  );

+  ASSERT_EFI_ERROR (Status);

+  TopOfLowMem = AsmReadMsr64 (TOP_MEM);

+  Status      = gDS->AddMemorySpace (

+                       EfiGcdMemoryTypeMemoryMappedIo,

+                       TopOfLowMem,

+                       0xF8000000-TopOfLowMem,

+                       0

+                       );

+

+  return EFI_SUCCESS;

+}

+

+/**

+  These are the notifications from the PCI bus driver that it is about to enter

+  a certain phase of the PCI enumeration process.

+

+  This member function can be used to notify the host bridge driver to perform

+  specific actions, including any chipset-specific initialization, so that the

+  chipset is ready to enter the next phase. Eight notification points are

+  defined at this time. See belows:

+

+  EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures

+                                         and internal data structures. The PCI

+                                         enumerator should issue this

+                                         notification before starting a fresh

+                                         enumeration process. Enumeration

+                                         cannot be restarted after sending any

+                                         other notification such as

+                                         EfiPciHostBridgeBeginBusAllocation.

+

+  EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to

+                                         begin. No specific action is required

+                                         here. This notification can be used to

+                                         perform any chipset-specific

+                                         programming.

+

+  EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming

+                                         phase is complete. No specific action

+                                         is required here. This notification

+                                         can be used to perform any

+                                         chipset-specific programming.

+

+  EfiPciHostBridgeBeginResourceAllocation

+                                         The resource allocation phase is about

+                                         to begin. No specific action is

+                                         required here. This notification can

+                                         be used to perform any

+                                         chipset-specific programming.

+

+  EfiPciHostBridgeAllocateResources      Allocates resources per previously

+                                         submitted requests for all the PCI

+                                         root bridges. These resource settings

+                                         are returned on the next call to

+                                         GetProposedResources(). Before calling

+                                         NotifyPhase() with a Phase of

+                                         EfiPciHostBridgeAllocateResource, the

+                                         PCI bus enumerator is responsible for

+                                         gathering I/O and memory requests for

+                                         all the PCI root bridges and

+                                         submitting these requests using

+                                         SubmitResources(). This function pads

+                                         the resource amount to suit the root

+                                         bridge hardware, takes care of

+                                         dependencies between the PCI root

+                                         bridges, and calls the Global

+                                         Coherency Domain (GCD) with the

+                                         allocation request. In the case of

+                                         padding, the allocated range could be

+                                         bigger than what was requested.

+

+  EfiPciHostBridgeSetResources           Programs the host bridge hardware to

+                                         decode previously allocated resources

+                                         (proposed resources) for all the PCI

+                                         root bridges. After the hardware is

+                                         programmed, reassigning resources will

+                                         not be supported. The bus settings are

+                                         not affected.

+

+  EfiPciHostBridgeFreeResources          Deallocates resources that were

+                                         previously allocated for all the PCI

+                                         root bridges and resets the I/O and

+                                         memory apertures to their initial

+                                         state. The bus settings are not

+                                         affected. If the request to allocate

+                                         resources fails, the PCI enumerator

+                                         can use this notification to

+                                         deallocate previous resources, adjust

+                                         the requests, and retry allocation.

+

+  EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is

+                                         completed. No specific action is

+                                         required here. This notification can

+                                         be used to perform any chipsetspecific

+                                         programming.

+

+  @param[in] This                The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in] Phase               The phase during enumeration

+

+  @retval EFI_NOT_READY          This phase cannot be entered at this time. For

+                                 example, this error is valid for a Phase of

+                                 EfiPciHostBridgeAllocateResources if

+                                 SubmitResources() has not been called for one

+                                 or more PCI root bridges before this call

+

+  @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+                                 This error is valid for a Phase of

+                                 EfiPciHostBridgeSetResources.

+

+  @retval EFI_INVALID_PARAMETER  Invalid phase parameter

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources. This error is valid for a

+                                 Phase of EfiPciHostBridgeAllocateResources if

+                                 the previously submitted resource requests

+                                 cannot be fulfilled or were only partially

+                                 fulfilled.

+

+  @retval EFI_SUCCESS            The notification was accepted without any

+                                 errors.

+**/

+EFI_STATUS

+EFIAPI

+NotifyPhase (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE     Phase

+  )

+{

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+  PCI_RESOURCE_TYPE         Index;

+  LIST_ENTRY                *List;

+  EFI_PHYSICAL_ADDRESS      BaseAddress;

+  UINT64                    AddrLen;

+  UINTN                     BitsOfAlignment;

+  EFI_STATUS                Status;

+  EFI_STATUS                ReturnStatus;

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+

+  switch (Phase) {

+    case EfiPciHostBridgeBeginEnumeration:

+      if (HostBridgeInstance->CanRestarted) {

+        //

+        // Reset the Each Root Bridge

+        //

+        List = HostBridgeInstance->Head.ForwardLink;

+

+        while (List != &HostBridgeInstance->Head) {

+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+          for (Index = TypeIo; Index < TypeMax; Index++) {

+            RootBridgeInstance->ResAllocNode[Index].Type   = Index;

+            RootBridgeInstance->ResAllocNode[Index].Base   = 0;

+            RootBridgeInstance->ResAllocNode[Index].Length = 0;

+            RootBridgeInstance->ResAllocNode[Index].Status = ResNone;

+          }

+

+          List = List->ForwardLink;

+        }

+

+        HostBridgeInstance->ResourceSubmited = FALSE;

+        HostBridgeInstance->CanRestarted     = TRUE;

+      } else {

+        //

+        // Can not restart

+        //

+        return EFI_NOT_READY;

+      }

+

+      break;

+

+    case EfiPciHostBridgeEndEnumeration:

+      break;

+

+    case EfiPciHostBridgeBeginBusAllocation:

+      //

+      // No specific action is required here, can perform any chipset specific

+      // programing

+      //

+      HostBridgeInstance->CanRestarted = FALSE;

+      break;

+

+    case EfiPciHostBridgeEndBusAllocation:

+      //

+      // No specific action is required here, can perform any chipset specific

+      // programing

+      //

+      // HostBridgeInstance->CanRestarted = FALSE;

+      break;

+

+    case EfiPciHostBridgeBeginResourceAllocation:

+      //

+      // No specific action is required here, can perform any chipset specific

+      // programing

+      //

+      // HostBridgeInstance->CanRestarted = FALSE;

+      break;

+

+    case EfiPciHostBridgeAllocateResources:

+      ReturnStatus = EFI_SUCCESS;

+      if (HostBridgeInstance->ResourceSubmited) {

+        //

+        // Take care of the resource dependencies between the root bridges

+        //

+        List = HostBridgeInstance->Head.ForwardLink;

+

+        while (List != &HostBridgeInstance->Head) {

+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+          for (Index = TypeIo; Index < TypeBus; Index++) {

+            if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+              AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+

+              //

+              // Get the number of '1' in Alignment.

+              //

+              BitsOfAlignment =

+                (UINTN)(HighBitSet64 (

+                          RootBridgeInstance->ResAllocNode[Index].Alignment

+                          ) + 1);

+

+              switch (Index) {

+                case TypeIo:

+                  //

+                  // It is impossible for this chipset to align 0xFFFF for IO16

+                  // So clear it

+                  //

+                  if (BitsOfAlignment >= 16) {

+                    BitsOfAlignment = 0;

+                  }

+

+                  Status = gDS->AllocateIoSpace (

+                                  EfiGcdAllocateAnySearchBottomUp,

+                                  EfiGcdIoTypeIo,

+                                  BitsOfAlignment,

+                                  AddrLen,

+                                  &BaseAddress,

+                                  mDriverImageHandle,

+                                  NULL

+                                  );

+

+                  if (!EFI_ERROR (Status)) {

+                    RootBridgeInstance->ResAllocNode[Index].Base =

+                      (UINTN)BaseAddress;

+                    RootBridgeInstance->ResAllocNode[Index].Status =

+                      ResAllocated;

+                  } else {

+                    ReturnStatus = Status;

+                    if (Status != EFI_OUT_OF_RESOURCES) {

+                      RootBridgeInstance->ResAllocNode[Index].Length = 0;

+                    }

+                  }

+

+                  break;

+

+                case TypeMem32:

+                  //

+                  // It is impossible for this chipset to align 0xFFFFFFFF for

+                  // Mem32

+                  // So clear it

+                  //

+

+                  if (BitsOfAlignment >= 32) {

+                    BitsOfAlignment = 0;

+                  }

+

+                  Status = gDS->AllocateMemorySpace (

+                                  EfiGcdAllocateAnySearchBottomUp,

+                                  EfiGcdMemoryTypeMemoryMappedIo,

+                                  BitsOfAlignment,

+                                  AddrLen,

+                                  &BaseAddress,

+                                  mDriverImageHandle,

+                                  NULL

+                                  );

+

+                  if (!EFI_ERROR (Status)) {

+                    // We were able to allocate the PCI memory

+                    RootBridgeInstance->ResAllocNode[Index].Base =

+                      (UINTN)BaseAddress;

+                    RootBridgeInstance->ResAllocNode[Index].Status =

+                      ResAllocated;

+                  } else {

+                    // Not able to allocate enough PCI memory

+                    ReturnStatus = Status;

+

+                    if (Status != EFI_OUT_OF_RESOURCES) {

+                      RootBridgeInstance->ResAllocNode[Index].Length = 0;

+                    }

+

+                    ASSERT (FALSE);

+                  }

+

+                  break;

+

+                case TypePMem32:

+                case TypeMem64:

+                case TypePMem64:

+                  ReturnStatus = EFI_ABORTED;

+                  break;

+                default:

+                  ASSERT (FALSE);

+                  break;

+              }  // end switch

+            }

+          }

+

+          List = List->ForwardLink;

+        }

+

+        return ReturnStatus;

+      } else {

+        return EFI_NOT_READY;

+      }

+

+      break;

+

+    case EfiPciHostBridgeSetResources:

+      break;

+

+    case EfiPciHostBridgeFreeResources:

+      ReturnStatus = EFI_SUCCESS;

+      List         = HostBridgeInstance->Head.ForwardLink;

+      while (List != &HostBridgeInstance->Head) {

+        RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+        for (Index = TypeIo; Index < TypeBus; Index++) {

+          if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {

+            AddrLen     = RootBridgeInstance->ResAllocNode[Index].Length;

+            BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;

+            switch (Index) {

+              case TypeIo:

+                Status = gDS->FreeIoSpace (BaseAddress, AddrLen);

+                if (EFI_ERROR (Status)) {

+                  ReturnStatus = Status;

+                }

+

+                break;

+

+              case TypeMem32:

+                Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);

+                if (EFI_ERROR (Status)) {

+                  ReturnStatus = Status;

+                }

+

+                break;

+

+              case TypePMem32:

+                break;

+

+              case TypeMem64:

+                break;

+

+              case TypePMem64:

+                break;

+

+              default:

+                ASSERT (FALSE);

+                break;

+            } // end switch

+

+            RootBridgeInstance->ResAllocNode[Index].Type   = Index;

+            RootBridgeInstance->ResAllocNode[Index].Base   = 0;

+            RootBridgeInstance->ResAllocNode[Index].Length = 0;

+            RootBridgeInstance->ResAllocNode[Index].Status = ResNone;

+          }

+        }

+

+        List = List->ForwardLink;

+      }

+

+      HostBridgeInstance->ResourceSubmited = FALSE;

+      HostBridgeInstance->CanRestarted     = TRUE;

+      return ReturnStatus;

+

+    case EfiPciHostBridgeEndResourceAllocation:

+      HostBridgeInstance->CanRestarted = FALSE;

+      break;

+

+    default:

+      return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return the device handle of the next PCI root bridge that is associated with

+  this Host Bridge.

+

+  This function is called multiple times to retrieve the device handles of all

+  the PCI root bridges that are associated with this PCI host bridge. Each PCI

+  host bridge is associated with one or more PCI root bridges. On each call,

+  the handle that was returned by the previous call is passed into the

+  interface, and on output the interface returns the device handle of the next

+  PCI root bridge. The caller can use the handle to obtain the instance of the

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more

+  PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI

+  enumerator must enumerate the PCI root bridges in the order that they are

+  returned by this function.

+

+  For D945 implementation, there is only one root bridge in PCI host bridge.

+

+  @param[in]       This              The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI

+                                     root bridge.

+

+  @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then

+                                 return the first Rootbridge handle of the

+                                 specific Host bridge and return EFI_SUCCESS.

+

+  @retval EFI_NOT_FOUND          Can not find the any more root bridge in

+                                 specific host bridge.

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was

+                                 returned on a previous call to

+                                 GetNextRootBridge().

+**/

+EFI_STATUS

+EFIAPI

+GetNextRootBridge (

+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN OUT   EFI_HANDLE                                        *RootBridgeHandle

+  )

+{

+  BOOLEAN                   NoRootBridge;

+  LIST_ENTRY                *List;

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+

+  NoRootBridge       = TRUE;

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  while (List != &HostBridgeInstance->Head) {

+    NoRootBridge       = FALSE;

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (*RootBridgeHandle == NULL) {

+      //

+      // Return the first Root Bridge Handle of the Host Bridge

+      //

+      *RootBridgeHandle = RootBridgeInstance->Handle;

+      return EFI_SUCCESS;

+    } else {

+      if (*RootBridgeHandle == RootBridgeInstance->Handle) {

+        //

+        // Get next if have

+        //

+        List = List->ForwardLink;

+        if (List != &HostBridgeInstance->Head) {

+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+          *RootBridgeHandle  = RootBridgeInstance->Handle;

+          return EFI_SUCCESS;

+        } else {

+          return EFI_NOT_FOUND;

+        }

+      }

+    }

+

+    List = List->ForwardLink;

+  } // end while

+

+  if (NoRootBridge) {

+    return EFI_NOT_FOUND;

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+}

+

+/**

+  Returns the allocation attributes of a PCI root bridge.

+

+  The function returns the allocation attributes of a specific PCI root bridge.

+  The attributes can vary from one PCI root bridge to another. These attributes

+  are different from the decode-related attributes that are returned by the

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The

+  RootBridgeHandle parameter is used to specify the instance of the PCI root

+  bridge. The device handles of all the root bridges that are associated with

+  this host bridge must be obtained by calling GetNextRootBridge(). The

+  attributes are static in the sense that they do not change during or after

+  the enumeration process. The hardware may provide mechanisms to change the

+  attributes on the fly, but such changes must be completed before

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted

+  values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in

+  "Related Definitions" below. The caller uses these attributes to combine

+  multiple resource requests.

+

+  For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI

+  bus enumerator needs to include requests for the prefetchable memory in the

+  nonprefetchable memory pool and not request any prefetchable memory.

+

+  Attribute                             Description

+  ------------------------------------  ---------------------------------------

+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM  If this bit is set, then the PCI root

+                                        bridge does not support separate

+                                        windows for nonprefetchable and

+                                        prefetchable memory. A PCI bus driver

+                                        needs to include requests for

+                                        prefetchable memory in the

+                                        nonprefetchable memory pool.

+

+  EFI_PCI_HOST_BRIDGE_MEM64_DECODE      If this bit is set, then the PCI root

+                                        bridge supports 64-bit memory windows.

+                                        If this bit is not set, the PCI bus

+                                        driver needs to include requests for a

+                                        64-bit memory address in the

+                                        corresponding 32-bit memory pool.

+

+  @param[in]   This               The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in

+                                  which the caller is interested. Type

+                                  EFI_HANDLE is defined in

+                                  InstallProtocolInterface() in the UEFI 2.0

+                                  Specification.

+

+  @param[out]  Attributes         The pointer to attribte of root bridge, it is

+                                  output parameter

+

+  @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL

+

+  @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.

+

+  @retval EFI_SUCCESS             Success to get attribute of interested root

+                                  bridge.

+**/

+EFI_STATUS

+EFIAPI

+GetAttributes (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT UINT64                                            *Attributes

+  )

+{

+  LIST_ENTRY                *List;

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+

+  if (Attributes == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      *Attributes = RootBridgeInstance->RootBridgeAttrib;

+      return EFI_SUCCESS;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  //

+  // RootBridgeHandle is not an EFI_HANDLE

+  // that was returned on a previous call to GetNextRootBridge()

+  //

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  Sets up the specified PCI root bridge for the bus enumeration process.

+

+  This member function sets up the root bridge for bus enumeration and returns

+  the PCI bus range over which the search should be performed in ACPI 2.0

+  resource descriptor format.

+

+  @param[in]   This              The

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                                 instance.

+

+  @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.

+

+  @param[out]  Configuration     Pointer to the pointer to the PCI bus resource

+                                 descriptor.

+

+  @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle

+

+  @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.

+

+  @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.

+**/

+EFI_STATUS

+EFIAPI

+StartBusEnumeration (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT VOID                                              **Configuration

+  )

+{

+  LIST_ENTRY                *List;

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+  VOID                      *Buffer;

+  UINT8                     *Temp;

+  UINT64                    BusStart;

+  UINT64                    BusEnd;

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      //

+      // Set up the Root Bridge for Bus Enumeration

+      //

+      BusStart = RootBridgeInstance->BusBase;

+      BusEnd   = RootBridgeInstance->BusLimit;

+      //

+      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR

+      //

+

+      Buffer = AllocatePool (

+                 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +

+                 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)

+                 );

+      if (Buffer == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      Temp = (UINT8 *)Buffer;

+

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc                  = 0x8A;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len                   = 0x2B;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType               = 2;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag               = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag          = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity  = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin          = BusStart;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax          = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen               =

+        BusEnd - BusStart + 1;

+

+      Temp                                            = Temp + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc     = 0x79;

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;

+

+      *Configuration = Buffer;

+      return EFI_SUCCESS;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  Programs the PCI root bridge hardware so that it decodes the specified PCI

+  bus range.

+

+  This member function programs the specified PCI root bridge to decode the bus

+  range that is specified by the input parameter Configuration.

+  The bus range information is specified in terms of the ACPI 2.0 resource

+  descriptor format.

+

+  @param[in] This              The

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                               instance

+

+  @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be

+                               programmed

+

+  @param[in] Configuration     The pointer to the PCI bus resource descriptor

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                 handle.

+

+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI

+                                 2.0 resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI

+                                 2.0 bus resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource

+                                 descriptors other than bus descriptors.

+

+  @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid

+                                 ACPI resource descriptors.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this

+                                 root bridge.

+

+  @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+

+  @retval EFI_SUCCESS            The bus range for the PCI root bridge was

+                                 programmed.

+**/

+EFI_STATUS

+EFIAPI

+SetBusNumbers (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_HANDLE                                        RootBridgeHandle,

+  IN VOID                                              *Configuration

+  )

+{

+  LIST_ENTRY                *List;

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+  UINT8                     *Ptr;

+  UINTN                     BusStart;

+  UINTN                     BusEnd;

+  UINTN                     BusLen;

+

+  if (Configuration == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Ptr = Configuration;

+

+  //

+  // Check the Configuration is valid

+  //

+  if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  Ptr = Configuration;

+

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Desc;

+

+      Desc     = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;

+      BusStart = (UINTN)Desc->AddrRangeMin;

+      BusLen   = (UINTN)Desc->AddrLen;

+      BusEnd   = BusStart + BusLen - 1;

+

+      if (BusStart > BusEnd) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if ((BusStart < RootBridgeInstance->BusBase) ||

+          (BusEnd > RootBridgeInstance->BusLimit))

+      {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      //

+      // Update the Bus Range

+      //

+      RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;

+      RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;

+      RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;

+

+      //

+      // Program the Root Bridge Hardware

+      //

+

+      return EFI_SUCCESS;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  Submits the I/O and memory resource requirements for the specified PCI root

+  bridge.

+

+  This function is used to submit all the I/O and memory resources that are

+  required by the specified PCI root bridge. The input parameter Configuration

+  is used to specify the following:

+  - The various types of resources that are required

+  - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+  @param[in] This              Pointer to the

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                               instance.

+

+  @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory

+                               resource requirements are being submitted.

+

+  @param[in] Configuration     The pointer to the PCI I/O and PCI memory

+                               resource descriptor.

+

+  @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI

+                                 root bridge were accepted.

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                 handle.

+

+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI

+                                 2.0 resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or

+                                 more resource types that are not supported by

+                                 this PCI root bridge. This error will happen

+                                 if the caller did not combine resources

+                                 according to Attributes that were returned by

+                                 GetAllocAttributes().

+

+  @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for

+                                 this PCI root bridge.

+**/

+EFI_STATUS

+EFIAPI

+SubmitResources (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_HANDLE                                        RootBridgeHandle,

+  IN VOID                                              *Configuration

+  )

+{

+  LIST_ENTRY                         *List;

+  PCI_HOST_BRIDGE_INSTANCE           *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE           *RootBridgeInstance;

+  UINT8                              *Temp;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;

+  UINT64                             AddrLen;

+  UINT64                             Alignment;

+

+  //

+  // Check the input parameter: Configuration

+  //

+  if (Configuration == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  Temp = (UINT8 *)Configuration;

+  while ( *Temp == 0x8A) {

+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+  }

+

+  if (*Temp != 0x79) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Temp = (UINT8 *)Configuration;

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      while ( *Temp == 0x8A) {

+        Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;

+

+        //

+        // Check Address Length

+        //

+        if (Ptr->AddrLen > 0xffffffff) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        //

+        // Check address range alignment

+        //

+        if ((Ptr->AddrRangeMax >= 0xffffffff) ||

+            (Ptr->AddrRangeMax != (GetPowerOfTwo64 (

+                                     Ptr->AddrRangeMax + 1

+                                     ) - 1)))

+        {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        switch (Ptr->ResType) {

+          case 0:

+

+            //

+            // Check invalid Address Sapce Granularity

+            //

+            if (Ptr->AddrSpaceGranularity != 32) {

+              return EFI_INVALID_PARAMETER;

+            }

+

+            //

+            // check the memory resource request is supported by PCI root bridge

+            //

+            if ((RootBridgeInstance->RootBridgeAttrib ==

+                 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) &&

+                (Ptr->SpecificFlag == 0x06))

+            {

+              return EFI_INVALID_PARAMETER;

+            }

+

+            AddrLen   = Ptr->AddrLen;

+            Alignment = Ptr->AddrRangeMax;

+            if (Ptr->AddrSpaceGranularity == 32) {

+              if (Ptr->SpecificFlag == 0x06) {

+                //

+                // Apply from GCD

+                //

+                RootBridgeInstance->ResAllocNode[TypePMem32].Status =

+                  ResSubmitted;

+              } else {

+                RootBridgeInstance->ResAllocNode[TypeMem32].Length    = AddrLen;

+                RootBridgeInstance->ResAllocNode[TypeMem32].Alignment =

+                  Alignment;

+                RootBridgeInstance->ResAllocNode[TypeMem32].Status =

+                  ResRequested;

+                HostBridgeInstance->ResourceSubmited = TRUE;

+              }

+            }

+

+            if (Ptr->AddrSpaceGranularity == 64) {

+              if (Ptr->SpecificFlag == 0x06) {

+                RootBridgeInstance->ResAllocNode[TypePMem64].Status =

+                  ResSubmitted;

+              } else {

+                RootBridgeInstance->ResAllocNode[TypeMem64].Status =

+                  ResSubmitted;

+              }

+            }

+

+            break;

+

+          case 1:

+            AddrLen                                            = (UINTN)Ptr->AddrLen;

+            Alignment                                          = (UINTN)Ptr->AddrRangeMax;

+            RootBridgeInstance->ResAllocNode[TypeIo].Length    = AddrLen;

+            RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;

+            RootBridgeInstance->ResAllocNode[TypeIo].Status    = ResRequested;

+            HostBridgeInstance->ResourceSubmited               = TRUE;

+            break;

+

+          default:

+            break;

+        }

+

+        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+   Returns the proposed resource settings for the specified PCI root bridge.

+

+   This member function returns the proposed resource settings for the

+   specified PCI root bridge. The proposed resource settings are prepared when

+   NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.

+   The output parameter Configuration specifies the following:

+   - The various types of resources, excluding bus resources, that are

+     allocated

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in]  This              Pointer to the

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                                 instance.

+

+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is

+                                 defined in InstallProtocolInterface() in the

+                                 UEFI 2.0 Specification.

+

+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and

+                                 memory resource descriptor.

+

+   @retval EFI_SUCCESS            The requested parameters were returned.

+

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                  handle.

+

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                  lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+GetProposedResources (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT VOID                                              **Configuration

+  )

+{

+  LIST_ENTRY                         *List;

+  PCI_HOST_BRIDGE_INSTANCE           *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE           *RootBridgeInstance;

+  UINTN                              Index;

+  UINTN                              Number;

+  VOID                               *Buffer;

+  UINT8                              *Temp;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;

+  UINT64                             ResStatus;

+

+  Buffer = NULL;

+  Number = 0;

+  //

+  // Get the Host Bridge Instance from the resource allocation protocol

+  //

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  //

+  // Enumerate the root bridges in this host bridge

+  //

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      for (Index = 0; Index < TypeBus; Index++) {

+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+          Number++;

+        }

+      }

+

+      if (Number ==  0) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      Buffer = AllocateZeroPool (

+                 Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +

+                 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)

+                 );

+      if (Buffer == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      Temp = Buffer;

+      for (Index = 0; Index < TypeBus; Index++) {

+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+          Ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;

+          ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;

+

+          switch (Index) {

+            case TypeIo:

+              //

+              // Io

+              //

+              Ptr->Desc                  = 0x8A;

+              Ptr->Len                   = 0x2B;

+              Ptr->ResType               = 1;

+              Ptr->GenFlag               = 0;

+              Ptr->SpecificFlag          = 0;

+              Ptr->AddrRangeMin          = RootBridgeInstance->ResAllocNode[Index].Base;

+              Ptr->AddrRangeMax          = 0;

+              Ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ?

+                                           EFI_RESOURCE_SATISFIED :

+                                           EFI_RESOURCE_LESS;

+              Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+              break;

+

+            case TypeMem32:

+              //

+              // Memory 32

+              //

+              Ptr->Desc                  = 0x8A;

+              Ptr->Len                   = 0x2B;

+              Ptr->ResType               = 0;

+              Ptr->GenFlag               = 0;

+              Ptr->SpecificFlag          = 0;

+              Ptr->AddrSpaceGranularity  = 32;

+              Ptr->AddrRangeMin          = RootBridgeInstance->ResAllocNode[Index].Base;

+              Ptr->AddrRangeMax          = 0;

+              Ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ?

+                                           EFI_RESOURCE_SATISFIED :

+                                           EFI_RESOURCE_LESS;

+              Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+              break;

+

+            case TypePMem32:

+              //

+              // Prefetch memory 32

+              //

+              Ptr->Desc                  = 0x8A;

+              Ptr->Len                   = 0x2B;

+              Ptr->ResType               = 0;

+              Ptr->GenFlag               = 0;

+              Ptr->SpecificFlag          = 6;

+              Ptr->AddrSpaceGranularity  = 32;

+              Ptr->AddrRangeMin          = 0;

+              Ptr->AddrRangeMax          = 0;

+              Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;

+              Ptr->AddrLen               = 0;

+              break;

+

+            case TypeMem64:

+              //

+              // Memory 64

+              //

+              Ptr->Desc                  = 0x8A;

+              Ptr->Len                   = 0x2B;

+              Ptr->ResType               = 0;

+              Ptr->GenFlag               = 0;

+              Ptr->SpecificFlag          = 0;

+              Ptr->AddrSpaceGranularity  = 64;

+              Ptr->AddrRangeMin          = 0;

+              Ptr->AddrRangeMax          = 0;

+              Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;

+              Ptr->AddrLen               = 0;

+              break;

+

+            case TypePMem64:

+              //

+              // Prefetch memory 64

+              //

+              Ptr->Desc                  = 0x8A;

+              Ptr->Len                   = 0x2B;

+              Ptr->ResType               = 0;

+              Ptr->GenFlag               = 0;

+              Ptr->SpecificFlag          = 6;

+              Ptr->AddrSpaceGranularity  = 64;

+              Ptr->AddrRangeMin          = 0;

+              Ptr->AddrRangeMax          = 0;

+              Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;

+              Ptr->AddrLen               = 0;

+              break;

+          }

+

+          Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+        }

+      }

+

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc     = 0x79;

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;

+

+      *Configuration = Buffer;

+

+      return EFI_SUCCESS;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  Provides the hooks from the PCI bus driver to every PCI controller

+  (device/function) at various stages of the PCI enumeration process that allow

+  the host bridge driver to preinitialize individual PCI controllers before

+  enumeration.

+

+  This function is called during the PCI enumeration process. No specific

+  action is expected from this member function. It allows the host bridge

+  driver to preinitialize individual PCI controllers before enumeration.

+

+  @param This              Pointer to the

+                           EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                           instance.

+

+  @param RootBridgeHandle  The associated PCI root bridge handle. Type

+                           EFI_HANDLE is defined in InstallProtocolInterface()

+                           in the UEFI 2.0 Specification.

+

+  @param PciAddress        The address of the PCI device on the PCI bus. This

+                           address can be passed to the

+                           EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to

+                           access the PCI configuration space of the device.

+                           See Table 12-1 in the UEFI 2.0 Specification for the

+                           definition of

+                           EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.

+

+  @param Phase             The phase of the PCI device enumeration.

+

+  @retval EFI_SUCCESS              The requested parameters were returned.

+

+  @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge

+                                   handle.

+

+  @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined

+                                   in

+                                  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.

+

+  @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error.

+                                   The PCI enumerator should not enumerate this

+                                   device, including its child devices if it is

+                                   a PCI-to-PCI bridge.

+**/

+EFI_STATUS

+EFIAPI

+PreprocessController (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase

+  )

+{

+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;

+  LIST_ENTRY                *List;

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List               = HostBridgeInstance->Head.ForwardLink;

+

+  //

+  // Enumerate the root bridges in this host bridge

+  //

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      break;

+    }

+

+    List = List->ForwardLink;

+  }

+

+  if (List == &HostBridgeInstance->Head) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h

new file mode 100644

index 0000000000..a6a14e8bac

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h

@@ -0,0 +1,652 @@

+/** @file

+  Implementation of PciHostBridge.h

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  The Header file of the Pci Host Bridge Driver

+

+  Copyright (c) 2008 - 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.

+**/

+

+#ifndef _PCI_HOST_BRIDGE_H_

+#define _PCI_HOST_BRIDGE_H_

+

+#include <PiDxe.h>

+

+#include <IndustryStandard/Pci.h>

+#include <IndustryStandard/Acpi.h>

+

+#include <Protocol/PciHostBridgeResourceAllocation.h>

+#include <Protocol/PciRootBridgeIo.h>

+#include <Protocol/Metronome.h>

+#include <Protocol/DevicePath.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/IoLib.h>

+#include <Library/PciLib.h>

+

+//

+// Hard code the host bridge number in the platform.

+// In this chipset, there is only one host bridge.

+//

+#define HOST_BRIDGE_NUMBER  1

+

+#define MAX_PCI_DEVICE_NUMBER    31

+#define MAX_PCI_FUNCTION_NUMBER  7

+#define MAX_PCI_REG_ADDRESS      0xFF

+

+typedef enum {

+  IoOperation,

+  MemOperation,

+  PciOperation

+} OPERATION_TYPE;

+

+#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')

+typedef struct {

+  UINTN                                               Signature;

+  EFI_HANDLE                                          HostBridgeHandle;

+  UINTN                                               RootBridgeNumber;

+  LIST_ENTRY                                          Head;

+  BOOLEAN                                             ResourceSubmited;

+  BOOLEAN                                             CanRestarted;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL    ResAlloc;

+} PCI_HOST_BRIDGE_INSTANCE;

+

+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \

+  CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)

+

+//

+//  HostBridge Resource Allocation interface

+//

+

+/**

+  These are the notifications from the PCI bus driver that it is about to enter

+  a certain phase of the PCI enumeration process.

+

+  This member function can be used to notify the host bridge driver to perform

+  specific actions, including any chipset-specific initialization, so that the

+  chipset is ready to enter the next phase. Eight notification points are

+  defined at this time. See belows:

+

+  EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures

+                                         and internal data structures. The PCI

+                                         enumerator should issue this

+                                         notification before starting a fresh

+                                         enumeration process. Enumeration

+                                         cannot be restarted after sending any

+                                         other notification such as

+                                         EfiPciHostBridgeBeginBusAllocation.

+

+  EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to

+                                         begin. No specific action is required

+                                         here. This notification can be used to

+                                         perform any chipset-specific

+                                         programming.

+

+  EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming

+                                         phase is complete. No specific action

+                                         is required here. This notification

+                                         can be used to perform any

+                                         chipset-specific programming.

+

+  EfiPciHostBridgeBeginResourceAllocation

+                                         The resource allocation phase is about

+                                         to begin. No specific action is

+                                         required here. This notification can

+                                         be used to perform any

+                                         chipset-specific programming.

+

+  EfiPciHostBridgeAllocateResources      Allocates resources per previously

+                                         submitted requests for all the PCI

+                                         root bridges. These resource settings

+                                         are returned on the next call to

+                                         GetProposedResources(). Before calling

+                                         NotifyPhase() with a Phase of

+                                         EfiPciHostBridgeAllocateResource, the

+                                         PCI bus enumerator is responsible for

+                                         gathering I/O and memory requests for

+                                         all the PCI root bridges and

+                                         submitting these requests using

+                                         SubmitResources(). This function pads

+                                         the resource amount to suit the root

+                                         bridge hardware, takes care of

+                                         dependencies between the PCI root

+                                         bridges, and calls the Global

+                                         Coherency Domain (GCD) with the

+                                         allocation request. In the case of

+                                         padding, the allocated range could be

+                                         bigger than what was requested.

+

+  EfiPciHostBridgeSetResources           Programs the host bridge hardware to

+                                         decode previously allocated resources

+                                         (proposed resources) for all the PCI

+                                         root bridges. After the hardware is

+                                         programmed, reassigning resources will

+                                         not be supported. The bus settings are

+                                         not affected.

+

+  EfiPciHostBridgeFreeResources          Deallocates resources that were

+                                         previously allocated for all the PCI

+                                         root bridges and resets the I/O and

+                                         memory apertures to their initial

+                                         state. The bus settings are not

+                                         affected. If the request to allocate

+                                         resources fails, the PCI enumerator

+                                         can use this notification to

+                                         deallocate previous resources, adjust

+                                         the requests, and retry allocation.

+

+  EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is

+                                         completed. No specific action is

+                                         required here. This notification can

+                                         be used to perform any chipsetspecific

+                                         programming.

+

+  @param[in] This                The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in] Phase               The phase during enumeration

+

+  @retval EFI_NOT_READY          This phase cannot be entered at this time. For

+                                 example, this error is valid for a Phase of

+                                 EfiPciHostBridgeAllocateResources if

+                                 SubmitResources() has not been called for one

+                                 or more PCI root bridges before this call

+

+  @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+                                 This error is valid for a Phase of

+                                 EfiPciHostBridgeSetResources.

+

+  @retval EFI_INVALID_PARAMETER  Invalid phase parameter

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources. This error is valid for a

+                                 Phase of EfiPciHostBridgeAllocateResources if

+                                 the previously submitted resource requests

+                                 cannot be fulfilled or were only partially

+                                 fulfilled.

+

+  @retval EFI_SUCCESS            The notification was accepted without any

+                                 errors.

+**/

+EFI_STATUS

+EFIAPI

+NotifyPhase (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE     Phase

+  );

+

+/**

+  Return the device handle of the next PCI root bridge that is associated with

+  this Host Bridge.

+

+  This function is called multiple times to retrieve the device handles of all

+  the PCI root bridges that are associated with this PCI host bridge. Each PCI

+  host bridge is associated with one or more PCI root bridges. On each call,

+  the handle that was returned by the previous call is passed into the

+  interface, and on output the interface returns the device handle of the next

+  PCI root bridge. The caller can use the handle to obtain the instance of the

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more

+  PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI

+  enumerator must enumerate the PCI root bridges in the order that they are

+  returned by this function.

+

+  For D945 implementation, there is only one root bridge in PCI host bridge.

+

+  @param[in]       This              The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI

+                                     root bridge.

+

+  @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then

+                                 return the first Rootbridge handle of the

+                                 specific Host bridge and return EFI_SUCCESS.

+

+  @retval EFI_NOT_FOUND          Can not find the any more root bridge in

+                                 specific host bridge.

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was

+                                 returned on a previous call to

+                                 GetNextRootBridge().

+**/

+EFI_STATUS

+EFIAPI

+GetNextRootBridge (

+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN OUT   EFI_HANDLE                                        *RootBridgeHandle

+  );

+

+/**

+  Returns the allocation attributes of a PCI root bridge.

+

+  The function returns the allocation attributes of a specific PCI root bridge.

+  The attributes can vary from one PCI root bridge to another. These attributes

+  are different from the decode-related attributes that are returned by the

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The

+  RootBridgeHandle parameter is used to specify the instance of the PCI root

+  bridge. The device handles of all the root bridges that are associated with

+  this host bridge must be obtained by calling GetNextRootBridge(). The

+  attributes are static in the sense that they do not change during or after

+  the enumeration process. The hardware may provide mechanisms to change the

+  attributes on the fly, but such changes must be completed before

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted

+  values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in

+  "Related Definitions" below. The caller uses these attributes to combine

+  multiple resource requests.

+

+  For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI

+  bus enumerator needs to include requests for the prefetchable memory in the

+  nonprefetchable memory pool and not request any prefetchable memory.

+

+  Attribute                             Description

+  ------------------------------------  ---------------------------------------

+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM  If this bit is set, then the PCI root

+                                        bridge does not support separate

+                                        windows for nonprefetchable and

+                                        prefetchable memory. A PCI bus driver

+                                        needs to include requests for

+                                        prefetchable memory in the

+                                        nonprefetchable memory pool.

+

+  EFI_PCI_HOST_BRIDGE_MEM64_DECODE      If this bit is set, then the PCI root

+                                        bridge supports 64-bit memory windows.

+                                        If this bit is not set, the PCI bus

+                                        driver needs to include requests for a

+                                        64-bit memory address in the

+                                        corresponding 32-bit memory pool.

+

+  @param[in]   This               The instance pointer of

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+

+  @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in

+                                  which the caller is interested. Type

+                                  EFI_HANDLE is defined in

+                                  InstallProtocolInterface() in the UEFI 2.0

+                                  Specification.

+

+  @param[out]  Attributes         The pointer to attribte of root bridge, it is

+                                  output parameter

+

+  @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL

+

+  @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.

+

+  @retval EFI_SUCCESS             Success to get attribute of interested root

+                                  bridge.

+**/

+EFI_STATUS

+EFIAPI

+GetAttributes (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT UINT64                                            *Attributes

+  );

+

+/**

+  Sets up the specified PCI root bridge for the bus enumeration process.

+

+  This member function sets up the root bridge for bus enumeration and returns

+  the PCI bus range over which the search should be performed in ACPI 2.0

+  resource descriptor format.

+

+  @param[in]   This              The

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                                 instance.

+

+  @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.

+

+  @param[out]  Configuration     Pointer to the pointer to the PCI bus resource

+                                 descriptor.

+

+  @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle

+

+  @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.

+

+  @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.

+**/

+EFI_STATUS

+EFIAPI

+StartBusEnumeration (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT VOID                                              **Configuration

+  );

+

+/**

+  Programs the PCI root bridge hardware so that it decodes the specified PCI

+  bus range.

+

+  This member function programs the specified PCI root bridge to decode the bus

+  range that is specified by the input parameter Configuration.

+  The bus range information is specified in terms of the ACPI 2.0 resource

+  descriptor format.

+

+  @param[in] This              The

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                               instance

+

+  @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be

+                               programmed

+

+  @param[in] Configuration     The pointer to the PCI bus resource descriptor

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                 handle.

+

+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI

+                                 2.0 resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI

+                                 2.0 bus resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource

+                                 descriptors other than bus descriptors.

+

+  @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid

+                                 ACPI resource descriptors.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this

+                                 root bridge.

+

+  @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+

+  @retval EFI_SUCCESS            The bus range for the PCI root bridge was

+                                 programmed.

+**/

+EFI_STATUS

+EFIAPI

+SetBusNumbers (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_HANDLE                                        RootBridgeHandle,

+  IN VOID                                              *Configuration

+  );

+

+/**

+  Submits the I/O and memory resource requirements for the specified PCI root

+  bridge.

+

+  This function is used to submit all the I/O and memory resources that are

+  required by the specified PCI root bridge. The input parameter Configuration

+  is used to specify the following:

+  - The various types of resources that are required

+  - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+  @param[in] This              Pointer to the

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                               instance.

+

+  @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory

+                               resource requirements are being submitted.

+

+  @param[in] Configuration     The pointer to the PCI I/O and PCI memory

+                               resource descriptor.

+

+  @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI

+                                 root bridge were accepted.

+

+  @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                 handle.

+

+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI

+                                 2.0 resource descriptor.

+

+  @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or

+                                 more resource types that are not supported by

+                                 this PCI root bridge. This error will happen

+                                 if the caller did not combine resources

+                                 according to Attributes that were returned by

+                                 GetAllocAttributes().

+

+  @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.

+

+  @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for

+                                 this PCI root bridge.

+**/

+EFI_STATUS

+EFIAPI

+SubmitResources (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN EFI_HANDLE                                        RootBridgeHandle,

+  IN VOID                                              *Configuration

+  );

+

+/**

+   Returns the proposed resource settings for the specified PCI root bridge.

+

+   This member function returns the proposed resource settings for the

+   specified PCI root bridge. The proposed resource settings are prepared when

+   NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.

+   The output parameter Configuration specifies the following:

+   - The various types of resources, excluding bus resources, that are

+     allocated

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in]  This              Pointer to the

+                               EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                                 instance.

+

+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is

+                                 defined in InstallProtocolInterface() in the

+                                 UEFI 2.0 Specification.

+

+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and

+                                 memory resource descriptor.

+

+   @retval EFI_SUCCESS            The requested parameters were returned.

+

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge

+                                  handle.

+

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                  lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+GetProposedResources (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  OUT VOID                                              **Configuration

+  );

+

+/**

+  Provides the hooks from the PCI bus driver to every PCI controller

+  (device/function) at various stages of the PCI enumeration process that allow

+  the host bridge driver to preinitialize individual PCI controllers before

+  enumeration.

+

+  This function is called during the PCI enumeration process. No specific

+  action is expected from this member function. It allows the host bridge

+  driver to preinitialize individual PCI controllers before enumeration.

+

+  @param This              Pointer to the

+                           EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+                           instance.

+

+  @param RootBridgeHandle  The associated PCI root bridge handle. Type

+                           EFI_HANDLE is defined in InstallProtocolInterface()

+                           in the UEFI 2.0 Specification.

+

+  @param PciAddress        The address of the PCI device on the PCI bus. This

+                           address can be passed to the

+                           EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to

+                           access the PCI configuration space of the device.

+                           See Table 12-1 in the UEFI 2.0 Specification for the

+                           definition of

+                           EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.

+

+  @param Phase             The phase of the PCI device enumeration.

+

+  @retval EFI_SUCCESS              The requested parameters were returned.

+

+  @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge

+                                   handle.

+

+  @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined

+                                   in

+                                  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.

+

+  @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error.

+                                   The PCI enumerator should not enumerate this

+                                   device, including its child devices if it is

+                                   a PCI-to-PCI bridge.

+**/

+EFI_STATUS

+EFIAPI

+PreprocessController (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase

+  );

+

+//

+// Define resource status constant

+//

+#define EFI_RESOURCE_NONEXISTENT  0xFFFFFFFFFFFFFFFFULL

+#define EFI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL

+

+//

+// Driver Instance Data Prototypes

+//

+

+typedef struct {

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION    Operation;

+  UINTN                                        NumberOfBytes;

+  UINTN                                        NumberOfPages;

+  EFI_PHYSICAL_ADDRESS                         HostAddress;

+  EFI_PHYSICAL_ADDRESS                         MappedHostAddress;

+} MAP_INFO;

+

+typedef struct {

+  ACPI_HID_DEVICE_PATH        AcpiDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL    EndDevicePath;

+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;

+

+typedef struct {

+  UINT64    BusBase;

+  UINT64    BusLimit;

+

+  UINT64    MemBase;

+  UINT64    MemLimit;

+

+  UINT64    IoBase;

+  UINT64    IoLimit;

+} PCI_ROOT_BRIDGE_RESOURCE_APERTURE;

+

+typedef enum {

+  TypeIo = 0,

+  TypeMem32,

+  TypePMem32,

+  TypeMem64,

+  TypePMem64,

+  TypeBus,

+  TypeMax

+} PCI_RESOURCE_TYPE;

+

+typedef enum {

+  ResNone = 0,

+  ResSubmitted,

+  ResRequested,

+  ResAllocated,

+  ResStatusMax

+} RES_STATUS;

+

+typedef struct {

+  PCI_RESOURCE_TYPE    Type;

+  UINT64               Base;

+  UINT64               Length;

+  UINT64               Alignment;

+  RES_STATUS           Status;

+} PCI_RES_NODE;

+

+#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')

+

+typedef struct {

+  UINT32                             Signature;

+  LIST_ENTRY                         Link;

+  EFI_HANDLE                         Handle;

+  UINT64                             RootBridgeAttrib;

+  UINT64                             Attributes;

+  UINT64                             Supports;

+

+  //

+  // Specific for this memory controller: Bus, I/O, Mem

+  //

+  PCI_RES_NODE                       ResAllocNode[6];

+

+  //

+  // Addressing for Memory and I/O and Bus arrange

+  //

+  UINT64                             BusBase;

+  UINT64                             MemBase;

+  UINT64                             IoBase;

+  UINT64                             BusLimit;

+  UINT64                             MemLimit;

+  UINT64                             IoLimit;

+

+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    Io;

+} PCI_ROOT_BRIDGE_INSTANCE;

+

+//

+// Driver Instance Data Macros

+//

+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \

+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)

+

+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \

+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)

+

+/**

+

+  Construct the Pci Root Bridge Io protocol

+

+  @param Protocol         Point to protocol instance

+  @param HostBridgeHandle Handle of host bridge

+  @param Attri            Attribute of host bridge

+  @param ResAperture      ResourceAperture for host bridge

+

+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.

+**/

+EFI_STATUS

+RootBridgeConstructor (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,

+  IN EFI_HANDLE                         HostBridgeHandle,

+  IN UINT64                             Attri,

+  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *ResAperture

+  );

+

+#endif

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.uni b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.uni

new file mode 100644

index 0000000000000000000000000000000000000000..9b5bedb8fcb24ebee1ec579df5b028b9cfc5a995

GIT binary patch

literal 2558

zcmdUwU2hUW6o${WiT`0jZ`72f8ZS&^jI^L7)j|r5dS!qD-Gq;ZkJkQq^?A=SyM<um

zg%>uP-I+Oa<~?WL^Rd5vR;*%y_XSU|_cpZD#x}60_5`W+8aA<OmramQZE0QJ)Mm^B

z-yz?Y^^u&gTCjIyb5@r&LO-z;dTEYV;2xuWZFjCavMbI7duGS>obi<%@V;hN1?L8f

zQ!EUa2m1_KpHnmDHDouw9$<MNNy9Z0KRL$ha1VdsD`^gp-Z)-jZ}Ios-tF+P&An>&

z)ynp1ZDZ<Z%UHSOw75u}G2tD8eq?P<l<~dHO~&}WTAye+YuTB|K^%j#UvUo#SqDy1

zPKP`ufwg!TgDU&l>%)WQiiB7nxlR|IG28|iURjU1kgoj3!6TwGbM}`mm5rI7nc1x)

zjM&pDv7X&J$r*Y$U*xy^>2c$QBV>Lr-Qp0bFy(vtU}h~n!d>))GUaB<ORWaXV=gN9

zj)_Oevrkbd@-M)SR*LqVY>fQIG1z1CcX!?N^SU{(H?UFWRTaIYieg<T0;&ih%*hOW

zi(39SHB)5mHRv-UB^wj0s)kj+G2@g6%3gIB?cJ@T9FWK>#VchtCgMf3x=57;o4G06

zh_BOGMRdJ$sGoJc26Rr{Xgl{aTNBU8h$7FVnR<<Du8hsPUA#e7?P04s6u#bi1^4;N

zyUp9C+(L-L%Bozp)ID|U9)89itGE<dI%Fs7Yx4RBTH9W2GLx~XPSA7SROcB7@@aXG

zS#{tgu{iX;uil(hzVzo_vk7PCM6|NS{sKu4-!I9!P3s9LSG<vvIO;wpR>!Lry|-x}

z`Bv%d>fdd?H6J@j8&vZJ+I3`s*%@OUd4W(wp+RQX(P%qzlbQY>`j!}lEA$fMk*~Gd

z&wUH_g?;(ebc<S7u_VvVkT*aTM$@gIvy$(U$z}&F>BwrP^#NU-{Kk07jyzW-*4I|D

zTh#f#M4SS>0T(UuN;YddyO#df#UDew?&aB|UK#L0{Cx+h3C0CzbyijXM`@=DTOIWN

z^z3=v2x~>A=wBW@Bg$aO(-Nou-%elhxc)sa%BnVuDC1grBzJN1xOqv4n^@8N8}Q<j

As{jB1



literal 0

HcmV?d00001



diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf

new file mode 100644

index 0000000000..ac1d1e8afc

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf

@@ -0,0 +1,68 @@

+## @file

+# Platform Boot Manager Lib Module

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+# This file includes code originally published under the following license.

+## @file

+#  The basic interfaces implementation to a single segment PCI Host Bridge

+#  driver.

+#

+#  Copyright (c) 2008 - 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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PciHostBridge

+  MODULE_UNI_FILE                = PciHostBridge.uni

+  FILE_GUID                      = ACAB2797-6602-4B27-925F-B43483C630CE

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializePciHostBridge

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiDriverEntryPoint

+  UefiBootServicesTableLib

+  DxeServicesTableLib

+  UefiLib

+  MemoryAllocationLib

+  BaseMemoryLib

+  BaseLib

+  DebugLib

+  DevicePathLib

+  IoLib

+  PciLib

+

+[Sources]

+  PciHostBridge.c

+  PciRootBridgeIo.c

+  PciHostBridge.h

+  IoFifo.h

+

+[Protocols]

+  gEfiPciHostBridgeResourceAllocationProtocolGuid       ## PRODUCES

+  gEfiPciRootBridgeIoProtocolGuid                       ## PRODUCES

+  gEfiMetronomeArchProtocolGuid                         ## CONSUMES

+  gEfiDevicePathProtocolGuid                            ## PRODUCES

+

+[depex]

+  gEfiMetronomeArchProtocolGuid

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  PciHostBridgeExtra.uni

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeExtra.uni

new file mode 100644

index 0000000000000000000000000000000000000000..98b82859a26c32373a70cc7ba24082e60c51f8de

GIT binary patch

literal 1914

zcmb`IT~8BH5QgX4#Q$&tH)?3{>xvj7&{Z0RHZ4TFBHL2RCM`>rwunDoecstUyOe-e

zrrGl`XXc$b@64J0`Mqu17WiKA3--w_EVG$S?72Nds<W=m?b>B?<X5(^lrOWKbzr<;

z?AsX00lOQ{_N-ucZd3FV`-!B$rfo|svKqPZu#erf-MQ7&F3}J6!uIVY^ILn(_ny@*

zh%0ce@HJr_>=3juRypeqvX$>A#IS{=>zZx1oDqMxhkxTcX-<%?9ItI3h<solABk|t

z4Lf#fE&EpaxN_STUe2)=E17dAydBW@Y=}jR*jwCWM%>HFqVN2bHj#rk2hYQ{N6^TQ

z;UvR4)Y%E_#ls9#`PbPP9<)|Y#Q)TFQgmi;8(?^8Bi2H?^cx4yh-?bZ7cP~L+--8Z

zb%ZHrvJ&g%t=lz2|E`>;t0KT-4x*yV>{k`d&?`kZoBEBEYvoz>A%>sg?D6^;*Y)$p

z-qjT$6xD)k3OLc&)bszTmL^}<py%91KIV9hH;P=RaG<>Dh3V|BW_<2ZDKi<X8GJPL

zkRnx{*Rvv~BEGE4T1frP=uM}dec9<9KFqp!DTqUr6j2nJG&8Smt#w+y_;`b|&Xv#m

z71G3d>$N*(6z=+MGkgkBSY>_7mpX`UJtEH7XOx#<;#Kiqa8kZ#MXmnwFsgNC0{2S&

z4U8)Lyy8GHE$%U^-m@SVJKp=$mCBlzenIpTx|k|v%K5sF8zduQKj*!#pR_@_<cpld

zS@$`hKdO5UtY=>scj;;BTtmi=&&No+bdwXb6J&wa5p#mPL1?njrLq$=hK}50rOv5w

zgITyj-(cSJy>?r5Y{9;BuDE*cQTtsyDY7HvT~LM5bMFIoid{1KJVr}8@>*(rMpu?U

zn7?wO$km&Z%1e2Rgw7gq8uTt)^r<WP?7(~EEzS>n<z`(u>K}m!#NAoNZXc9EeS<Tw

zd!U|xpP+L@l!vT@z3Fd77)z={|6#$apoR9(H8#N9C$3Qc<B84YKTo+k1x>T0`hO|l

IT<G!p3rwXcGynhq



literal 0

HcmV?d00001



diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c

new file mode 100644

index 0000000000..7349d0c291

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c

@@ -0,0 +1,2686 @@

+/** @file

+  Implementation of PciRootBridgeIo.c

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  PCI Root Bridge Io Protocol implementation

+

+  Copyright (c) 2008 - 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.

+**/

+

+#include "PciHostBridge.h"

+#include "IoFifo.h"

+

+typedef struct {

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR    SpaceDesp[TypeMax];

+  EFI_ACPI_END_TAG_DESCRIPTOR          EndDesp;

+} RESOURCE_CONFIGURATION;

+

+RESOURCE_CONFIGURATION  Configuration = {

+  {

+    { 0x8A, 0x2B, 1, 0, 0, 0,  0, 0, 0, 0 },

+    { 0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0 },

+    { 0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0 },

+    { 0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0 },

+    { 0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0 },

+    { 0x8A, 0x2B, 2, 0, 0, 0,  0, 0, 0, 0 }

+  },

+  { 0x79, 0 }

+};

+

+//

+// Protocol Member Function Prototypes

+//

+

+/**

+  Polls an address in memory mapped I/O space until an exit condition is met,

+  or a timeout occurs.

+

+  This function provides a standard way to poll a PCI memory location. A PCI

+  memory read operation is performed at the PCI memory address specified by

+  Address for the width specified by Width. The result of this PCI memory read

+  operation is stored in Result. This PCI memory read operation is repeated

+  until either a timeout of Delay 100 ns units has expired, or (Result & Mask)

+  is equal to Value.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The base address of the memory operations. The caller

+                         is responsible for aligning Address if required.

+

+  @param[in]   Mask      Mask used for the polling criteria. Bytes above Width

+                         in Mask are ignored. The bits in the bytes below Width

+                         which are zero in Mask are ignored when polling the

+                         memory address.

+

+  @param[in]   Value     The comparison value used for the polling exit

+                         criteria.

+

+  @param[in]   Delay     The number of 100 ns units to poll. Note that timer

+                         available may be of poorer granularity.

+

+  @param[out]  Result    Pointer to the last value read from the memory

+                         location.

+

+  @retval EFI_SUCCESS            The last data returned from the access matched

+                                 the poll exit criteria.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid.

+

+  @retval EFI_INVALID_PARAMETER  Result is NULL.

+

+  @retval EFI_TIMEOUT            Delay expired before a match occurred.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollMem (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  );

+

+/**

+  Reads from the I/O space of a PCI Root Bridge. Returns when either the

+  polling exit criteria is satisfied or after a defined duration.

+

+  This function provides a standard way to poll a PCI I/O location. A PCI I/O

+  read operation is performed at the PCI I/O address specified by Address for

+  the width specified by Width. The result of this PCI I/O read operation is

+  stored in Result. This PCI I/O read operation is repeated until either a

+  timeout of Delay 100 ns units has expired, or (Result & Mask) is equal to

+  Value.

+

+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in] Width     Signifies the width of the I/O operations.

+

+  @param[in] Address   The base address of the I/O operations. The caller is

+                       responsible for aligning Address if required.

+

+  @param[in] Mask      Mask used for the polling criteria. Bytes above Width in

+                       Mask are ignored. The bits in the bytes below Width

+                       which are zero in Mask are ignored when polling the I/O

+                       address.

+

+  @param[in] Value     The comparison value used for the polling exit criteria.

+

+

+  @param[in] Delay     The number of 100 ns units to poll. Note that timer

+                       available may be of poorer granularity.

+

+  @param[out] Result   Pointer to the last value read from the memory location.

+

+  @retval EFI_SUCCESS            The last data returned from the access matched

+                                 the poll exit criteria.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid.

+

+  @retval EFI_INVALID_PARAMETER  Result is NULL.

+

+  @retval EFI_TIMEOUT            Delay expired before a match occurred.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollIo (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge memory space.

+

+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI

+  controller registers in the PCI root bridge memory space.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operation.

+

+  @param[in]   Address   The base address of the memory operation. The caller

+                         is responsible for aligning the Address if required.

+

+  @param[in]   Count     The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at Address.

+

+  @param[out]  Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge memory space.

+

+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI

+  controller registers in the PCI root bridge memory space.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operation.

+

+  @param[in]   Address   The base address of the memory operation. The caller

+                         is responsible for aligning the Address if required.

+

+  @param[in]   Count     The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at Address.

+

+  @param[in]   Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge I/O space.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width       Signifies the width of the memory operations.

+

+  @param[in]   UserAddress The base address of the I/O operation. The caller is

+                           responsible for aligning the Address if required.

+

+  @param[in]   Count       The number of I/O operations to perform. Bytes moved

+                           is Width size * Count, starting at Address.

+

+  @param[out]  UserBuffer  For read operations, the destination buffer to store

+                           the results. For write operations, the source buffer

+                           to write data from.

+

+

+  @retval EFI_SUCCESS              The data was read from or written to the PCI

+                                   root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 UserAddress,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *UserBuffer

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge I/O space.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width       Signifies the width of the memory operations.

+

+  @param[in]   UserAddress The base address of the I/O operation. The caller is

+                           responsible for aligning the Address if required.

+

+  @param[in]   Count       The number of I/O operations to perform. Bytes moved

+                           is Width size * Count, starting at Address.

+

+  @param[in]   UserBuffer  For read operations, the destination buffer to store

+                           the results. For write operations, the source buffer

+                           to write data from.

+

+

+  @retval EFI_SUCCESS              The data was read from or written to the PCI

+                                   root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 UserAddress,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *UserBuffer

+  );

+

+/**

+  Enables a PCI driver to copy one region of PCI root bridge memory space to

+  another region of PCI root bridge memory space.

+

+  The CopyMem() function enables a PCI driver to copy one region of PCI root

+  bridge memory space to another region of PCI root bridge memory space. This

+  is especially useful for video scroll operation on a memory mapped video

+  buffer.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI root bridge on a platform might require.

+

+  @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+                         instance.

+

+  @param[in] Width       Signifies the width of the memory operations.

+

+  @param[in] DestAddress The destination address of the memory operation. The

+                         caller is responsible for aligning the DestAddress if

+                         required.

+

+  @param[in] SrcAddress  The source address of the memory operation. The caller

+                         is responsible for aligning the SrcAddress if

+                         required.

+

+  @param[in] Count       The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at DestAddress

+                         and SrcAddress.

+

+

+  @retval  EFI_SUCCESS             The data was copied from one memory region

+                                   to another memory region.

+

+  @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.

+

+  @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoCopyMem (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 DestAddress,

+  IN     UINT64                                 SrcAddress,

+  IN     UINTN                                  Count

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in a PCI root

+  bridge's configuration space.

+

+  The Pci.Read() and Pci.Write() functions enable a driver to access PCI

+  configuration registers for a PCI controller.

+  The PCI Configuration operations are carried out exactly as requested. The

+  caller is responsible for any alignment and PCI configuration width issues

+  that a PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The address within the PCI configuration space for the

+                         PCI controller.

+

+  @param[in]   Count     The number of PCI configuration operations to perform.

+                         Bytes moved is Width size * Count, starting at

+                         Address.

+

+  @param[out]  Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  );

+

+/**

+  Enables a PCI driver to access PCI controller registers in a PCI root

+  bridge's configuration space.

+

+  The Pci.Read() and Pci.Write() functions enable a driver to access PCI

+  configuration registers for a PCI controller.

+  The PCI Configuration operations are carried out exactly as requested. The

+  caller is responsible for any alignment and PCI configuration width issues

+  that a PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The address within the PCI configuration space for the

+                         PCI controller.

+

+  @param[in]   Count     The number of PCI configuration operations to perform.

+                         Bytes moved is Width size * Count, starting at

+                         Address.

+

+  @param[in]   Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  );

+

+/**

+  Provides the PCI controller-specific addresses required to access system

+  memory from a DMA bus master.

+

+  The Map() function provides the PCI controller specific addresses needed to

+  access system memory. This function is used to map system memory for PCI bus

+  master DMA accesses.

+

+  @param[in]       This            A pointer to the

+                                   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]       Operation       Indicates if the bus master is going to read

+                                   or write to system memory.

+

+  @param[in]       HostAddress     The system memory address to map to the PCI

+                                   controller.

+

+  @param[in, out]  NumberOfBytes   On input the number of bytes to map. On

+                                   output the number of bytes that were mapped.

+

+  @param[out]      DeviceAddress   The resulting map address for the bus master

+                                   PCI controller to use to access the system

+                                   memory's HostAddress.

+

+  @param[out]      Mapping         The value to pass to Unmap() when the bus

+                                   master DMA operation is complete.

+

+  @retval EFI_SUCCESS            The range was mapped for the returned

+                                 NumberOfBytes.

+

+  @retval EFI_INVALID_PARAMETER  Operation is invalid.

+

+  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+

+  @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.

+

+  @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Mapping is NULL.

+

+  @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common

+                                 buffer.

+

+  @retval EFI_DEVICE_ERROR       The system hardware could not map the

+                                 requested address.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMap (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                                       *HostAddress,

+  IN OUT UINTN                                      *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,

+  OUT    VOID                                       **Mapping

+  );

+

+/**

+  Completes the Map() operation and releases any corresponding resources.

+

+  The Unmap() function completes the Map() operation and releases any

+  corresponding resources.

+  If the operation was an EfiPciOperationBusMasterWrite or

+  EfiPciOperationBusMasterWrite64, the data is committed to the target system

+  memory.

+  Any resources used for the mapping are freed.

+

+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in] Mapping   The mapping value returned from Map().

+

+  @retval EFI_SUCCESS            The range was unmapped.

+

+  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by

+                                 Map().

+

+  @retval EFI_DEVICE_ERROR       The data was not committed to the target

+                                 system memory.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoUnmap (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  VOID                             *Mapping

+  );

+

+/**

+  Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer

+  or EfiPciOperationBusMasterCommonBuffer64 mapping.

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Type        This parameter is not used and must be ignored.

+

+  @param MemoryType  The type of memory to allocate, EfiBootServicesData or

+                     EfiRuntimeServicesData.

+

+  @param Pages       The number of pages to allocate.

+

+  @param HostAddress A pointer to store the base system memory address of the

+                     allocated range.

+

+  @param Attributes  The requested bit mask of attributes for the allocated

+                     range. Only the attributes

+                     EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,

+                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and

+                     EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this

+                     function.

+

+  @retval EFI_SUCCESS            The requested memory pages were allocated.

+

+  @retval EFI_INVALID_PARAMETER  MemoryType is invalid.

+

+  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+

+  @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal

+                                 attribute bits are MEMORY_WRITE_COMBINE,

+                                 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.

+

+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoAllocateBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  EFI_ALLOCATE_TYPE                Type,

+  IN  EFI_MEMORY_TYPE                  MemoryType,

+  IN  UINTN                            Pages,

+  OUT VOID                             **HostAddress,

+  IN  UINT64                           Attributes

+  );

+

+/**

+  Frees memory that was allocated with AllocateBuffer().

+

+  The FreeBuffer() function frees memory that was allocated with

+  AllocateBuffer().

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Pages       The number of pages to free.

+

+  @param HostAddress The base system memory address of the allocated range.

+

+  @retval EFI_SUCCESS            The requested memory pages were freed.

+

+  @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and

+                                 Pages was not allocated with AllocateBuffer().

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFreeBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  UINTN                            Pages,

+  OUT VOID                             *HostAddress

+  );

+

+/**

+  Flushes all PCI posted write transactions from a PCI host bridge to system

+  memory.

+

+  The Flush() function flushes any PCI posted write transactions from a PCI

+  host bridge to system memory. Posted write transactions are generated by PCI

+  bus masters when they perform write transactions to target addresses in

+  system memory.

+  This function does not flush posted write transactions from any PCI bridges.

+  A PCI controller specific action must be taken to guarantee that the posted

+  write transactions have been flushed from the PCI controller and from all the

+  PCI bridges into the PCI host bridge. This is typically done with a PCI read

+  transaction from the PCI controller prior to calling Flush().

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @retval EFI_SUCCESS        The PCI posted write transactions were flushed

+                             from the PCI host bridge to system memory.

+

+  @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed

+                             from the PCI host bridge due to a hardware error.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFlush (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This

+  );

+

+/**

+  Gets the attributes that a PCI root bridge supports setting with

+  SetAttributes(), and the attributes that a PCI root bridge is currently

+  using.

+

+  The GetAttributes() function returns the mask of attributes that this PCI

+  root bridge supports and the mask of attributes that the PCI root bridge is

+  currently using.

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Supported   A pointer to the mask of attributes that this PCI root

+                     bridge supports setting with SetAttributes().

+

+  @param Attributes  A pointer to the mask of attributes that this PCI root

+                     bridge is currently using.

+

+

+  @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes

+                                 that the PCI root bridge supports is returned

+                                 in Supports. If Attributes is not NULL, then

+                                 the attributes that the PCI root bridge is

+                                 currently using is returned in Attributes.

+

+  @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoGetAttributes (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT UINT64                           *Supported,

+  OUT UINT64                           *Attributes

+  );

+

+/**

+  Sets attributes for a resource range on a PCI root bridge.

+

+  The SetAttributes() function sets the attributes specified in Attributes for

+  the PCI root bridge on the resource range specified by ResourceBase and

+  ResourceLength. Since the granularity of setting these attributes may vary

+  from resource type to resource type, and from platform to platform, the

+  actual resource range and the one passed in by the caller may differ. As a

+  result, this function may set the attributes specified by Attributes on a

+  larger resource range than the caller requested. The actual range is returned

+  in ResourceBase and ResourceLength. The caller is responsible for verifying

+  that the actual range for which the attributes were set is acceptable.

+

+  @param[in]       This            A pointer to the

+                                   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]       Attributes      The mask of attributes to set. If the

+                                   attribute bit MEMORY_WRITE_COMBINE,

+                                   MEMORY_CACHED, or MEMORY_DISABLE is set,

+                                   then the resource range is specified by

+                                   ResourceBase and ResourceLength. If

+                                   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and

+                                   MEMORY_DISABLE are not set, then

+                                   ResourceBase and ResourceLength are ignored,

+                                   and may be NULL.

+

+  @param[in, out]  ResourceBase    A pointer to the base address of the

+                                   resource range to be modified by the

+                                   attributes specified by Attributes.

+

+  @param[in, out]  ResourceLength  A pointer to the length of the resource

+                                   range to be modified by the attributes

+                                   specified by Attributes.

+

+  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge

+                           was returned in Resources.

+

+  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge

+                           could not be retrieved.

+

+  @retval  EFI_INVALID_PARAMETER Invalid pointer of

+                                 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoSetAttributes (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN     UINT64                           Attributes,

+  IN OUT UINT64                           *ResourceBase,

+  IN OUT UINT64                           *ResourceLength

+  );

+

+/**

+  Retrieves the current resource settings of this PCI root bridge in the form

+  of a set of ACPI 2.0 resource descriptors.

+

+  There are only two resource descriptor types from the ACPI Specification that

+  may be used to describe the current resources allocated to a PCI root bridge.

+  These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1),

+  and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space

+  Descriptor can describe memory, I/O, and bus number ranges for dynamic or

+  fixed resources. The configuration of a PCI root bridge is described with one

+  or more QWORD Address Space Descriptors followed by an End Tag.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that

+                           describe the current configuration of this PCI root

+                           bridge. The storage for the ACPI 2.0 resource

+                           descriptors is allocated by this function. The

+                           caller must treat the return buffer as read-only

+                           data, and the buffer must not be freed by the

+                           caller.

+

+  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge

+                           was returned in Resources.

+

+  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge

+                           could not be retrieved.

+

+  @retval  EFI_INVALID_PARAMETER Invalid pointer of

+                                 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoConfiguration (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT    VOID                             **Resources

+  );

+

+//

+// Memory Controller Pci Root Bridge Io Module Variables

+//

+EFI_METRONOME_ARCH_PROTOCOL  *mMetronome;

+

+//

+// Lookup table for increment values based on transfer widths

+//

+UINT8  mInStride[] = {

+  1, // EfiPciWidthUint8

+  2, // EfiPciWidthUint16

+  4, // EfiPciWidthUint32

+  8, // EfiPciWidthUint64

+  0, // EfiPciWidthFifoUint8

+  0, // EfiPciWidthFifoUint16

+  0, // EfiPciWidthFifoUint32

+  0, // EfiPciWidthFifoUint64

+  1, // EfiPciWidthFillUint8

+  2, // EfiPciWidthFillUint16

+  4, // EfiPciWidthFillUint32

+  8  // EfiPciWidthFillUint64

+};

+

+//

+// Lookup table for increment values based on transfer widths

+//

+UINT8  mOutStride[] = {

+  1, // EfiPciWidthUint8

+  2, // EfiPciWidthUint16

+  4, // EfiPciWidthUint32

+  8, // EfiPciWidthUint64

+  1, // EfiPciWidthFifoUint8

+  2, // EfiPciWidthFifoUint16

+  4, // EfiPciWidthFifoUint32

+  8, // EfiPciWidthFifoUint64

+  0, // EfiPciWidthFillUint8

+  0, // EfiPciWidthFillUint16

+  0, // EfiPciWidthFillUint32

+  0  // EfiPciWidthFillUint64

+};

+

+/**

+  Construct the Pci Root Bridge Io protocol

+

+  @param Protocol         Point to protocol instance

+

+  @param HostBridgeHandle Handle of host bridge

+

+  @param Attri            Attribute of host bridge

+

+  @param ResAperture      ResourceAperture for host bridge

+

+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.

+**/

+EFI_STATUS

+RootBridgeConstructor (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,

+  IN EFI_HANDLE                         HostBridgeHandle,

+  IN UINT64                             Attri,

+  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *ResAperture

+  )

+{

+  EFI_STATUS                Status;

+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;

+  PCI_RESOURCE_TYPE         Index;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);

+

+  //

+  // The host to pci bridge, the host memory and io addresses are

+  // direct mapped to pci addresses, so no need translate, set bases to 0.

+  //

+  PrivateData->MemBase = ResAperture->MemBase;

+  PrivateData->IoBase  = ResAperture->IoBase;

+

+  //

+  // The host bridge only supports 32bit addressing for memory

+  // and standard IA32 16bit io

+  //

+  PrivateData->MemLimit = ResAperture->MemLimit;

+  PrivateData->IoLimit  = ResAperture->IoLimit;

+

+  //

+  // Bus Aperture for this Root Bridge (Possible Range)

+  //

+  PrivateData->BusBase  = ResAperture->BusBase;

+  PrivateData->BusLimit = ResAperture->BusLimit;

+

+  //

+  // Specific for this chipset

+  //

+  for (Index = TypeIo; Index < TypeMax; Index++) {

+    PrivateData->ResAllocNode[Index].Type   = Index;

+    PrivateData->ResAllocNode[Index].Base   = 0;

+    PrivateData->ResAllocNode[Index].Length = 0;

+    PrivateData->ResAllocNode[Index].Status = ResNone;

+  }

+

+  PrivateData->RootBridgeAttrib = Attri;

+

+  PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |

+                          EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |

+                          EFI_PCI_ATTRIBUTE_ISA_IO_16 |

+                          EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |

+                          EFI_PCI_ATTRIBUTE_VGA_MEMORY |

+                          EFI_PCI_ATTRIBUTE_VGA_IO_16  |

+                          EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;

+  PrivateData->Attributes = PrivateData->Supports;

+

+  Protocol->ParentHandle = HostBridgeHandle;

+

+  Protocol->PollMem = RootBridgeIoPollMem;

+  Protocol->PollIo  = RootBridgeIoPollIo;

+

+  Protocol->Mem.Read  = RootBridgeIoMemRead;

+  Protocol->Mem.Write = RootBridgeIoMemWrite;

+

+  Protocol->Io.Read  = RootBridgeIoIoRead;

+  Protocol->Io.Write = RootBridgeIoIoWrite;

+

+  Protocol->CopyMem = RootBridgeIoCopyMem;

+

+  Protocol->Pci.Read  = RootBridgeIoPciRead;

+  Protocol->Pci.Write = RootBridgeIoPciWrite;

+

+  Protocol->Map   = RootBridgeIoMap;

+  Protocol->Unmap = RootBridgeIoUnmap;

+

+  Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;

+  Protocol->FreeBuffer     = RootBridgeIoFreeBuffer;

+

+  Protocol->Flush = RootBridgeIoFlush;

+

+  Protocol->GetAttributes = RootBridgeIoGetAttributes;

+  Protocol->SetAttributes = RootBridgeIoSetAttributes;

+

+  Protocol->Configuration = RootBridgeIoConfiguration;

+

+  Protocol->SegmentNumber = 0;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiMetronomeArchProtocolGuid,

+                  NULL,

+                  (VOID **)&mMetronome

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.

+

+  The I/O operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and I/O width restrictions that a PI

+  System on a platform might require. For example on some platforms, width

+  requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other

+  hand, will be handled by the driver.

+

+  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.

+

+  @param[in] Width          Signifies the width of the I/O or Memory operation.

+

+  @param[in] Address        The base address of the I/O operation.

+

+  @param[in] Count          The number of I/O operations to perform. The number

+                            of bytes moved is Width size * Count, starting at

+                            Address.

+

+  @param[in] Buffer         For read operations, the destination buffer to

+                            store the results. For write operations, the source

+                            buffer from which to write data.

+

+  @retval EFI_SUCCESS            The parameters for this request pass the

+                                 checks.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.

+

+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,

+                                 and Count is not valid for this PI system.

+**/

+EFI_STATUS

+RootBridgeIoCheckParameter (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN OPERATION_TYPE                         OperationType,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN UINT64                                 Address,

+  IN UINTN                                  Count,

+  IN VOID                                   *Buffer

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;

+  UINT64                                       MaxCount;

+  UINT64                                       Base;

+  UINT64                                       Limit;

+

+  //

+  // Check to see if Buffer is NULL

+  //

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check to see if Width is in the valid range

+  //

+  if ((UINT32)Width >= EfiPciWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // For FIFO type, the target address won't increase during the access,

+  // so treat Count as 1

+  //

+  if ((Width >= EfiPciWidthFifoUint8) && (Width <= EfiPciWidthFifoUint64)) {

+    Count = 1;

+  }

+

+  //

+  // Check to see if Width is in the valid range for I/O Port operations

+  //

+  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);

+  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {

+    ASSERT (FALSE);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check to see if Address is aligned

+  //

+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+

+  //

+  // Check to see if any address associated with this transfer exceeds the

+  // maximum allowed address.  The maximum address implied by the parameters

+  // passed in is Address + Size * Count.  If the following condition is met,

+  // then the transfer is not supported.

+  //

+  //    Address + Size * Count > Limit + 1

+  //

+  // Since Limit can be the maximum integer value supported by the CPU and

+  // Count can also be the maximum integer value supported by the CPU, this

+  // range check must be adjusted to avoid all oveflow conditions.

+  //

+  // The following form of the range check is equivalent but assumes that

+  // Limit is of the form (2^n - 1).

+  //

+  if (OperationType == IoOperation) {

+    Base  = PrivateData->IoBase;

+    Limit = PrivateData->IoLimit;

+  } else if (OperationType == MemOperation) {

+    Base  = PrivateData->MemBase;

+    Limit = PrivateData->MemLimit;

+  } else {

+    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;

+    if ((PciRbAddr->Bus < PrivateData->BusBase) ||

+        (PciRbAddr->Bus > PrivateData->BusLimit))

+    {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if ((PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER) ||

+        (PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER))

+    {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (PciRbAddr->ExtendedRegister != 0) {

+      Address = PciRbAddr->ExtendedRegister;

+    } else {

+      Address = PciRbAddr->Register;

+    }

+

+    Base  = 0;

+    Limit = MAX_PCI_REG_ADDRESS;

+  }

+

+  if (Address < Base) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Count == 0) {

+    if (Address > Limit) {

+      return EFI_UNSUPPORTED;

+    }

+  } else {

+    MaxCount = RShiftU64 (Limit, Width);

+    if (MaxCount < (Count - 1)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Internal help function for read and write memory space.

+

+  @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Write         Switch value for Read or Write.

+

+  @param[in]   Width         Signifies the width of the memory operations.

+

+  @param[in]   UserAddress   The address within the PCI configuration space for

+                             the PCI controller.

+

+  @param[in]   Count         The number of PCI configuration operations to

+                             perform. Bytes moved is Width size * Count,

+                             starting at Address.

+

+  @param[in, out] UserBuffer For read operations, the destination buffer to

+                             store the results. For write operations, the

+                             source buffer to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+RootBridgeIoMemRW (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     BOOLEAN                                Write,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN OUT VOID                                   *Buffer

+  )

+{

+  EFI_STATUS                             Status;

+  UINT8                                  InStride;

+  UINT8                                  OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;

+  UINT8                                  *Uint8Buffer;

+

+  Status = RootBridgeIoCheckParameter (

+             This,

+             MemOperation,

+             Width,

+             Address,

+             Count,

+             Buffer

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  InStride       = mInStride[Width];

+  OutStride      = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);

+  for (Uint8Buffer = Buffer;

+       Count > 0;

+       Address += InStride, Uint8Buffer += OutStride, Count--)

+  {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          MmioWrite8 ((UINTN)Address, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint64:

+          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = MmioRead8 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint64:

+          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Internal help function for read and write IO space.

+

+  @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Write         Switch value for Read or Write.

+

+  @param[in]   Width         Signifies the width of the memory operations.

+

+  @param[in]   UserAddress   The address within the PCI configuration space for

+                             the PCI controller.

+

+  @param[in]   Count         The number of PCI configuration operations to

+                             perform. Bytes moved is Width size * Count,

+                             starting at Address.

+

+  @param[in, out] UserBuffer For read operations, the destination buffer to

+                             store the results. For write operations, the

+                             source buffer to write data from.

+

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+RootBridgeIoIoRW (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     BOOLEAN                                Write,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN OUT VOID                                   *Buffer

+  )

+{

+  EFI_STATUS                             Status;

+  UINT8                                  InStride;

+  UINT8                                  OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;

+  UINT8                                  *Uint8Buffer;

+

+  Status = RootBridgeIoCheckParameter (

+             This,

+             IoOperation,

+             Width,

+             Address,

+             Count,

+             Buffer

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  InStride       = mInStride[Width];

+  OutStride      = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);

+

+ #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)

+  if (InStride == 0) {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoWriteFifo8 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint16:

+          IoWriteFifo16 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint32:

+          IoWriteFifo32 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoReadFifo8 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint16:

+          IoReadFifo16 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint32:

+          IoReadFifo32 ((UINTN)Address, Count, Buffer);

+          return EFI_SUCCESS;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+

+ #endif

+

+  for (Uint8Buffer = Buffer;

+       Count > 0;

+       Address += InStride, Uint8Buffer += OutStride, Count--)

+  {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoWrite8 ((UINTN)Address, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = IoRead8 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Internal help function for read and write PCI configuration space.

+

+  @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Write         Switch value for Read or Write.

+

+  @param[in]   Width         Signifies the width of the memory operations.

+

+  @param[in]   UserAddress   The address within the PCI configuration space for

+                             the PCI controller.

+

+  @param[in]   Count         The number of PCI configuration operations to

+                             perform. Bytes moved is Width size * Count,

+                             starting at Address.

+

+  @param[in, out] UserBuffer For read operations, the destination buffer to

+                             store the results. For write operations, the

+                             source buffer to write data from.

+

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+RootBridgeIoPciRW (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN BOOLEAN                                Write,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN UINT64                                 Address,

+  IN UINTN                                  Count,

+  IN OUT VOID                               *Buffer

+  )

+{

+  EFI_STATUS                                   Status;

+  UINT8                                        InStride;

+  UINT8                                        OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        OperationWidth;

+  UINT8                                        *Uint8Buffer;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;

+  UINTN                                        PcieRegAddr;

+

+  Status = RootBridgeIoCheckParameter (

+             This,

+             PciOperation,

+             Width,

+             Address,

+             Count,

+             Buffer

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;

+

+  PcieRegAddr = (UINTN)PCI_LIB_ADDRESS (

+                         PciRbAddr->Bus,

+                         PciRbAddr->Device,

+                         PciRbAddr->Function,

+                         (PciRbAddr->ExtendedRegister != 0) ? \

+                         PciRbAddr->ExtendedRegister :

+                         PciRbAddr->Register

+                         );

+

+  InStride       = mInStride[Width];

+  OutStride      = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);

+  for (Uint8Buffer = Buffer;

+       Count > 0;

+       PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--)

+  {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          PciWrite8 (PcieRegAddr, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = PciRead8 (PcieRegAddr);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Polls an address in memory mapped I/O space until an exit condition is met,

+  or a timeout occurs.

+

+  This function provides a standard way to poll a PCI memory location. A PCI

+  memory read operation is performed at the PCI memory address specified by

+  Address for the width specified by Width. The result of this PCI memory read

+  operation is stored in Result. This PCI memory read operation is repeated

+  until either a timeout of Delay 100 ns units has expired, or (Result & Mask)

+  is equal to Value.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The base address of the memory operations. The caller

+                         is responsible for aligning Address if required.

+

+  @param[in]   Mask      Mask used for the polling criteria. Bytes above Width

+                         in Mask are ignored. The bits in the bytes below Width

+                         which are zero in Mask are ignored when polling the

+                         memory address.

+

+  @param[in]   Value     The comparison value used for the polling exit

+                         criteria.

+

+  @param[in]   Delay     The number of 100 ns units to poll. Note that timer

+                         available may be of poorer granularity.

+

+  @param[out]  Result    Pointer to the last value read from the memory

+                         location.

+

+  @retval EFI_SUCCESS            The last data returned from the access matched

+                                 the poll exit criteria.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid.

+

+  @retval EFI_INVALID_PARAMETER  Result is NULL.

+

+  @retval EFI_TIMEOUT            Delay expired before a match occurred.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollMem (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      NumberOfTicks;

+  UINT32      Remainder;

+

+  if (Result == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // No matter what, always do a single poll.

+  //

+  Status = This->Mem.Read (This, Width, Address, 1, Result);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if ((*Result & Mask) == Value) {

+    return EFI_SUCCESS;

+  }

+

+  if (Delay == 0) {

+    return EFI_SUCCESS;

+  } else {

+    //

+    // Determine the proper # of metronome ticks to wait for polling the

+    // location.  The nuber of ticks is Roundup (Delay /

+    // mMetronome->TickPeriod)+1

+    // The "+1" to account for the possibility of the first tick being short

+    // because we started in the middle of a tick.

+    //

+    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome

+    // protocol definition is updated.

+    //

+    NumberOfTicks = DivU64x32Remainder (

+                      Delay,

+                      (UINT32)mMetronome->TickPeriod,

+                      &Remainder

+                      );

+    if (Remainder != 0) {

+      NumberOfTicks += 1;

+    }

+

+    NumberOfTicks += 1;

+

+    while (NumberOfTicks != 0) {

+      mMetronome->WaitForTick (mMetronome, 1);

+

+      Status = This->Mem.Read (This, Width, Address, 1, Result);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      if ((*Result & Mask) == Value) {

+        return EFI_SUCCESS;

+      }

+

+      NumberOfTicks -= 1;

+    }

+  }

+

+  return EFI_TIMEOUT;

+}

+

+/**

+  Reads from the I/O space of a PCI Root Bridge. Returns when either the

+  polling exit criteria is satisfied or after a defined duration.

+

+  This function provides a standard way to poll a PCI I/O location. A PCI I/O

+  read operation is performed at the PCI I/O address specified by Address for

+  the width specified by Width.

+  The result of this PCI I/O read operation is stored in Result. This PCI I/O

+  read operation is repeated until either a timeout of Delay 100 ns units has

+  expired, or (Result & Mask) is equal to Value.

+

+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in] Width     Signifies the width of the I/O operations.

+

+  @param[in] Address   The base address of the I/O operations. The caller is

+                       responsible for aligning Address if required.

+

+  @param[in] Mask      Mask used for the polling criteria. Bytes above Width in

+                       Mask are ignored. The bits in the bytes below Width

+                       which are zero in Mask are ignored when polling the I/O

+                       address.

+

+  @param[in] Value     The comparison value used for the polling exit criteria.

+

+  @param[in] Delay     The number of 100 ns units to poll. Note that timer

+                       available may be of poorer granularity.

+

+  @param[out] Result   Pointer to the last value read from the memory location.

+

+  @retval EFI_SUCCESS            The last data returned from the access matched

+                                 the poll exit criteria.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid.

+

+  @retval EFI_INVALID_PARAMETER  Result is NULL.

+

+  @retval EFI_TIMEOUT            Delay expired before a match occurred.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollIo (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      NumberOfTicks;

+  UINT32      Remainder;

+

+  //

+  // No matter what, always do a single poll.

+  //

+

+  if (Result == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = This->Io.Read (This, Width, Address, 1, Result);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if ((*Result & Mask) == Value) {

+    return EFI_SUCCESS;

+  }

+

+  if (Delay == 0) {

+    return EFI_SUCCESS;

+  } else {

+    //

+    // Determine the proper # of metronome ticks to wait for polling the

+    // location.  The number of ticks is Roundup (Delay /

+    // mMetronome->TickPeriod)+1

+    // The "+1" to account for the possibility of the first tick being short

+    // because we started in the middle of a tick.

+    //

+    NumberOfTicks = DivU64x32Remainder (

+                      Delay,

+                      (UINT32)mMetronome->TickPeriod,

+                      &Remainder

+                      );

+    if (Remainder != 0) {

+      NumberOfTicks += 1;

+    }

+

+    NumberOfTicks += 1;

+

+    while (NumberOfTicks != 0) {

+      mMetronome->WaitForTick (mMetronome, 1);

+

+      Status = This->Io.Read (This, Width, Address, 1, Result);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      if ((*Result & Mask) == Value) {

+        return EFI_SUCCESS;

+      }

+

+      NumberOfTicks -= 1;

+    }

+  }

+

+  return EFI_TIMEOUT;

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge memory space.

+

+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI

+  controller registers in the PCI root bridge memory space.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operation.

+

+  @param[in]   Address   The base address of the memory operation. The caller

+                         is responsible for aligning the Address if required.

+

+  @param[in]   Count     The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at Address.

+

+  @param[out]  Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge memory space.

+

+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI

+  controller registers in the PCI root bridge memory space.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operation.

+

+  @param[in]   Address   The base address of the memory operation. The caller

+                         is responsible for aligning the Address if required.

+

+  @param[in]   Count     The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at Address.

+

+  @param[in]   Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge I/O space.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width       Signifies the width of the memory operations.

+

+  @param[in]   Address     The base address of the I/O operation. The caller is

+                           responsible for aligning the Address if required.

+

+  @param[in]   Count       The number of I/O operations to perform. Bytes moved

+                           is Width size * Count, starting at Address.

+

+  @param[out]  Buffer      For read operations, the destination buffer to store

+                           the results. For write operations, the source buffer

+                           to write data from.

+

+

+  @retval EFI_SUCCESS              The data was read from or written to the PCI

+                                   root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in the PCI root

+  bridge I/O space.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width       Signifies the width of the memory operations.

+

+  @param[in]   Address     The base address of the I/O operation. The caller is

+                           responsible for aligning the Address if required.

+

+  @param[in]   Count       The number of I/O operations to perform. Bytes moved

+                           is Width size * Count, starting at Address.

+

+  @param[in]   Buffer      For read operations, the destination buffer to store

+                           the results. For write operations, the source buffer

+                           to write data from.

+

+  @retval EFI_SUCCESS              The data was read from or written to the PCI

+                                   root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoWrite (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN       UINT64                                 Address,

+  IN       UINTN                                  Count,

+  IN       VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);

+}

+

+/**

+  Enables a PCI driver to copy one region of PCI root bridge memory space to

+  another region of PCI root bridge memory space.

+

+  The CopyMem() function enables a PCI driver to copy one region of PCI root

+  bridge memory space to another region of PCI root bridge memory space. This

+  is especially useful for video scroll operation on a memory mapped video

+  buffer.

+  The memory operations are carried out exactly as requested. The caller is

+  responsible for satisfying any alignment and memory width restrictions that a

+  PCI root bridge on a platform might require.

+

+  @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+                         instance.

+

+  @param[in] Width       Signifies the width of the memory operations.

+

+  @param[in] DestAddress The destination address of the memory operation. The

+                         caller is responsible for aligning the DestAddress if

+                         required.

+

+  @param[in] SrcAddress  The source address of the memory operation. The caller

+                         is responsible for aligning the SrcAddress if

+                         required.

+

+  @param[in] Count       The number of memory operations to perform. Bytes

+                         moved is Width size * Count, starting at DestAddress

+                         and SrcAddress.

+

+  @retval  EFI_SUCCESS             The data was copied from one memory region

+                                   to another memory region.

+

+  @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.

+

+  @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a

+                                   lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoCopyMem (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN UINT64                                 DestAddress,

+  IN UINT64                                 SrcAddress,

+  IN UINTN                                  Count

+  )

+{

+  EFI_STATUS  Status;

+  BOOLEAN     Direction;

+  UINTN       Stride;

+  UINTN       Index;

+  UINT64      Result;

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (DestAddress == SrcAddress) {

+    return EFI_SUCCESS;

+  }

+

+  Stride = (UINTN)(1 << Width);

+

+  Direction = TRUE;

+  if ((DestAddress > SrcAddress) &&

+      (DestAddress < (SrcAddress + Count * Stride)))

+  {

+    Direction   = FALSE;

+    SrcAddress  = SrcAddress  + (Count-1) * Stride;

+    DestAddress = DestAddress + (Count-1) * Stride;

+  }

+

+  for (Index = 0; Index < Count; Index++) {

+    Status = RootBridgeIoMemRead (

+               This,

+               Width,

+               SrcAddress,

+               1,

+               &Result

+               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = RootBridgeIoMemWrite (

+               This,

+               Width,

+               DestAddress,

+               1,

+               &Result

+               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    if (Direction) {

+      SrcAddress  += Stride;

+      DestAddress += Stride;

+    } else {

+      SrcAddress  -= Stride;

+      DestAddress -= Stride;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in a PCI root

+  bridge's configuration space.

+

+  The Pci.Read() and Pci.Write() functions enable a driver to access PCI

+  configuration registers for a PCI controller.

+  The PCI Configuration operations are carried out exactly as requested. The

+  caller is responsible for any alignment and PCI configuration width issues

+  that a PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The address within the PCI configuration space for the

+                         PCI controller.

+

+  @param[in]   Count     The number of PCI configuration operations to perform.

+                         Bytes moved is Width size * Count, starting at

+                         Address.

+

+  @param[out]  Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciRead (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN       UINT64                                 Address,

+  IN       UINTN                                  Count,

+  OUT      VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);

+}

+

+/**

+  Enables a PCI driver to access PCI controller registers in a PCI root

+  bridge's configuration space.

+

+  The Pci.Read() and Pci.Write() functions enable a driver to access PCI

+  configuration registers for a PCI controller.

+  The PCI Configuration operations are carried out exactly as requested. The

+  caller is responsible for any alignment and PCI configuration width issues

+  that a PCI Root Bridge on a platform might require.

+

+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]   Width     Signifies the width of the memory operations.

+

+  @param[in]   Address   The address within the PCI configuration space for the

+                         PCI controller.

+

+  @param[in]   Count     The number of PCI configuration operations to perform.

+                         Bytes moved is Width size * Count, starting at

+                         Address.

+

+  @param[in]   Buffer    For read operations, the destination buffer to store

+                         the results. For write operations, the source buffer

+                         to write data from.

+

+  @retval EFI_SUCCESS            The data was read from or written to the PCI

+                                 root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciWrite (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN       UINT64                                 Address,

+  IN       UINTN                                  Count,

+  IN       VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);

+}

+

+/**

+  Provides the PCI controller-specific addresses required to access system

+  memory from a DMA bus master.

+

+  The Map() function provides the PCI controller specific addresses needed to

+  access system memory. This function is used to map system memory for PCI bus

+  master DMA accesses.

+

+  @param[in]       This            A pointer to the

+                                   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]       Operation       Indicates if the bus master is going to read

+                                   or write to system memory.

+

+  @param[in]       HostAddress     The system memory address to map to the PCI

+                                   controller.

+

+  @param[in, out]  NumberOfBytes   On input the number of bytes to map. On

+                                   output the number of bytes that were mapped.

+

+  @param[out]      DeviceAddress   The resulting map address for the bus master

+                                   PCI controller to use to access the system

+                                   memory's HostAddress.

+

+  @param[out]      Mapping         The value to pass to Unmap() when the bus

+                                   master DMA operation is complete.

+

+  @retval EFI_SUCCESS            The range was mapped for the returned

+                                 NumberOfBytes.

+

+  @retval EFI_INVALID_PARAMETER  Operation is invalid.

+

+  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+

+  @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.

+

+  @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.

+

+  @retval EFI_INVALID_PARAMETER  Mapping is NULL.

+

+  @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common

+                                 buffer.

+

+  @retval EFI_DEVICE_ERROR       The system hardware could not map the

+                                 requested address.

+

+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a

+                                 lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMap (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                                       *HostAddress,

+  IN OUT UINTN                                      *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,

+  OUT    VOID                                       **Mapping

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;

+  MAP_INFO              *MapInfo;

+

+  if ((HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) ||

+      (Mapping == NULL))

+  {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Initialize the return values to their defaults

+  //

+  *Mapping = NULL;

+

+  //

+  // Make sure that Operation is valid

+  //

+  if ((UINT32)Operation >= EfiPciOperationMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Most PCAT like chipsets can not handle performing DMA above 4GB.

+  // If any part of the DMA transfer being mapped is above 4GB, then

+  // map the DMA transfer to a buffer below 4GB.

+  //

+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;

+  if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {

+    //

+    // Common Buffer operations can not be remapped.  If the common buffer

+    // if above 4GB, then it is not possible to generate a mapping, so return

+    // an error.

+    //

+    if ((Operation == EfiPciOperationBusMasterCommonBuffer) ||

+        (Operation == EfiPciOperationBusMasterCommonBuffer64))

+    {

+      return EFI_UNSUPPORTED;

+    }

+

+    //

+    // Allocate a MAP_INFO structure to remember the mapping when Unmap() is

+    // called later.

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (MAP_INFO),

+                    (VOID **)&MapInfo

+                    );

+    if (EFI_ERROR (Status)) {

+      *NumberOfBytes = 0;

+      return Status;

+    }

+

+    //

+    // Return a pointer to the MAP_INFO structure in Mapping

+    //

+    *Mapping = MapInfo;

+

+    //

+    // Initialize the MAP_INFO structure

+    //

+    MapInfo->Operation         = Operation;

+    MapInfo->NumberOfBytes     = *NumberOfBytes;

+    MapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES (*NumberOfBytes);

+    MapInfo->HostAddress       = PhysicalAddress;

+    MapInfo->MappedHostAddress = 0x00000000ffffffff;

+

+    //

+    // Allocate a buffer below 4GB to map the transfer to.

+    //

+    Status = gBS->AllocatePages (

+                    AllocateMaxAddress,

+                    EfiBootServicesData,

+                    MapInfo->NumberOfPages,

+                    &MapInfo->MappedHostAddress

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (MapInfo);

+      *NumberOfBytes = 0;

+      return Status;

+    }

+

+    //

+    // If this is a read operation from the Bus Master's point of view,

+    // then copy the contents of the real buffer into the mapped buffer

+    // so the Bus Master can read the contents of the real buffer.

+    //

+    if ((Operation == EfiPciOperationBusMasterRead) ||

+        (Operation == EfiPciOperationBusMasterRead64))

+    {

+      CopyMem (

+        (VOID *)(UINTN)MapInfo->MappedHostAddress,

+        (VOID *)(UINTN)MapInfo->HostAddress,

+        MapInfo->NumberOfBytes

+        );

+    }

+

+    //

+    // The DeviceAddress is the address of the maped buffer below 4GB

+    //

+    *DeviceAddress = MapInfo->MappedHostAddress;

+  } else {

+    //

+    // The transfer is below 4GB, so the DeviceAddress is simply the

+    // HostAddress

+    //

+    *DeviceAddress = PhysicalAddress;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Completes the Map() operation and releases any corresponding resources.

+

+  The Unmap() function completes the Map() operation and releases any

+  corresponding resources.

+  If the operation was an EfiPciOperationBusMasterWrite or

+  EfiPciOperationBusMasterWrite64, the data is committed to the target system

+  memory.

+  Any resources used for the mapping are freed.

+

+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in] Mapping   The mapping value returned from Map().

+

+  @retval EFI_SUCCESS            The range was unmapped.

+

+  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by

+                                 Map().

+

+  @retval EFI_DEVICE_ERROR       The data was not committed to the target

+                                 system memory.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoUnmap (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN VOID                             *Mapping

+  )

+{

+  MAP_INFO  *MapInfo;

+

+  //

+  // See if the Map() operation associated with this Unmap() required a mapping

+  // buffer. If a mapping buffer was not required, then this function simply

+  // returns EFI_SUCCESS.

+  //

+  if (Mapping != NULL) {

+    //

+    // Get the MAP_INFO structure from Mapping

+    //

+    MapInfo = (MAP_INFO *)Mapping;

+

+    //

+    // If this is a write operation from the Bus Master's point of view,

+    // then copy the contents of the mapped buffer into the real buffer

+    // so the processor can read the contents of the real buffer.

+    //

+    if ((MapInfo->Operation == EfiPciOperationBusMasterWrite) ||

+        (MapInfo->Operation == EfiPciOperationBusMasterWrite64))

+    {

+      CopyMem (

+        (VOID *)(UINTN)MapInfo->HostAddress,

+        (VOID *)(UINTN)MapInfo->MappedHostAddress,

+        MapInfo->NumberOfBytes

+        );

+    }

+

+    //

+    // Free the mapped buffer and the MAP_INFO structure.

+    //

+    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);

+    gBS->FreePool (Mapping);

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer

+  or EfiPciOperationBusMasterCommonBuffer64 mapping.

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Type        This parameter is not used and must be ignored.

+

+  @param MemoryType  The type of memory to allocate, EfiBootServicesData or

+                     EfiRuntimeServicesData.

+

+  @param Pages       The number of pages to allocate.

+

+  @param HostAddress A pointer to store the base system memory address of the

+                     allocated range.

+

+  @param Attributes  The requested bit mask of attributes for the allocated

+                     range. Only the attributes

+                     EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,

+                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and

+                     EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this

+                     function.

+

+  @retval EFI_SUCCESS            The requested memory pages were allocated.

+

+  @retval EFI_INVALID_PARAMETER  MemoryType is invalid.

+

+  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+

+  @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal

+                                 attribute bits are MEMORY_WRITE_COMBINE,

+                                 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.

+

+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoAllocateBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  EFI_ALLOCATE_TYPE                Type,

+  IN  EFI_MEMORY_TYPE                  MemoryType,

+  IN  UINTN                            Pages,

+  OUT VOID                             **HostAddress,

+  IN  UINT64                           Attributes

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;

+

+  //

+  // Validate Attributes

+  //

+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Check for invalid inputs

+  //

+  if (HostAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // The only valid memory types are EfiBootServicesData and

+  // EfiRuntimeServicesData

+  //

+  if ((MemoryType != EfiBootServicesData) &&

+      (MemoryType != EfiRuntimeServicesData))

+  {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Limit allocations to memory below 4GB

+  //

+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);

+

+  Status = gBS->AllocatePages (

+                  AllocateMaxAddress,

+                  MemoryType,

+                  Pages,

+                  &PhysicalAddress

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  *HostAddress = (VOID *)(UINTN)PhysicalAddress;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Frees memory that was allocated with AllocateBuffer().

+

+  The FreeBuffer() function frees memory that was allocated with

+  AllocateBuffer().

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Pages       The number of pages to free.

+

+  @param HostAddress The base system memory address of the allocated range.

+

+  @retval EFI_SUCCESS            The requested memory pages were freed.

+

+  @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and

+                                 Pages was not allocated with AllocateBuffer().

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFreeBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  UINTN                            Pages,

+  OUT VOID                             *HostAddress

+  )

+{

+  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages);

+}

+

+/**

+  Flushes all PCI posted write transactions from a PCI host bridge to system

+  memory.

+

+  The Flush() function flushes any PCI posted write transactions from a PCI

+  host bridge to system memory. Posted write transactions are generated by PCI

+  bus masters when they perform write transactions to target addresses in

+  system memory.

+  This function does not flush posted write transactions from any PCI bridges.

+  A PCI controller specific action must be taken to guarantee that the posted

+  write transactions have been flushed from the PCI controller and from all the

+  PCI bridges into the PCI host bridge. This is typically done with a PCI read

+  transaction from the PCI controller prior to calling Flush().

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @retval EFI_SUCCESS        The PCI posted write transactions were flushed

+                             from the PCI host bridge to system memory.

+

+  @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed

+                             from the PCI host bridge due to a hardware error.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFlush (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This

+  )

+{

+  //

+  // not supported yet

+  //

+  return EFI_SUCCESS;

+}

+

+/**

+  Gets the attributes that a PCI root bridge supports setting with

+  SetAttributes(), and the attributes that a PCI root bridge is currently

+  using.

+

+  The GetAttributes() function returns the mask of attributes that this PCI

+  root bridge supports and the mask of attributes that the PCI root bridge is

+  currently using.

+

+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param Supported   A pointer to the mask of attributes that this PCI root

+                     bridge supports setting with SetAttributes().

+

+  @param Attributes  A pointer to the mask of attributes that this PCI root

+                     bridge is currently using.

+

+  @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes

+                                 that the PCI root bridge supports is returned

+                                 in Supports. If Attributes is not NULL, then

+                                 the attributes that the PCI root bridge is

+                                 currently using is returned in Attributes.

+

+  @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoGetAttributes (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT UINT64                           *Supported,

+  OUT UINT64                           *Attributes

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+

+  if ((Attributes == NULL) && (Supported == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Set the return value for Supported and Attributes

+  //

+  if (Supported != NULL) {

+    *Supported = PrivateData->Supports;

+  }

+

+  if (Attributes != NULL) {

+    *Attributes = PrivateData->Attributes;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets attributes for a resource range on a PCI root bridge.

+

+  The SetAttributes() function sets the attributes specified in Attributes for

+  the PCI root bridge on the resource range specified by ResourceBase and

+  ResourceLength. Since the granularity of setting these attributes may vary

+  from resource type to resource type, and from platform to platform, the

+  actual resource range and the one passed in by the caller may differ. As a

+  result, this function may set the attributes specified by Attributes on a

+  larger resource range than the caller requested. The actual range is returned

+  in ResourceBase and ResourceLength. The caller is responsible for verifying

+  that the actual range for which the attributes were set is acceptable.

+

+  @param[in]       This            A pointer to the

+                                   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[in]       Attributes      The mask of attributes to set. If the

+                                   attribute bit MEMORY_WRITE_COMBINE,

+                                   MEMORY_CACHED, or MEMORY_DISABLE is set,

+                                   then the resource range is specified by

+                                   ResourceBase and ResourceLength. If

+                                   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and

+                                   MEMORY_DISABLE are not set, then

+                                   ResourceBase and ResourceLength are ignored,

+                                   and may be NULL.

+

+  @param[in, out]  ResourceBase    A pointer to the base address of the

+                                   resource range to be modified by the

+                                   attributes specified by Attributes.

+

+  @param[in, out]  ResourceLength  A pointer to the length of the resource

+                                   range to be modified by the attributes

+                                   specified by Attributes.

+

+  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge

+                           was returned in Resources.

+

+  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge

+                           could not be retrieved.

+

+  @retval  EFI_INVALID_PARAMETER Invalid pointer of

+                                 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoSetAttributes (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN     UINT64                           Attributes,

+  IN OUT UINT64                           *ResourceBase,

+  IN OUT UINT64                           *ResourceLength

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+

+  if (Attributes != 0) {

+    if ((Attributes & (~(PrivateData->Supports))) != 0) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  //

+  // This is a generic driver for a PC-AT class system.  It does not have any

+  // chipset specific knowlegde, so none of the attributes can be set or

+  // cleared.  Any attempt to set attribute that are already set will succeed,

+  // and any attempt to set an attribute that is not supported will fail.

+  //

+  if (Attributes & (~PrivateData->Attributes)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Retrieves the current resource settings of this PCI root bridge in the form

+  of a set of ACPI 2.0 resource descriptors.

+

+  There are only two resource descriptor types from the ACPI Specification that

+  may be used to describe the current resources allocated to a PCI root bridge.

+  These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1),

+  and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space

+  Descriptor can describe memory, I/O, and bus number ranges for dynamic or

+  fixed resources. The configuration of a PCI root bridge is described with one

+  or more QWORD Address Space Descriptors followed by an End Tag.

+

+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+

+  @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that

+                           describe the current configuration of this PCI root

+                           bridge. The storage for the ACPI 2.0 resource

+                           descriptors is allocated by this function. The

+                           caller must treat the return buffer as read-only

+                           data, and the buffer must not be freed by the

+                           caller.

+

+  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge

+                           was returned in Resources.

+

+  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge

+                           could not be retrieved.

+

+  @retval  EFI_INVALID_PARAMETER Invalid pointer of

+                                 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoConfiguration (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT VOID                             **Resources

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;

+  UINTN                     Index;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+

+  for (Index = 0; Index < TypeMax; Index++) {

+    if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {

+      EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Desc;

+

+      Desc               = &Configuration.SpaceDesp[Index];

+      Desc->AddrRangeMin = PrivateData->ResAllocNode[Index].Base;

+      Desc->AddrRangeMax = PrivateData->ResAllocNode[Index].Base +

+                           PrivateData->ResAllocNode[Index].Length - 1;

+      Desc->AddrLen = PrivateData->ResAllocNode[Index].Length;

+    }

+  }

+

+  *Resources = &Configuration;

+  return EFI_SUCCESS;

+}

--

2.31.1





-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114066): https://edk2.groups.io/g/devel/message/114066
Mute This Topic: https://groups.io/mt/103831178/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-01-19 14:57 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-18  6:50 [edk2-devel] [PATCH 00/33] Introduce AMD Vangogh platform reference code duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 01/33] AMD/AmdPlatformPkg: Check in AMD S3 logo duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 02/33] AMD/VanGoghBoard: Check in ACPI tables duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update duke.zhai via groups.io
2024-01-23  4:42   ` Chang, Abner via groups.io
2024-01-25  8:25     ` Zhai, MingXin (Duke) via groups.io
2024-01-25 11:45       ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 04/33] AMD/VanGoghBoard: Check in AgesaPublic pkg duke.zhai via groups.io
2024-01-23  4:44   ` Chang, Abner via groups.io
2024-01-25  8:17     ` Xing, Eric via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 05/33] AMD/VanGoghBoard: Check in PlatformSecLib duke.zhai via groups.io
2024-01-23  4:46   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 06/33] AMD/VanGoghBoard: Check in AmdIdsExtLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 07/33] AMD/VanGoghBoard: Check in PciPlatform duke.zhai via groups.io
2024-01-23  4:50   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 08/33] AMD/VanGoghBoard: Check in UDKFlashUpdate duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 09/33] AMD/VanGoghBoard: Check in Flash_AB duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 10/33] AMD/VanGoghBoard: Check in FlashUpdate duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 11/33] AMD/VanGoghBoard: Check in FvbServices duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 12/33] AMD/VanGoghBoard: Check in AMD BaseSerialPortLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 13/33] AMD/VanGoghBoard: Check in PlatformFlashAccessLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 14/33] AMD/VanGoghBoard: Check in SmbiosLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 15/33] AMD/VanGoghBoard: Check in SpiFlashDeviceLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 16/33] AMD/VanGoghBoard: Check in BaseTscTimerLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 17/33] AMD/VanGoghBoard: Check in Smm access module duke.zhai via groups.io
2024-01-18  6:50 ` duke.zhai via groups.io [this message]
2024-01-18  6:50 ` [edk2-devel] [PATCH 19/33] AMD/VanGoghBoard: Check in PcatRealTimeClockRuntimeDxe module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 20/33] AMD/VanGoghBoard: Check in FTPM module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 21/33] AMD/VanGoghBoard: Check in SignedCapsule duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 22/33] AMD/VanGoghBoard: Check in Vtf0 duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 23/33] AMD/VanGoghBoard: Check in AcpiPlatform duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 24/33] AMD/VanGoghBoard: Check in FchSpi module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 25/33] AMD/VanGoghBoard: Check in PlatformInitPei module duke.zhai via groups.io
2024-01-23  6:35   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 26/33] AMD/VanGoghBoard: Check in Smbios platform dxe drivers duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 27/33] AMD/VanGoghBoard: Check in Fsp2WrapperPkg duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 28/33] AMD/VanGoghBoard: Check in SmmCpuFeaturesLibCommon module duke.zhai via groups.io
2024-01-23  5:14   ` Chang, Abner via groups.io
2024-01-23 10:20     ` Xing, Eric via groups.io
2024-01-23 10:44       ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 29/33] AMD/VanGoghBoard: Check in SmramSaveState module duke.zhai via groups.io
2024-01-20 14:37   ` Abdul Lateef Attar via groups.io
2024-01-23  5:15     ` Chang, Abner via groups.io
2024-01-23 10:27       ` Xing, Eric via groups.io
2024-01-23 10:44         ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 30/33] AMD/VanGoghBoard: Check in EDK2 override files duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 31/33] AMD/VanGoghBoard: Check in AMD SmmControlPei module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 32/33] AMD/VanGoghBoard: Check in Chachani board project files and build script duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 33/33] AMD/VanGoghBoard: Improvement coding style duke.zhai via groups.io

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240118065046.961-19-duke.zhai@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox