From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c00::234; helo=mail-pf0-x234.google.com; envelope-from=heyi.guo@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-pf0-x234.google.com (mail-pf0-x234.google.com [IPv6:2607:f8b0:400e:c00::234]) (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 968CE2034A8A5 for ; Wed, 17 Jan 2018 17:21:23 -0800 (PST) Received: by mail-pf0-x234.google.com with SMTP id k19so12960207pfj.5 for ; Wed, 17 Jan 2018 17:26:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:date:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=OiqB7+PdxD6PgJ2dEiVqf11irpPGR0DMgczer158Y7Q=; b=alBR89x5FFMk4l+kFqsOhnyWH39k21yx3zrhHza7AS1xt55vaT/ledVyKIA5t5NTCV HNCAE2nxv9wuEsn4dpg55nMMEZtgP5LEYLROLxK2mMH3xB/dG3hW/kQbPX4o7Uz2g29x Vz5KCbYLvwhkujcxFjk10PyygAw/REFCRZmpw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:date:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=OiqB7+PdxD6PgJ2dEiVqf11irpPGR0DMgczer158Y7Q=; b=V5GsETAVj4SFxoZhw+Eo91aNlgLIuHpSF/B3pasLGFY2ICRjN7y1BNgzNg3rpruJ6K mz/vXbsW/Y+sINeE2Peh2Yd6x7Fy/6XMIG8NWusjVtb1hE5XdUAHf6CJVLdwYBsTkNyZ Ms9wOJZ4MkyneHsQ50WTSR/DKUrDQI2s4fjvmZx5t0bQcq8hQu1TCQquy9AZ7N4tD2J/ SV9yC3Z1YIb2nlTNfbCCLrfIv3McryutDE6Fc33iuesdrQSpVdOpczEyAza1Z1hm9Emg l3Bub6VfUobtXyPG00tOMAYb4T4MNwUjT7j0EQyaehTOn9m7mrgY8F735YMJQLelpQ5B CMQw== X-Gm-Message-State: AKwxytfsoAkVXaxjgLD3zR+JtB7BWfr1W/iXbZ+bv52c2qNfz0IzccPB vG3WbY7vrQL9SmtYh9XZVkZnhg== X-Google-Smtp-Source: ACJfBot/LtmtMu82UGSOMKc+Yqqqmv+69+fNAeI3XEW3Yp3WGxPJqJb3K1VuzO+lBST3VaNX0hUQ7A== X-Received: by 10.99.123.74 with SMTP id k10mr25002400pgn.165.1516238804026; Wed, 17 Jan 2018 17:26:44 -0800 (PST) Received: from SZX1000114654 ([104.237.91.79]) by smtp.gmail.com with ESMTPSA id m10sm8952424pgt.56.2018.01.17.17.26.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Jan 2018 17:26:43 -0800 (PST) From: Guo Heyi X-Google-Original-From: Guo Heyi Date: Thu, 18 Jan 2018 09:26:39 +0800 To: Ard Biesheuvel Cc: Heyi Guo , linaro-uefi , "edk2-devel@lists.01.org" , Ruiyu Ni , Star Zeng , Eric Dong Message-ID: <20180118012639.GA113567@SZX1000114654> References: <1516027600-32172-1-git-send-email-heyi.guo@linaro.org> MIME-Version: 1.0 In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) 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: Thu, 18 Jan 2018 01:21:24 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Jan 17, 2018 at 02:08:06PM +0000, Ard Biesheuvel wrote: > 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. > Actually my first idea was the same, but when I looked at the implementation of PciHostBridgeLib of Ovmf, I found it a little tedious to change the existing code in this way. We'll need to check everywhere PCI_ROOT_BRIDGE_APERTURE or PCI_ROOT_BRIDGE is used, to make sure the translation field is initialized to be zero, e.g. line 235~245. What I did in this RFC is not so straightforward indeed. So I can change the code if we all agree to add Translation field into PCI_ROOT_BRIDGE_APERTURE directly. Thanks, Gary (Heyi Guo) > > + 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 > >