On 15 January 2018 at 14:46, Heyi Guo <heyi....@linaro.org> wrote:
> This is the draft patch for the discussion posted in edk2-devel
> mailing list:
> https://lists.01.org/pipermail/edk2-devel/2017-December/019289.html
>
> As discussed in the mailing list, we'd like to add support for PCI
> address translation which is necessary for some non-x86 platforms. I
> also want to minimize the changes to the generic host bridge driver
> and platform PciHostBridgeLib implemetations, so additional two
> interfaces are added to expose translation information of the
> platform. To be generic, I add translation for each type of IO or
> memory resources.
>
> The patch is still a RFC, so I only passed the build for qemu64 and
> the function has not been tested yet.
>
> Please let me know your comments about it.
>
> Thanks.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Heyi Guo <heyi....@linaro.org>
> Cc: Ruiyu Ni <ruiyu...@intel.com>
> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org>
> Cc: Star Zeng <star.z...@intel.com>
> Cc: Eric Dong <eric.d...@intel.com>
> ---
>  .../FdtPciHostBridgeLib/FdtPciHostBridgeLib.c      |  19 ++++
>  .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c       |  53 ++++++++---
>  .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h       |   8 +-
>  .../Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c     | 101 
> ++++++++++++++++++---
>  MdeModulePkg/Include/Library/PciHostBridgeLib.h    |  36 ++++++++
>  5 files changed, 192 insertions(+), 25 deletions(-)
>
> diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c 
> b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
> index 5b9c887..0c8371a 100644
> --- a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
> +++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
> @@ -360,6 +360,16 @@ PciHostBridgeGetRootBridges (
>    return &mRootBridge;
>  }
>
> +PCI_ROOT_BRIDGE_TRANSLATION *
> +EFIAPI
> +PciHostBridgeGetTranslations (
> +  UINTN *Count
> +  )
> +{
> +  *Count = 0;
> +  return NULL;
> +}
> +
>  /**
>    Free the root bridge instances array returned from
>    PciHostBridgeGetRootBridges().
> @@ -377,6 +387,15 @@ PciHostBridgeFreeRootBridges (
>    ASSERT (Count == 1);
>  }
>
> +VOID
> +EFIAPI
> +PciHostBridgeFreeTranslations (
> +  PCI_ROOT_BRIDGE_TRANSLATION *Translations,
> +  UINTN                       Count
> +  )
> +{
> +}
> +
>  /**
>    Inform the platform that the resource conflict happens.
>
> diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c 
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
> index 1494848..835e411 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
> @@ -360,18 +360,38 @@ InitializePciHostBridge (
>    PCI_HOST_BRIDGE_INSTANCE    *HostBridge;
>    PCI_ROOT_BRIDGE_INSTANCE    *RootBridge;
>    PCI_ROOT_BRIDGE             *RootBridges;
> +  PCI_ROOT_BRIDGE_TRANSLATION *Translations;
>    UINTN                       RootBridgeCount;
> +  UINTN                       TranslationCount;
>    UINTN                       Index;
>    PCI_ROOT_BRIDGE_APERTURE    *MemApertures[4];

Wouldn't it be much better to add a 'translation' member to
PCI_ROOT_BRIDGE_APERTURE? That way, existing code just default to a
translation of 0, and all the handling of the separate array can be
dropped.

> +  UINT64                      MemTranslation[4];
>    UINTN                       MemApertureIndex;
>    BOOLEAN                     ResourceAssigned;
>    LIST_ENTRY                  *Link;
> +  UINT64                      Trans;
>
>    RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount);
>    if ((RootBridges == NULL) || (RootBridgeCount == 0)) {
>      return EFI_UNSUPPORTED;
>    }
>
> +  Translations = PciHostBridgeGetTranslations (&TranslationCount);
> +  if (Translations == NULL || TranslationCount == 0) {
> +    TranslationCount = 0;
> +    Translations = AllocateZeroPool (RootBridgeCount * sizeof 
> (*Translations));
> +    if (Translations == NULL) {
> +      PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +  }
> +
> +  if (TranslationCount != 0 && TranslationCount != RootBridgeCount) {
> +    DEBUG ((DEBUG_ERROR, "Error: count of root bridges (%d) and translation 
> (%d) are different!\n",
> +      RootBridgeCount, TranslationCount));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
>    Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID 
> **) &mMetronome);
>    ASSERT_EFI_ERROR (Status);
>    Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) 
> &mCpuIo);
> @@ -395,7 +415,7 @@ InitializePciHostBridge (
>      //
>      // Create Root Bridge Handle Instance
>      //
> -    RootBridge = CreateRootBridge (&RootBridges[Index]);
> +    RootBridge = CreateRootBridge (&RootBridges[Index], 
> &Translations[Index]);
>      ASSERT (RootBridge != NULL);
>      if (RootBridge == NULL) {
>        continue;
> @@ -411,8 +431,9 @@ InitializePciHostBridge (
>      }
>
>      if (RootBridges[Index].Io.Base <= RootBridges[Index].Io.Limit) {
> +      Trans = Translations[Index].IoTranslation;
>        Status = AddIoSpace (
> -                 RootBridges[Index].Io.Base,
> +                 RootBridges[Index].Io.Base + Trans,
>                   RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1
>                   );
>        ASSERT_EFI_ERROR (Status);
> @@ -422,7 +443,7 @@ InitializePciHostBridge (
>                          EfiGcdIoTypeIo,
>                          0,
>                          RootBridges[Index].Io.Limit - 
> RootBridges[Index].Io.Base + 1,
> -                        &RootBridges[Index].Io.Base,
> +                        &RootBridges[Index].Io.Base + Trans,
>                          gImageHandle,
>                          NULL
>                          );
> @@ -437,20 +458,24 @@ InitializePciHostBridge (
>      // the MEM aperture in Mem
>      //
>      MemApertures[0] = &RootBridges[Index].Mem;
> +    MemTranslation[0] = Translations[Index].MemTranslation;
>      MemApertures[1] = &RootBridges[Index].MemAbove4G;
> +    MemTranslation[1] = Translations[Index].MemAbove4GTranslation;
>      MemApertures[2] = &RootBridges[Index].PMem;
> +    MemTranslation[2] = Translations[Index].PMemTranslation;
>      MemApertures[3] = &RootBridges[Index].PMemAbove4G;
> +    MemTranslation[3] = Translations[Index].PMemAbove4GTranslation;
>
>      for (MemApertureIndex = 0; MemApertureIndex < ARRAY_SIZE (MemApertures); 
> MemApertureIndex++) {
>        if (MemApertures[MemApertureIndex]->Base <= 
> MemApertures[MemApertureIndex]->Limit) {
>          Status = AddMemoryMappedIoSpace (
> -                   MemApertures[MemApertureIndex]->Base,
> +                   MemApertures[MemApertureIndex]->Base + 
> MemTranslation[MemApertureIndex],
>                     MemApertures[MemApertureIndex]->Limit - 
> MemApertures[MemApertureIndex]->Base + 1,
>                     EFI_MEMORY_UC
>                     );
>          ASSERT_EFI_ERROR (Status);
>          Status = gDS->SetMemorySpaceAttributes (
> -                        MemApertures[MemApertureIndex]->Base,
> +                        MemApertures[MemApertureIndex]->Base + 
> MemTranslation[MemApertureIndex],
>                          MemApertures[MemApertureIndex]->Limit - 
> MemApertures[MemApertureIndex]->Base + 1,
>                          EFI_MEMORY_UC
>                          );
> @@ -463,7 +488,7 @@ InitializePciHostBridge (
>                            EfiGcdMemoryTypeMemoryMappedIo,
>                            0,
>                            MemApertures[MemApertureIndex]->Limit - 
> MemApertures[MemApertureIndex]->Base + 1,
> -                          &MemApertures[MemApertureIndex]->Base,
> +                          &MemApertures[MemApertureIndex]->Base + 
> MemTranslation[MemApertureIndex],
>                            gImageHandle,
>                            NULL
>                            );
> @@ -514,7 +539,13 @@ InitializePciHostBridge (
>                      );
>      ASSERT_EFI_ERROR (Status);
>    }
> +
>    PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
> +  if (TranslationCount == 0) {
> +    FreePool (Translations);
> +  } else {
> +    PciHostBridgeFreeTranslations (Translations, TranslationCount);
> +  }
>
>    if (!EFI_ERROR (Status)) {
>      mIoMmuEvent = EfiCreateProtocolNotifyEvent (
> @@ -828,7 +859,7 @@ NotifyPhase (
>                              FALSE,
>                              RootBridge->ResAllocNode[Index].Length,
>                              MIN (15, BitsOfAlignment),
> -                            ALIGN_VALUE (RootBridge->Io.Base, Alignment + 1),
> +                            ALIGN_VALUE (RootBridge->Io.Base, Alignment + 1) 
> + RootBridge->IoTranslation,
>                              RootBridge->Io.Limit
>                              );
>              break;
> @@ -838,7 +869,7 @@ NotifyPhase (
>                              TRUE,
>                              RootBridge->ResAllocNode[Index].Length,
>                              MIN (63, BitsOfAlignment),
> -                            ALIGN_VALUE (RootBridge->MemAbove4G.Base, 
> Alignment + 1),
> +                            ALIGN_VALUE (RootBridge->MemAbove4G.Base, 
> Alignment + 1) + RootBridge->MemAbove4GTranslation,
>                              RootBridge->MemAbove4G.Limit
>                              );
>              if (BaseAddress != MAX_UINT64) {
> @@ -853,7 +884,7 @@ NotifyPhase (
>                              TRUE,
>                              RootBridge->ResAllocNode[Index].Length,
>                              MIN (31, BitsOfAlignment),
> -                            ALIGN_VALUE (RootBridge->Mem.Base, Alignment + 
> 1),
> +                            ALIGN_VALUE (RootBridge->Mem.Base, Alignment + 
> 1) + RootBridge->MemTranslation,
>                              RootBridge->Mem.Limit
>                              );
>              break;
> @@ -863,7 +894,7 @@ NotifyPhase (
>                              TRUE,
>                              RootBridge->ResAllocNode[Index].Length,
>                              MIN (63, BitsOfAlignment),
> -                            ALIGN_VALUE (RootBridge->PMemAbove4G.Base, 
> Alignment + 1),
> +                            ALIGN_VALUE (RootBridge->PMemAbove4G.Base, 
> Alignment + 1) + RootBridge->PMemAbove4GTranslation,
>                              RootBridge->PMemAbove4G.Limit
>                              );
>              if (BaseAddress != MAX_UINT64) {
> @@ -877,7 +908,7 @@ NotifyPhase (
>                              TRUE,
>                              RootBridge->ResAllocNode[Index].Length,
>                              MIN (31, BitsOfAlignment),
> -                            ALIGN_VALUE (RootBridge->PMem.Base, Alignment + 
> 1),
> +                            ALIGN_VALUE (RootBridge->PMem.Base, Alignment + 
> 1) + RootBridge->PMemTranslation,
>                              RootBridge->PMem.Limit
>                              );
>              break;
> diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h 
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> index d3dfb57..449c4b3 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> @@ -73,6 +73,11 @@ typedef struct {
>    PCI_ROOT_BRIDGE_APERTURE          PMem;
>    PCI_ROOT_BRIDGE_APERTURE          MemAbove4G;
>    PCI_ROOT_BRIDGE_APERTURE          PMemAbove4G;
> +  UINT64                            IoTranslation;
> +  UINT64                            MemTranslation;
> +  UINT64                            MemAbove4GTranslation;
> +  UINT64                            PMemTranslation;
> +  UINT64                            PMemAbove4GTranslation;
>    BOOLEAN                           DmaAbove4G;
>    BOOLEAN                           NoExtendedConfigSpace;
>    VOID                              *ConfigBuffer;
> @@ -98,7 +103,8 @@ typedef struct {
>  **/
>  PCI_ROOT_BRIDGE_INSTANCE *
>  CreateRootBridge (
> -  IN PCI_ROOT_BRIDGE       *Bridge
> +  IN PCI_ROOT_BRIDGE                *Bridge,
> +  IN PCI_ROOT_BRIDGE_TRANSLATION    *Translation
>    );
>
>  //
> diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c 
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> index dc06c16..84b2d5a 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> @@ -67,7 +67,8 @@ UINT8 mOutStride[] = {
>  **/
>  PCI_ROOT_BRIDGE_INSTANCE *
>  CreateRootBridge (
> -  IN PCI_ROOT_BRIDGE       *Bridge
> +  IN PCI_ROOT_BRIDGE                *Bridge,
> +  IN PCI_ROOT_BRIDGE_TRANSLATION    *Translation
>    )
>  {
>    PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> @@ -87,11 +88,21 @@ CreateRootBridge (
>            (Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) 
> != 0 ? L"Mem64Decode" : L""
>            ));
>    DEBUG ((EFI_D_INFO, "           Bus: %lx - %lx\n", Bridge->Bus.Base, 
> Bridge->Bus.Limit));
> -  DEBUG ((EFI_D_INFO, "            Io: %lx - %lx\n", Bridge->Io.Base, 
> Bridge->Io.Limit));
> -  DEBUG ((EFI_D_INFO, "           Mem: %lx - %lx\n", Bridge->Mem.Base, 
> Bridge->Mem.Limit));
> -  DEBUG ((EFI_D_INFO, "    MemAbove4G: %lx - %lx\n", 
> Bridge->MemAbove4G.Base, Bridge->MemAbove4G.Limit));
> -  DEBUG ((EFI_D_INFO, "          PMem: %lx - %lx\n", Bridge->PMem.Base, 
> Bridge->PMem.Limit));
> -  DEBUG ((EFI_D_INFO, "   PMemAbove4G: %lx - %lx\n", 
> Bridge->PMemAbove4G.Base, Bridge->PMemAbove4G.Limit));
> +  DEBUG ((DEBUG_INFO, "            Io: %lx - %lx translation=%lx\n",
> +          Bridge->Io.Base, Bridge->Io.Limit, Translation->IoTranslation
> +          ));
> +  DEBUG ((DEBUG_INFO, "           Mem: %lx - %lx translation=%lx\n",
> +          Bridge->Mem.Base, Bridge->Mem.Limit, Translation->MemTranslation
> +          ));
> +  DEBUG ((DEBUG_INFO, "    MemAbove4G: %lx - %lx translation=%lx\n",
> +          Bridge->MemAbove4G.Base, Bridge->MemAbove4G.Limit, 
> Translation->MemAbove4GTranslation
> +          ));
> +  DEBUG ((DEBUG_INFO, "          PMem: %lx - %lx translation=%lx\n",
> +          Bridge->PMem.Base, Bridge->PMem.Limit, Translation->PMemTranslation
> +          ));
> +  DEBUG ((DEBUG_INFO, "   PMemAbove4G: %lx - %lx translation=%lx\n",
> +          Bridge->PMemAbove4G.Base, Bridge->PMemAbove4G.Limit, 
> Translation->PMemAbove4GTranslation
> +          ));
>
>    //
>    // Make sure Mem and MemAbove4G apertures are valid
> @@ -174,10 +185,15 @@ CreateRootBridge (
>
>    CopyMem (&RootBridge->Bus, &Bridge->Bus, sizeof 
> (PCI_ROOT_BRIDGE_APERTURE));
>    CopyMem (&RootBridge->Io, &Bridge->Io, sizeof (PCI_ROOT_BRIDGE_APERTURE));
> +  RootBridge->IoTranslation = Translation->IoTranslation;
>    CopyMem (&RootBridge->Mem, &Bridge->Mem, sizeof 
> (PCI_ROOT_BRIDGE_APERTURE));
> +  RootBridge->MemTranslation = Translation->MemTranslation;
>    CopyMem (&RootBridge->MemAbove4G, &Bridge->MemAbove4G, sizeof 
> (PCI_ROOT_BRIDGE_APERTURE));
> +  RootBridge->MemAbove4GTranslation = Translation->MemAbove4GTranslation;
>    CopyMem (&RootBridge->PMem, &Bridge->PMem, sizeof 
> (PCI_ROOT_BRIDGE_APERTURE));
> +  RootBridge->PMemTranslation = Translation->PMemTranslation;
>    CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof 
> (PCI_ROOT_BRIDGE_APERTURE));
> +  RootBridge->PMemAbove4GTranslation = Translation->PMemAbove4GTranslation;
>
>    for (Index = TypeIo; Index < TypeMax; Index++) {
>      switch (Index) {
> @@ -403,6 +419,28 @@ RootBridgeIoCheckParameter (
>    return EFI_SUCCESS;
>  }
>
> +EFI_STATUS
> +RootBridgeIoGetMemTranslation (
> +  IN PCI_ROOT_BRIDGE_INSTANCE               *RootBridge,
> +  IN UINT64                                 Address,
> +  IN OUT UINT64                             *Translation
> +  )
> +{
> +  if (Address >= RootBridge->Mem.Base && Address <= RootBridge->Mem.Limit) {
> +    *Translation = RootBridge->MemTranslation;
> +  } else if (Address >= RootBridge->PMem.Base && Address <= 
> RootBridge->PMem.Limit) {
> +    *Translation = RootBridge->PMemTranslation;
> +  } else if (Address >= RootBridge->MemAbove4G.Base && Address <= 
> RootBridge->MemAbove4G.Limit) {
> +    *Translation = RootBridge->MemAbove4GTranslation;
> +  } else if (Address >= RootBridge->PMemAbove4G.Base && Address <= 
> RootBridge->PMemAbove4G.Limit) {
> +    *Translation = RootBridge->PMemAbove4GTranslation;
> +  } else {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
>  /**
>    Polls an address in memory mapped I/O space until an exit condition is met,
>    or a timeout occurs.
> @@ -658,13 +696,22 @@ RootBridgeIoMemRead (
>    )
>  {
>    EFI_STATUS                             Status;
> +  PCI_ROOT_BRIDGE_INSTANCE               *RootBridge;
> +  UINT64                                 Translation;
>
>    Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address,
>                                         Count, Buffer);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -  return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address, Count, Buffer);
> +
> +  RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> +  Status = RootBridgeIoGetMemTranslation (RootBridge, Address, &Translation);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address + Translation, Count, Buffer);
>  }
>
>  /**
> @@ -705,13 +752,22 @@ RootBridgeIoMemWrite (
>    )
>  {
>    EFI_STATUS                             Status;
> +  PCI_ROOT_BRIDGE_INSTANCE               *RootBridge;
> +  UINT64                                 Translation;
>
>    Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address,
>                                         Count, Buffer);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -  return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address, Count, Buffer);
> +
> +  RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> +  Status = RootBridgeIoGetMemTranslation (RootBridge, Address, &Translation);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address + Translation, Count, Buffer);
>  }
>
>  /**
> @@ -746,6 +802,8 @@ RootBridgeIoIoRead (
>    )
>  {
>    EFI_STATUS                                    Status;
> +  PCI_ROOT_BRIDGE_INSTANCE                      *RootBridge;
> +
>    Status = RootBridgeIoCheckParameter (
>               This, IoOperation, Width,
>               Address, Count, Buffer
> @@ -753,7 +811,10 @@ RootBridgeIoIoRead (
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -  return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address, Count, Buffer);
> +
> +  RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address 
> + RootBridge->IoTranslation, Count, Buffer);
>  }
>
>  /**
> @@ -788,6 +849,8 @@ RootBridgeIoIoWrite (
>    )
>  {
>    EFI_STATUS                                    Status;
> +  PCI_ROOT_BRIDGE_INSTANCE                      *RootBridge;
> +
>    Status = RootBridgeIoCheckParameter (
>               This, IoOperation, Width,
>               Address, Count, Buffer
> @@ -795,7 +858,10 @@ RootBridgeIoIoWrite (
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> -  return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address, Count, Buffer);
> +
> +  RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, 
> Address + RootBridge->IoTranslation, Count, Buffer);
>  }
>
>  /**
> @@ -1621,19 +1687,28 @@ RootBridgeIoConfiguration (
>      switch (ResAllocNode->Type) {
>
>      case TypeIo:
> -      Descriptor->ResType       = ACPI_ADDRESS_SPACE_TYPE_IO;
> +      Descriptor->ResType               = ACPI_ADDRESS_SPACE_TYPE_IO;
> +      Descriptor->AddrTranslationOffset = RootBridge->IoTranslation;
>        break;
>
>      case TypePMem32:
> -      Descriptor->SpecificFlag = 
> EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->SpecificFlag          = 
> EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrTranslationOffset = RootBridge->PMemTranslation;
> +      Descriptor->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->AddrSpaceGranularity  = 32;
>      case TypeMem32:
> +      Descriptor->AddrTranslationOffset = RootBridge->MemTranslation;
>        Descriptor->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
>        Descriptor->AddrSpaceGranularity  = 32;
>        break;
>
>      case TypePMem64:
> -      Descriptor->SpecificFlag = 
> EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->SpecificFlag          = 
> EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrTranslationOffset = RootBridge->PMemAbove4GTranslation;
> +      Descriptor->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->AddrSpaceGranularity  = 64;
>      case TypeMem64:
> +      Descriptor->AddrTranslationOffset = RootBridge->MemAbove4GTranslation;
>        Descriptor->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
>        Descriptor->AddrSpaceGranularity  = 64;
>        break;
> diff --git a/MdeModulePkg/Include/Library/PciHostBridgeLib.h 
> b/MdeModulePkg/Include/Library/PciHostBridgeLib.h
> index d42e9ec..4c297fd 100644
> --- a/MdeModulePkg/Include/Library/PciHostBridgeLib.h
> +++ b/MdeModulePkg/Include/Library/PciHostBridgeLib.h
> @@ -53,6 +53,14 @@ typedef struct {
>    EFI_DEVICE_PATH_PROTOCOL *DevicePath;           ///< Device path.
>  } PCI_ROOT_BRIDGE;
>
> +typedef struct {
> +  UINT64                   IoTranslation;
> +  UINT64                   MemTranslation;
> +  UINT64                   MemAbove4GTranslation;
> +  UINT64                   PMemTranslation;
> +  UINT64                   PMemAbove4GTranslation;
> +} PCI_ROOT_BRIDGE_TRANSLATION;
> +
>  /**
>    Return all the root bridge instances in an array.
>
> @@ -69,6 +77,21 @@ PciHostBridgeGetRootBridges (
>    );
>
>  /**
> +  Return all the root bridge instances in an array.
> +
> +  @param Count  Return the count of root bridge instances.
> +
> +  @return All the root bridge instances in an array.
> +          The array should be passed into PciHostBridgeFreeRootBridges()
> +          when it's not used.
> +**/
> +PCI_ROOT_BRIDGE_TRANSLATION *
> +EFIAPI
> +PciHostBridgeGetTranslations (
> +  UINTN *Count
> +  );
> +
> +/**
>    Free the root bridge instances array returned from 
> PciHostBridgeGetRootBridges().
>
>    @param Bridges The root bridge instances array.
> @@ -82,6 +105,19 @@ PciHostBridgeFreeRootBridges (
>    );
>
>  /**
> +  Free the root bridge instances array returned from 
> PciHostBridgeGetRootBridges().
> +
> +  @param Bridges The root bridge instances array.
> +  @param Count   The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeTranslations (
> +  PCI_ROOT_BRIDGE_TRANSLATION  *Bridges,
> +  UINTN                        Count
> +  );
> +
> +/**
>    Inform the platform that the resource conflict happens.
>
>    @param HostBridgeHandle Handle of the Host Bridge.
> --
> 2.7.4
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to