From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4001:c0b::236; helo=mail-it0-x236.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-it0-x236.google.com (mail-it0-x236.google.com [IPv6:2607:f8b0:4001:c0b::236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 9411D2232BE11 for ; Wed, 17 Jan 2018 06:02:47 -0800 (PST) Received: by mail-it0-x236.google.com with SMTP id q8so9362323itb.2 for ; Wed, 17 Jan 2018 06:08:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=18qmLEQrd+m3S91AY+3MMaTEEKSoQNjkUU/7l2qdNpw=; b=fsJQWDLPyhJYgR9JmD2zEXUjxC1top8lpP070TtJUJkI8Z3cIjYbBwmpTAB8kQIjg+ qlb2zPMOdrvekPLcdgIOh8LSAggM+GIB/I/xzo39GNJGjkzHNin27L4l6cDOG04J0m+I 5UnpdTiDc9gLQeBPdZ2uAkwjg44uSykciXkLI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=18qmLEQrd+m3S91AY+3MMaTEEKSoQNjkUU/7l2qdNpw=; b=ReYaRXs/lAiwhqKgTaAdmtDTqZz+veVWUSpRwz/FUiFjevpNXZfCvnfGjNGTwS3zX6 GE4Mma7ynM63mqAo2J/DPz5FUMBU7d8zdh+bWllKsrke/dkjlx1xHX9JLq1ISzjeUqwA 2FuyDyq102egHhNrtFBbGIKrcrh3NM6K6DlVDrkrkvyLw1hWuWxj8X45uJgdab0n7WpA cKnec8RB9R8539lK8+YwZPj06KpJolyPx1PIw9bcfBd6R6JSuKgyZYFQmFGXVUmVjblk 3jizCncs5bfUhe6ZkDBNkbBvZwaaoFwLfSyoaQWaXG9d6cDwCF0NlmspdqGL38d6Terc DnKQ== X-Gm-Message-State: AKwxytfR8nPU866/O3nrOW2GFYjFgJvKvclPd0GsKCXZPThtbg08rnGU UUict2qCWtX5BabprkZjO1K7Nmos4Rdex8gayjp63g== X-Google-Smtp-Source: ACJfBotKuZjthYxIYbkQb2obV1Z1a/JkNQioj7Fn6zuLkMi7nbhOlYF2EKiTPUXNGsLOfUJeTxhtuzidaXkfXCmMVbE= X-Received: by 10.36.192.10 with SMTP id u10mr22645747itf.73.1516198086839; Wed, 17 Jan 2018 06:08:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.37.197 with HTTP; Wed, 17 Jan 2018 06:08:06 -0800 (PST) In-Reply-To: <1516027600-32172-1-git-send-email-heyi.guo@linaro.org> References: <1516027600-32172-1-git-send-email-heyi.guo@linaro.org> From: Ard Biesheuvel Date: Wed, 17 Jan 2018 14:08:06 +0000 Message-ID: To: Heyi Guo Cc: linaro-uefi , "edk2-devel@lists.01.org" , Ruiyu Ni , Star Zeng , Eric Dong Subject: Re: [RFC] MdeModulePkg/PciHostBridgeDxe: Add support for address translation X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jan 2018 14:02:48 -0000 Content-Type: text/plain; charset="UTF-8" On 15 January 2018 at 14:46, Heyi Guo 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 > Cc: Ruiyu Ni > Cc: Ard Biesheuvel > Cc: Star Zeng > Cc: Eric Dong > --- > .../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 >