From 401f8cd110f7eec7684d948df29e00b44b1468d9 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Mon, 9 May 2016 13:49:27 +0800 Subject: [PATCH] MdeModulePkg/PciHostBridgeDxe: Honor ResourceAssigned Change PciHostBridgeDxe driver to not install the PciHostBridgeResourceAllocation protocol and let PciRootBridgeIo.Configuration() return the correct PCI resource assignment information when the ResourceAssigned is TRUE. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan Reviewed-by: Laszlo Ersek --- .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 92 +++++++++++++----- .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 4 +- .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 96 ++++++++++++------- 3 files changed, 134 insertions(+), 58 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c index 07ed54b08e..c866e88016 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c @@ -338,6 +338,8 @@ InitializePciHostBridge ( UINTN Index; PCI_ROOT_BRIDGE_APERTURE *MemApertures[4]; UINTN MemApertureIndex; + BOOLEAN ResourceAssigned; + LIST_ENTRY *Link; RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount); if ((RootBridges == NULL) || (RootBridgeCount == 0)) { @@ -358,27 +360,7 @@ InitializePciHostBridge ( HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE; HostBridge->CanRestarted = TRUE; InitializeListHead (&HostBridge->RootBridges); - - HostBridge->ResAlloc.NotifyPhase = NotifyPhase; - HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge; - HostBridge->ResAlloc.GetAllocAttributes = GetAttributes; - HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration; - HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers; - HostBridge->ResAlloc.SubmitResources = SubmitResources; - HostBridge->ResAlloc.GetProposedResources = GetProposedResources; - HostBridge->ResAlloc.PreprocessController = PreprocessController; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &HostBridge->Handle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc, - NULL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - FreePool (HostBridge); - PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); - return Status; - } + ResourceAssigned = FALSE; // // Create Root Bridge Device Handle in this Host Bridge @@ -387,18 +369,39 @@ InitializePciHostBridge ( // // Create Root Bridge Handle Instance // - RootBridge = CreateRootBridge (&RootBridges[Index], HostBridge->Handle); + RootBridge = CreateRootBridge (&RootBridges[Index]); ASSERT (RootBridge != NULL); if (RootBridge == NULL) { continue; } + // + // Make sure all root bridges share the same ResourceAssigned value. + // + if (Index == 0) { + ResourceAssigned = RootBridges[Index].ResourceAssigned; + } else { + ASSERT (ResourceAssigned == RootBridges[Index].ResourceAssigned); + } + if (RootBridges[Index].Io.Base <= RootBridges[Index].Io.Limit) { Status = AddIoSpace ( RootBridges[Index].Io.Base, RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1 ); ASSERT_EFI_ERROR (Status); + if (ResourceAssigned) { + Status = gDS->AllocateIoSpace ( + EfiGcdAllocateAddress, + EfiGcdIoTypeIo, + 0, + RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1, + &RootBridges[Index].Io.Base, + gImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + } } // @@ -428,11 +431,55 @@ InitializePciHostBridge ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY_UC to MMIO aperture - %r.\n", Status)); } + if (ResourceAssigned) { + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + EfiGcdMemoryTypeMemoryMappedIo, + 0, + MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1, + &MemApertures[MemApertureIndex]->Base, + gImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + } } } // // Insert Root Bridge Handle Instance // + InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); + } + + // + // When resources were assigned, it's not needed to expose + // PciHostBridgeResourceAllocation protocol. + // + if (!ResourceAssigned) { + HostBridge->ResAlloc.NotifyPhase = NotifyPhase; + HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge; + HostBridge->ResAlloc.GetAllocAttributes = GetAttributes; + HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration; + HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers; + HostBridge->ResAlloc.SubmitResources = SubmitResources; + HostBridge->ResAlloc.GetProposedResources = GetProposedResources; + HostBridge->ResAlloc.PreprocessController = PreprocessController; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &HostBridge->Handle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + for (Link = GetFirstNode (&HostBridge->RootBridges) + ; !IsNull (&HostBridge->RootBridges, Link) + ; Link = GetNextNode (&HostBridge->RootBridges, Link) + ) { + RootBridge = ROOT_BRIDGE_FROM_LINK (Link); + RootBridge->RootBridgeIo.ParentHandle = HostBridge->Handle; + Status = gBS->InstallMultipleProtocolInterfaces ( &RootBridge->Handle, &gEfiDevicePathProtocolGuid, RootBridge->DevicePath, @@ -440,7 +487,6 @@ InitializePciHostBridge ( NULL ); ASSERT_EFI_ERROR (Status); - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); } PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); return Status; diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h index aa3f43a511..13185b41ac 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h @@ -90,15 +90,13 @@ typedef struct { Construct the Pci Root Bridge instance. @param Bridge The root bridge instance. - @param HostBridgeHandle Handle to the HostBridge. @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created or NULL if creation fails. **/ PCI_ROOT_BRIDGE_INSTANCE * CreateRootBridge ( - IN PCI_ROOT_BRIDGE *Bridge, - IN EFI_HANDLE HostBridgeHandle + IN PCI_ROOT_BRIDGE *Bridge ); // diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c index dbb415ac2d..78811419bf 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c @@ -59,20 +59,19 @@ UINT8 mOutStride[] = { Construct the Pci Root Bridge instance. @param Bridge The root bridge instance. - @param HostBridgeHandle Handle to the HostBridge. @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created or NULL if creation fails. **/ PCI_ROOT_BRIDGE_INSTANCE * CreateRootBridge ( - IN PCI_ROOT_BRIDGE *Bridge, - IN EFI_HANDLE HostBridgeHandle + IN PCI_ROOT_BRIDGE *Bridge ) { PCI_ROOT_BRIDGE_INSTANCE *RootBridge; PCI_RESOURCE_TYPE Index; CHAR16 *DevicePathStr; + PCI_ROOT_BRIDGE_APERTURE *Aperture; DevicePathStr = NULL; @@ -120,32 +119,37 @@ CreateRootBridge ( } } - if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) { - // - // If this bit is set, then the PCI Root Bridge does not - // support separate windows for Non-prefetchable and Prefetchable - // memory. - // - ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit); - ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); - if ((Bridge->PMem.Base <= Bridge->PMem.Limit) || - (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) - ) { - return NULL; + // + // Ignore AllocationAttributes when resources were already assigned. + // + if (!Bridge->ResourceAssigned) { + if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) { + // + // If this bit is set, then the PCI Root Bridge does not + // support separate windows for Non-prefetchable and Prefetchable + // memory. + // + ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit); + ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); + if ((Bridge->PMem.Base <= Bridge->PMem.Limit) || + (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) + ) { + return NULL; + } } - } - if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) { - // - // If this bit is not set, then the PCI Root Bridge does not support - // 64 bit memory windows. - // - ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit); - ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); - if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) || - (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) - ) { - return NULL; + if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) { + // + // If this bit is not set, then the PCI Root Bridge does not support + // 64 bit memory windows. + // + ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit); + ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); + if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) || + (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) + ) { + return NULL; + } } } @@ -174,14 +178,42 @@ CreateRootBridge ( CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE)); for (Index = TypeIo; Index < TypeMax; Index++) { - RootBridge->ResAllocNode[Index].Type = Index; - RootBridge->ResAllocNode[Index].Base = 0; - RootBridge->ResAllocNode[Index].Length = 0; - RootBridge->ResAllocNode[Index].Status = ResNone; + switch (Index) { + case TypeBus: + Aperture = &RootBridge->Bus; + break; + case TypeIo: + Aperture = &RootBridge->Io; + break; + case TypeMem32: + Aperture = &RootBridge->Mem; + break; + case TypeMem64: + Aperture = &RootBridge->MemAbove4G; + break; + case TypePMem32: + Aperture = &RootBridge->PMem; + break; + case TypePMem64: + Aperture = &RootBridge->PMemAbove4G; + break; + default: + ASSERT (FALSE); + break; + } + RootBridge->ResAllocNode[Index].Type = Index; + if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) { + RootBridge->ResAllocNode[Index].Base = Aperture->Base; + RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1; + RootBridge->ResAllocNode[Index].Status = ResAllocated; + } else { + RootBridge->ResAllocNode[Index].Base = 0; + RootBridge->ResAllocNode[Index].Length = 0; + RootBridge->ResAllocNode[Index].Status = ResNone; + } } RootBridge->RootBridgeIo.SegmentNumber = Bridge->Segment; - RootBridge->RootBridgeIo.ParentHandle = HostBridgeHandle; RootBridge->RootBridgeIo.PollMem = RootBridgeIoPollMem; RootBridge->RootBridgeIo.PollIo = RootBridgeIoPollIo; RootBridge->RootBridgeIo.Mem.Read = RootBridgeIoMemRead;