From: "Wu, Hao A" <hao.a.wu@intel.com>
To: "Ni, Ruiyu" <ruiyu.ni@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH] MdeModulePkg/PciBus: Shadow option ROM after BARs are programmed
Date: Thu, 6 Dec 2018 12:50:05 +0000 [thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C860B72@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20181205092433.136328-1-ruiyu.ni@intel.com>
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, December 05, 2018 5:25 PM
> To: edk2-devel@lists.01.org
> Cc: Wu, Hao A
> Subject: [PATCH] MdeModulePkg/PciBus: Shadow option ROM after BARs
> are programmed
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1376
>
> Today's implementation reuses the 32bit MMIO resource requested by
> all PCI devices MMIO BARs when shadowing the option ROM.
> Take a simple example, a system has only one PCI device. It requires
> 8MB 32bit MMIO and contains a 4MB option ROM. Today's implementation
> only requests 8MB (max of 4M and 8M) 32bit MMIO from
> PciHostBridgeResourceAllocation protocol. Let's assume the MMIO range
> [3GB, 3GB+8MB) is allocated. The 3GB base address is firstly
> programmed to the option ROM BAR for option ROM shadow. Then the
> option ROM decoding is turned off and 3GB base address is programmed
> to the 32bit MMIO BAR.
>
> It doesn't cause issues when the device doesn't request too much
> MMIO.
> But when the device contains a 64bit MMIO BAR which requests 4GB MMIO
> and a 4MB option ROM. Let's assume [3GB, 3GB+8MB) 32bit MMIO range is
"[3GB, 3GB+4MB)" here?
> allocated for the option ROM. When the option ROM is being shadowed,
> 64bit MMIO BAR is programmed to value 0, which means [0, 4GB) MMIO is
> given to the 64bit BAR.
> The range overlaps with the option ROM range which may cause the
> device malfunction (e.g.: option ROM cannot be read out) when the
> device has two separate decoders: one for MMIO BAR, the other for
> option ROM.
>
> The patch requests dedicated MEM32 resource for Option ROMs and
> moves the Option ROM shadow logic after all MMIO BARs are programmed.
> The MMIO BAR setting to 0 when shadowing Option ROM is also skipped
> because the MMIO BAR already contains the correct value.
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
Best Regards,
Hao Wu
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> ---
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 3 +-
> MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 71 ++++++++--------------
> .../Bus/Pci/PciBusDxe/PciOptionRomSupport.c | 13 ----
> .../Bus/Pci/PciBusDxe/PciResourceSupport.c | 37 ++++++++++-
> 4 files changed, 62 insertions(+), 62 deletions(-)
>
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> index f9eebdd5a8..6938802857 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> @@ -1,7 +1,7 @@
> /** @file
> Header files and data structures needed by PCI Bus module.
>
> -Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> This program and the accompanying materials
> are licensed and made available under the terms and conditions of the BSD
> License
> which accompanies this distribution. The full text of the license may be
> found at
> @@ -67,6 +67,7 @@ typedef enum {
> PciBarTypePMem32,
> PciBarTypeMem64,
> PciBarTypePMem64,
> + PciBarTypeOpRom,
> PciBarTypeIo,
> PciBarTypeMem,
> PciBarTypeMaxType
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
> index b81f81a136..7255bcfbbc 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
> @@ -24,6 +24,7 @@ CHAR16 *mBarTypeStr[] = {
> L"PMem32",
> L" Mem64",
> L"PMem64",
> + L" OpRom",
> L" Io",
> L" Mem",
> L"Unknow"
> @@ -425,15 +426,9 @@ PciHostBridgeResourceAllocator (
> PCI_RESOURCE_NODE PMem32Pool;
> PCI_RESOURCE_NODE Mem64Pool;
> PCI_RESOURCE_NODE PMem64Pool;
> - BOOLEAN ReAllocate;
> EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData;
> EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD
> AllocFailExtendedData;
>
> - //
> - // Reallocate flag
> - //
> - ReAllocate = FALSE;
> -
> //
> // It may try several times if the resource allocation fails
> //
> @@ -514,6 +509,17 @@ PciHostBridgeResourceAllocator (
> PciResUsageTypical
> );
>
> + //
> + // Get the max ROM size that the root bridge can process
> + // Insert to resource map so that there will be dedicate MEM32 resource
> range for Option ROM.
> + // All devices' Option ROM share the same MEM32 resource.
> + //
> + MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);
> + RootBridgeDev->PciBar[0].BarType = PciBarTypeOpRom;
> + RootBridgeDev->PciBar[0].Length = MaxOptionRomSize;
> + RootBridgeDev->PciBar[0].Alignment = MaxOptionRomSize - 1;
> + GetResourceFromDevice (RootBridgeDev, IoBridge, Mem32Bridge,
> PMem32Bridge, Mem64Bridge, PMem64Bridge);
> +
> //
> // Create resourcemap by going through all the devices subject to this
> root bridge
> //
> @@ -526,38 +532,6 @@ PciHostBridgeResourceAllocator (
> PMem64Bridge
> );
>
> - //
> - // Get the max ROM size that the root bridge can process
> - //
> - RootBridgeDev->RomSize = Mem32Bridge->Length;
> -
> - //
> - // Skip to enlarge the resource request during realloction
> - //
> - if (!ReAllocate) {
> - //
> - // Get Max Option Rom size for current root bridge
> - //
> - MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);
> -
> - //
> - // Enlarger the mem32 resource to accomdate the option rom
> - // if the mem32 resource is not enough to hold the rom
> - //
> - if (MaxOptionRomSize > Mem32Bridge->Length) {
> -
> - Mem32Bridge->Length = MaxOptionRomSize;
> - RootBridgeDev->RomSize = MaxOptionRomSize;
> -
> - //
> - // Alignment should be adjusted as well
> - //
> - if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {
> - Mem32Bridge->Alignment = MaxOptionRomSize - 1;
> - }
> - }
> - }
> -
> //
> // Based on the all the resource tree, construct ACPI resource node to
> // submit the resource aperture to pci host bridge protocol
> @@ -760,8 +734,6 @@ PciHostBridgeResourceAllocator (
> if (EFI_ERROR (Status)) {
> return Status;
> }
> -
> - ReAllocate = TRUE;
> }
> }
> //
> @@ -828,11 +800,6 @@ PciHostBridgeResourceAllocator (
> &PMem64Base
> );
>
> - //
> - // Process option rom for this root bridge
> - //
> - ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev-
> >RomSize);
> -
> //
> // Create the entire system resource map from the information collected
> by
> // enumerator. Several resource tree was created
> @@ -889,6 +856,20 @@ PciHostBridgeResourceAllocator (
> PMem64Bridge
> );
>
> + //
> + // Process Option ROM for this root bridge after all BARs are programmed.
> + // The PPB's MEM32 RANGE BAR is re-programmed to the Option ROM
> BAR Base in order to
> + // shadow the Option ROM of the devices under the PPB.
> + // After the shadow, Option ROM BAR decoding is turned off and the
> PPB's MEM32 RANGE
> + // BAR is restored back to the original value.
> + // The original value is programmed by ProgramResource() above.
> + //
> + DEBUG ((
> + DEBUG_INFO, "Process Option ROM: BAR Base/Length = %lx/%lx\n",
> + RootBridgeDev->PciBar[0].BaseAddress, RootBridgeDev-
> >PciBar[0].Length
> + ));
> + ProcessOptionRom (RootBridgeDev, RootBridgeDev-
> >PciBar[0].BaseAddress, RootBridgeDev->PciBar[0].Length);
> +
> IoBridge ->PciDev->PciBar[IoBridge ->Bar].BaseAddress = IoBase;
> Mem32Bridge ->PciDev->PciBar[Mem32Bridge ->Bar].BaseAddress =
> Mem32Base;
> PMem32Bridge->PciDev->PciBar[PMem32Bridge->Bar].BaseAddress =
> PMem32Base;
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
> index c2be85a906..aa314474dd 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
> @@ -583,23 +583,10 @@ RomDecode (
> )
> {
> UINT32 Value32;
> - UINT32 Offset;
> - UINT32 OffsetMax;
> EFI_PCI_IO_PROTOCOL *PciIo;
>
> PciIo = &PciDevice->PciIo;
> if (Enable) {
> - //
> - // Clear all bars
> - //
> - OffsetMax = 0x24;
> - if (IS_PCI_BRIDGE(&PciDevice->Pci)) {
> - OffsetMax = 0x14;
> - }
> -
> - for (Offset = 0x10; Offset <= OffsetMax; Offset += sizeof (UINT32)) {
> - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);
> - }
>
> //
> // set the Rom base address: now is hardcode
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
> index f3e51d6150..d3cbefbadf 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
> @@ -446,13 +446,14 @@ GetResourceFromDevice (
> switch ((PciDev->PciBar)[Index].BarType) {
>
> case PciBarTypeMem32:
> + case PciBarTypeOpRom:
>
> Node = CreateResourceNode (
> PciDev,
> (PciDev->PciBar)[Index].Length,
> (PciDev->PciBar)[Index].Alignment,
> Index,
> - PciBarTypeMem32,
> + (PciDev->PciBar)[Index].BarType,
> PciResUsageTypical
> );
>
> @@ -1307,7 +1308,13 @@ ProgramBar (
> 1,
> &Address
> );
> + //
> + // Continue to the case PciBarTypeOpRom to set the BaseAddress.
> + // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture
> + // the MEM32 resource requirement for Option ROM shadow.
> + //
>
> + case PciBarTypeOpRom:
> Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
>
> break;
> @@ -1656,6 +1663,8 @@ ProgrameUpstreamBridgeForRom (
> {
> PCI_IO_DEVICE *Parent;
> PCI_RESOURCE_NODE Node;
> + UINT64 Base;
> + UINT64 Length;
> //
> // For root bridge, just return.
> //
> @@ -1667,7 +1676,6 @@ ProgrameUpstreamBridgeForRom (
> }
>
> Node.PciDev = Parent;
> - Node.Length = PciDevice->RomSize;
> Node.Alignment = 0;
> Node.Bar = PPB_MEM32_RANGE;
> Node.ResType = PciBarTypeMem32;
> @@ -1677,10 +1685,33 @@ ProgrameUpstreamBridgeForRom (
> // Program PPB to only open a single <= 16MB apperture
> //
> if (Enable) {
> + //
> + // Save the original PPB_MEM32_RANGE BAR.
> + // The values will be changed by ProgramPpbApperture().
> + //
> + Base = Parent->PciBar[Node.Bar].BaseAddress;
> + Length = Parent->PciBar[Node.Bar].Length;
> +
> + //
> + // Only cover MMIO for Option ROM.
> + //
> + Node.Length = PciDevice->RomSize;
> ProgramPpbApperture (OptionRomBase, &Node);
> +
> + //
> + // Restore the original PPB_MEM32_RANGE BAR.
> + // So the MEM32 RANGE BAR register can be restored when disable the
> decoding.
> + //
> + Parent->PciBar[Node.Bar].BaseAddress = Base;
> + Parent->PciBar[Node.Bar].Length = Length;
> +
> PCI_ENABLE_COMMAND_REGISTER (Parent,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> } else {
> - InitializePpb (Parent);
> + //
> + // Cover 32bit MMIO for devices below the bridge.
> + //
> + Node.Length = Parent->PciBar[Node.Bar].Length;
> + ProgramPpbApperture (Parent->PciBar[Node.Bar].BaseAddress,
> &Node);
> PCI_DISABLE_COMMAND_REGISTER (Parent,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> }
>
> --
> 2.16.1.windows.1
next prev parent reply other threads:[~2018-12-06 12:50 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-05 9:24 [PATCH] MdeModulePkg/PciBus: Shadow option ROM after BARs are programmed Ruiyu Ni
2018-12-06 12:50 ` Wu, Hao A [this message]
2018-12-11 16:36 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=B80AF82E9BFB8E4FBD8C89DA810C6A093C860B72@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox