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::241; helo=mail-it0-x241.google.com; envelope-from=heyi.guo@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-it0-x241.google.com (mail-it0-x241.google.com [IPv6:2607:f8b0:4001:c0b::241]) (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 F30B12215BD83 for ; Mon, 29 Jan 2018 00:44:53 -0800 (PST) Received: by mail-it0-x241.google.com with SMTP id h129so2173236ita.2 for ; Mon, 29 Jan 2018 00:50:27 -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=F1FDG6UAWQMbCpIgJHOjKrX3FKTV+un6i8t80Vt/Y2E=; b=M8p6N+9whTL7THtVc353pxsMcg7DWnBoW+xR2Tw3pSc06fdw+Qj0l2y8MVuKG7CqCd 85H0r+MaLh5EFBmi0ztDAl/k9HWoBFFsejQrXv8Wg09gPuQlE7z/uRzkvwBCxUzpu+g+ Wc3fBpnZvvHu0MVdAHJXEdW3Klgg4JP12nvlY= 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=F1FDG6UAWQMbCpIgJHOjKrX3FKTV+un6i8t80Vt/Y2E=; b=ngCtOwGkSEmQEDldWiLDJ2dopbU5tUFyDePfOoeAXktouymnoC+nEGATUzbbOv9jBa 1F5KwndjDHT+eu2VRUhsZ1GZxqvQNtl5078H/UQR9Q3joyEdN0Nao/PZpFtW0jVgYdDc OIPiMUZKYaK3NupGtInjqObWfUEivCoSY/n5G1tF7y5tt+vygUyddqRh9ZVbg9tHdgk3 yPoYqW+Byj1hNU0YY1DJppeTUj63G/R0AdkkwfsRYjy6uktJyWsRyb7BIllhDjPyEDB6 7QPqJUBhc2nGqmVftJGrudsj3em0p4H8jiEgjyYSRQsuwPIje9hu1UjFnz8TkOwVQHoX GXqA== X-Gm-Message-State: AKwxyteqCrvYgJ8U2NrvXUpMYZp2QN8mcxoBv9+Gi/T3AXgLeuKyXqzy dReW1WeAAW63NmrmiLaQY4xjbQ== X-Google-Smtp-Source: AH8x226/KnZc725QIIV2QUFN8FU6Yff/CijgBPA2xTopuN5/TxxwRjHc/vH/LNKosSyNHsbRiJHocg== X-Received: by 10.36.33.85 with SMTP id e82mr27564655ita.135.1517215826304; Mon, 29 Jan 2018 00:50:26 -0800 (PST) Received: from SZX1000114654 ([104.237.91.79]) by smtp.gmail.com with ESMTPSA id c62sm3889016ioj.28.2018.01.29.00.50.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 00:50:25 -0800 (PST) From: Guo Heyi X-Google-Original-From: Guo Heyi Date: Mon, 29 Jan 2018 16:50:20 +0800 To: "Ni, Ruiyu" Cc: Guo Heyi , Michael D , Ard Biesheuvel , Eric Dong , "edk2-devel@lists.01.org" , linaro-uefi , Star Zeng Message-ID: <20180129085020.GA127987@SZX1000114654> References: <1516027600-32172-1-git-send-email-heyi.guo@linaro.org> <20180118012639.GA113567@SZX1000114654> 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: Mon, 29 Jan 2018 08:44:54 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sorry for the late; I caught cold and didn't work for several days last week :( Please see my comments below: On Mon, Jan 22, 2018 at 11:36:14AM +0800, Ni, Ruiyu wrote: > On 1/18/2018 9:26 AM, Guo Heyi wrote: > >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) > > I also agree to put the translation fields into the > PCI_ROOT_BRIDGE_APERTURE. > > > But I think we may have different understandings to the address > translation. > My understanding to the whole translation: > 1. PciHostBridge.GetProposedResources () returns resource information > for a single root bridge. It only carries the address range in PCI > view. > The address range/resource is reported/submitted by PciHostBridgeLib. > Before the change, CPU view equals to PCI view. So PciHostBridgeDxe > driver directly adds the resource to GCD. > In your change, PciHostBridgeDxe assumes the source is in PCI view > and it adds offset to convert to CPU view. > CPU-address = PCI-address + offset. <-- Equation #A > > > 2. PciRootBridgeIo.Configuration() returns the resource information > for a single root bridge. It carries the address range in CPU view, > and the translation offset. > However, per UEFI spec, "Address Translation Offset. Offset to apply > to the Starting address of a BAR to convert it to a PCI address. " > PCI-address = CPU-address + offset. <-- Equation #B If we get Equation #B from the statement in UEFI spec, does it also imply Starting address is "Address Range Minimum" and so it is CPU view address? If we use Equation #B, can offset be a negative value? If it is not, then it will make translation useless, since we cannot change CPU address above 4G into PCI address under 4G for legacy compatibility. Equation #B is also not consistent with how OS treats address translation; please see the ACPI ASL code which works well for OS: https://github.com/tianocore/edk2-platforms/blob/master/Silicon/Hisilicon/Hi1616/D05AcpiTables/Dsdt/D05Pci.asl#L201 Thanks, Gary (Heyi Guo) > > You can see that equation #A and #B are conflict. > > > 3. PciIo.GetBarAttributes() returns the resource information for a > single PCI BAR. > It carries the address range in CPU view, and the translation offset. > UEFI Spec content here is consistent to #2. > > > 4. I didn't find spec requires the offset only applies to MEM address. > So I am ok to extend the offset to IO address. > > So I suggest: > 1. PciHostBridgeLib still reports the resource in CPU view because > #2 and #3 both report resource in CPU view. > It also reports the resource offset (= PCI-address - CPU-address). > > 2. PciHostBridge.GetProposedResources() returns resource for a single > root bridge in PCI view. Because per PI spec, the Offset field in > the ACPI descriptor carries the allocation status. If the resource > is in CPU view, PciBus driver doesn't know how to calculate the > PCI address and update the BAR. > > 3. PciRootBridgeIo.Configuration() returns offset value reported by > PciHostBridgeLib. > > 4. PciRootBridgeIo/PciIo.Mem.Read/Write(): I agree that the address is > a PCI-address. So a conversion is needed when use CpuIo to access. > But I think a spec clarification is needed to tell developers > that the conversion happens in PciRootBridgeIo layer, not in PciIo > layer. > > > > > > >>>+ 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 > > > > > -- > Thanks, > Ray