X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FPciHostBridgeDxe%2FPciHostBridge.c;h=70726a6be8ff0d959956573ea5f3e47556edf2b3;hb=c15da8eb3587f2371df330bc4bcb5a31b2efac0d;hp=07ed54b08e1305d47f85226e1e5f6dd02c0210c8;hpb=f9607bef04a9abb698f9f8b4518b7955dc326521;p=mirror_edk2.git diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c index 07ed54b08e..70726a6be8 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c @@ -28,6 +28,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] = { L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus" }; +EDKII_IOMMU_PROTOCOL *mIoMmuProtocol; +EFI_EVENT mIoMmuEvent; +VOID *mIoMmuRegistration; + /** Ensure the compatibility of an IO space descriptor with the IO aperture. @@ -312,6 +316,28 @@ FreeMemorySpaceMap: return Status; } +/** + Event notification that is fired when IOMMU protocol is installed. + + @param Event The Event that is being processed. + @param Context Event Context. + +**/ +VOID +EFIAPI +IoMmuProtocolCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol); + if (!EFI_ERROR(Status)) { + gBS->CloseEvent (mIoMmuEvent); + } +} + /** Entry point of this driver. @@ -338,6 +364,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 +386,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 +395,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); + } } // @@ -412,7 +441,7 @@ InitializePciHostBridge ( MemApertures[2] = &RootBridges[Index].PMem; MemApertures[3] = &RootBridges[Index].PMemAbove4G; - for (MemApertureIndex = 0; MemApertureIndex < sizeof (MemApertures) / sizeof (MemApertures[0]); MemApertureIndex++) { + for (MemApertureIndex = 0; MemApertureIndex < ARRAY_SIZE (MemApertures); MemApertureIndex++) { if (MemApertures[MemApertureIndex]->Base <= MemApertures[MemApertureIndex]->Limit) { Status = AddMemoryMappedIoSpace ( MemApertures[MemApertureIndex]->Base, @@ -428,11 +457,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,9 +513,19 @@ InitializePciHostBridge ( NULL ); ASSERT_EFI_ERROR (Status); - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); } PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); + + if (!EFI_ERROR (Status)) { + mIoMmuEvent = EfiCreateProtocolNotifyEvent ( + &gEdkiiIoMmuProtocolGuid, + TPL_CALLBACK, + IoMmuProtocolCallback, + NULL, + &mIoMmuRegistration + ); + } + return Status; }