UINTN Index;\r
PCI_ROOT_BRIDGE_APERTURE *MemApertures[4];\r
UINTN MemApertureIndex;\r
+ BOOLEAN ResourceAssigned;\r
+ LIST_ENTRY *Link;\r
\r
RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount);\r
if ((RootBridges == NULL) || (RootBridgeCount == 0)) {\r
HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE;\r
HostBridge->CanRestarted = TRUE;\r
InitializeListHead (&HostBridge->RootBridges);\r
-\r
- HostBridge->ResAlloc.NotifyPhase = NotifyPhase;\r
- HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge;\r
- HostBridge->ResAlloc.GetAllocAttributes = GetAttributes;\r
- HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration;\r
- HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers;\r
- HostBridge->ResAlloc.SubmitResources = SubmitResources;\r
- HostBridge->ResAlloc.GetProposedResources = GetProposedResources;\r
- HostBridge->ResAlloc.PreprocessController = PreprocessController;\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &HostBridge->Handle,\r
- &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (HostBridge);\r
- PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);\r
- return Status;\r
- }\r
+ ResourceAssigned = FALSE;\r
\r
//\r
// Create Root Bridge Device Handle in this Host Bridge\r
//\r
// Create Root Bridge Handle Instance\r
//\r
- RootBridge = CreateRootBridge (&RootBridges[Index], HostBridge->Handle);\r
+ RootBridge = CreateRootBridge (&RootBridges[Index]);\r
ASSERT (RootBridge != NULL);\r
if (RootBridge == NULL) {\r
continue;\r
}\r
\r
+ //\r
+ // Make sure all root bridges share the same ResourceAssigned value.\r
+ //\r
+ if (Index == 0) {\r
+ ResourceAssigned = RootBridges[Index].ResourceAssigned;\r
+ } else {\r
+ ASSERT (ResourceAssigned == RootBridges[Index].ResourceAssigned);\r
+ }\r
+\r
if (RootBridges[Index].Io.Base <= RootBridges[Index].Io.Limit) {\r
Status = AddIoSpace (\r
RootBridges[Index].Io.Base,\r
RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1\r
);\r
ASSERT_EFI_ERROR (Status);\r
+ if (ResourceAssigned) {\r
+ Status = gDS->AllocateIoSpace (\r
+ EfiGcdAllocateAddress,\r
+ EfiGcdIoTypeIo,\r
+ 0,\r
+ RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1,\r
+ &RootBridges[Index].Io.Base,\r
+ gImageHandle,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
}\r
\r
//\r
if (EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY_UC to MMIO aperture - %r.\n", Status));\r
}\r
+ if (ResourceAssigned) {\r
+ Status = gDS->AllocateMemorySpace (\r
+ EfiGcdAllocateAddress,\r
+ EfiGcdMemoryTypeMemoryMappedIo,\r
+ 0,\r
+ MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,\r
+ &MemApertures[MemApertureIndex]->Base,\r
+ gImageHandle,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
}\r
}\r
//\r
// Insert Root Bridge Handle Instance\r
//\r
+ InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);\r
+ }\r
+\r
+ //\r
+ // When resources were assigned, it's not needed to expose\r
+ // PciHostBridgeResourceAllocation protocol.\r
+ //\r
+ if (!ResourceAssigned) {\r
+ HostBridge->ResAlloc.NotifyPhase = NotifyPhase;\r
+ HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge;\r
+ HostBridge->ResAlloc.GetAllocAttributes = GetAttributes;\r
+ HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration;\r
+ HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers;\r
+ HostBridge->ResAlloc.SubmitResources = SubmitResources;\r
+ HostBridge->ResAlloc.GetProposedResources = GetProposedResources;\r
+ HostBridge->ResAlloc.PreprocessController = PreprocessController;\r
+\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &HostBridge->Handle,\r
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ for (Link = GetFirstNode (&HostBridge->RootBridges)\r
+ ; !IsNull (&HostBridge->RootBridges, Link)\r
+ ; Link = GetNextNode (&HostBridge->RootBridges, Link)\r
+ ) {\r
+ RootBridge = ROOT_BRIDGE_FROM_LINK (Link);\r
+ RootBridge->RootBridgeIo.ParentHandle = HostBridge->Handle;\r
+\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&RootBridge->Handle,\r
&gEfiDevicePathProtocolGuid, RootBridge->DevicePath,\r
NULL\r
);\r
ASSERT_EFI_ERROR (Status);\r
- InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);\r
}\r
PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);\r
return Status;\r
Construct the Pci Root Bridge instance.\r
\r
@param Bridge The root bridge instance.\r
- @param HostBridgeHandle Handle to the HostBridge.\r
\r
@return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created\r
or NULL if creation fails.\r
**/\r
PCI_ROOT_BRIDGE_INSTANCE *\r
CreateRootBridge (\r
- IN PCI_ROOT_BRIDGE *Bridge,\r
- IN EFI_HANDLE HostBridgeHandle\r
+ IN PCI_ROOT_BRIDGE *Bridge\r
)\r
{\r
PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
PCI_RESOURCE_TYPE Index;\r
CHAR16 *DevicePathStr;\r
+ PCI_ROOT_BRIDGE_APERTURE *Aperture;\r
\r
DevicePathStr = NULL;\r
\r
}\r
}\r
\r
- if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {\r
- //\r
- // If this bit is set, then the PCI Root Bridge does not\r
- // support separate windows for Non-prefetchable and Prefetchable\r
- // memory.\r
- //\r
- ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit);\r
- ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);\r
- if ((Bridge->PMem.Base <= Bridge->PMem.Limit) ||\r
- (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)\r
- ) {\r
- return NULL;\r
+ //\r
+ // Ignore AllocationAttributes when resources were already assigned.\r
+ //\r
+ if (!Bridge->ResourceAssigned) {\r
+ if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {\r
+ //\r
+ // If this bit is set, then the PCI Root Bridge does not\r
+ // support separate windows for Non-prefetchable and Prefetchable\r
+ // memory.\r
+ //\r
+ ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit);\r
+ ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);\r
+ if ((Bridge->PMem.Base <= Bridge->PMem.Limit) ||\r
+ (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)\r
+ ) {\r
+ return NULL;\r
+ }\r
}\r
- }\r
\r
- if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) {\r
- //\r
- // If this bit is not set, then the PCI Root Bridge does not support\r
- // 64 bit memory windows.\r
- //\r
- ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit);\r
- ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);\r
- if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) ||\r
- (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)\r
- ) {\r
- return NULL;\r
+ if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) {\r
+ //\r
+ // If this bit is not set, then the PCI Root Bridge does not support\r
+ // 64 bit memory windows.\r
+ //\r
+ ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit);\r
+ ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);\r
+ if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) ||\r
+ (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)\r
+ ) {\r
+ return NULL;\r
+ }\r
}\r
}\r
\r
CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE));\r
\r
for (Index = TypeIo; Index < TypeMax; Index++) {\r
- RootBridge->ResAllocNode[Index].Type = Index;\r
- RootBridge->ResAllocNode[Index].Base = 0;\r
- RootBridge->ResAllocNode[Index].Length = 0;\r
- RootBridge->ResAllocNode[Index].Status = ResNone;\r
+ switch (Index) {\r
+ case TypeBus:\r
+ Aperture = &RootBridge->Bus;\r
+ break;\r
+ case TypeIo:\r
+ Aperture = &RootBridge->Io;\r
+ break;\r
+ case TypeMem32:\r
+ Aperture = &RootBridge->Mem;\r
+ break;\r
+ case TypeMem64:\r
+ Aperture = &RootBridge->MemAbove4G;\r
+ break;\r
+ case TypePMem32:\r
+ Aperture = &RootBridge->PMem;\r
+ break;\r
+ case TypePMem64:\r
+ Aperture = &RootBridge->PMemAbove4G;\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+ RootBridge->ResAllocNode[Index].Type = Index;\r
+ if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) {\r
+ RootBridge->ResAllocNode[Index].Base = Aperture->Base;\r
+ RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1;\r
+ RootBridge->ResAllocNode[Index].Status = ResAllocated;\r
+ } else {\r
+ RootBridge->ResAllocNode[Index].Base = 0;\r
+ RootBridge->ResAllocNode[Index].Length = 0;\r
+ RootBridge->ResAllocNode[Index].Status = ResNone;\r
+ }\r
}\r
\r
RootBridge->RootBridgeIo.SegmentNumber = Bridge->Segment;\r
- RootBridge->RootBridgeIo.ParentHandle = HostBridgeHandle;\r
RootBridge->RootBridgeIo.PollMem = RootBridgeIoPollMem;\r
RootBridge->RootBridgeIo.PollIo = RootBridgeIoPollIo;\r
RootBridge->RootBridgeIo.Mem.Read = RootBridgeIoMemRead;\r