L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"\r
};\r
\r
+EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;\r
+EFI_EVENT mIoMmuEvent;\r
+VOID *mIoMmuRegistration;\r
+\r
/**\r
Ensure the compatibility of an IO space descriptor with the IO aperture.\r
\r
return Status;\r
}\r
\r
+/**\r
+ Event notification that is fired when IOMMU protocol is installed.\r
+\r
+ @param Event The Event that is being processed.\r
+ @param Context Event Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IoMmuProtocolCallback (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol);\r
+ if (!EFI_ERROR(Status)) {\r
+ gBS->CloseEvent (mIoMmuEvent);\r
+ }\r
+}\r
+\r
/**\r
\r
Entry point of this driver.\r
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
- if (RootBridges[Index].Io.Limit > RootBridges[Index].Io.Base) {\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
MemApertures[2] = &RootBridges[Index].PMem;\r
MemApertures[3] = &RootBridges[Index].PMemAbove4G;\r
\r
- for (MemApertureIndex = 0; MemApertureIndex < sizeof (MemApertures) / sizeof (MemApertures[0]); MemApertureIndex++) {\r
- if (MemApertures[MemApertureIndex]->Limit > MemApertures[MemApertureIndex]->Base) {\r
+ for (MemApertureIndex = 0; MemApertureIndex < ARRAY_SIZE (MemApertures); MemApertureIndex++) {\r
+ if (MemApertures[MemApertureIndex]->Base <= MemApertures[MemApertureIndex]->Limit) {\r
Status = AddMemoryMappedIoSpace (\r
MemApertures[MemApertureIndex]->Base,\r
MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,\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
+\r
+ if (!EFI_ERROR (Status)) {\r
+ mIoMmuEvent = EfiCreateProtocolNotifyEvent (\r
+ &gEdkiiIoMmuProtocolGuid,\r
+ TPL_CALLBACK,\r
+ IoMmuProtocolCallback,\r
+ NULL,\r
+ &mIoMmuRegistration\r
+ );\r
+ }\r
+\r
return Status;\r
}\r
\r
PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
LIST_ENTRY *Link;\r
EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT64 AddrLen;\r
UINTN BitsOfAlignment;\r
UINT64 Alignment;\r
EFI_STATUS Status;\r
\r
ASSERT (Index < TypeMax);\r
ResNodeHandled[Index] = TRUE;\r
- AddrLen = RootBridge->ResAllocNode[Index].Length;\r
Alignment = RootBridge->ResAllocNode[Index].Alignment;\r
BitsOfAlignment = LowBitSet64 (Alignment + 1);\r
BaseAddress = MAX_UINT64;\r
PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
EFI_ACPI_END_TAG_DESCRIPTOR *End;\r
- UINTN BusStart;\r
- UINTN BusEnd;\r
- UINTN BusLen;\r
\r
if (Configuration == NULL) {\r
return EFI_INVALID_PARAMETER;\r
) {\r
RootBridge = ROOT_BRIDGE_FROM_LINK (Link);\r
if (RootBridgeHandle == RootBridge->Handle) {\r
- BusStart = (UINTN) Descriptor->AddrRangeMin;\r
- BusLen = (UINTN) Descriptor->AddrLen;\r
- BusEnd = BusStart + BusLen - 1;\r
\r
if (Descriptor->AddrLen == 0) {\r
return EFI_INVALID_PARAMETER;\r