diff options
Diffstat (limited to 'MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c')
-rw-r--r-- | MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 1471 |
1 files changed, 0 insertions, 1471 deletions
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c deleted file mode 100644 index 9005deeac2..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c +++ /dev/null @@ -1,1471 +0,0 @@ -/** @file
-
- Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
-
-Copyright (c) 1999 - 2016, 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
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "PciHostBridge.h"
-#include "PciRootBridge.h"
-#include "PciHostResource.h"
-
-
-EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
-EFI_CPU_IO2_PROTOCOL *mCpuIo;
-
-GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mAcpiAddressSpaceTypeStr[] = {
- L"Mem", L"I/O", L"Bus"
-};
-GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] = {
- L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"
-};
-
-/**
- Ensure the compatibility of an IO space descriptor with the IO aperture.
-
- The IO space descriptor can come from the GCD IO space map, or it can
- represent a gap between two neighboring IO space descriptors. In the latter
- case, the GcdIoType field is expected to be EfiGcdIoTypeNonExistent.
-
- If the IO space descriptor already has type EfiGcdIoTypeIo, then no action is
- taken -- it is by definition compatible with the aperture.
-
- Otherwise, the intersection of the IO space descriptor is calculated with the
- aperture. If the intersection is the empty set (no overlap), no action is
- taken; the IO space descriptor is compatible with the aperture.
-
- Otherwise, the type of the descriptor is investigated again. If the type is
- EfiGcdIoTypeNonExistent (representing a gap, or a genuine descriptor with
- such a type), then an attempt is made to add the intersection as IO space to
- the GCD IO space map. This ensures continuity for the aperture, and the
- descriptor is deemed compatible with the aperture.
-
- Otherwise, the IO space descriptor is incompatible with the IO aperture.
-
- @param[in] Base Base address of the aperture.
- @param[in] Length Length of the aperture.
- @param[in] Descriptor The descriptor to ensure compatibility with the
- aperture for.
-
- @retval EFI_SUCCESS The descriptor is compatible. The GCD IO space
- map may have been updated, for continuity
- within the aperture.
- @retval EFI_INVALID_PARAMETER The descriptor is incompatible.
- @return Error codes from gDS->AddIoSpace().
-**/
-EFI_STATUS
-IntersectIoDescriptor (
- IN UINT64 Base,
- IN UINT64 Length,
- IN CONST EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor
- )
-{
- UINT64 IntersectionBase;
- UINT64 IntersectionEnd;
- EFI_STATUS Status;
-
- if (Descriptor->GcdIoType == EfiGcdIoTypeIo) {
- return EFI_SUCCESS;
- }
-
- IntersectionBase = MAX (Base, Descriptor->BaseAddress);
- IntersectionEnd = MIN (Base + Length,
- Descriptor->BaseAddress + Descriptor->Length);
- if (IntersectionBase >= IntersectionEnd) {
- //
- // The descriptor and the aperture don't overlap.
- //
- return EFI_SUCCESS;
- }
-
- if (Descriptor->GcdIoType == EfiGcdIoTypeNonExistent) {
- Status = gDS->AddIoSpace (EfiGcdIoTypeIo, IntersectionBase,
- IntersectionEnd - IntersectionBase);
-
- DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE,
- "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__,
- IntersectionBase, IntersectionEnd, Status));
- return Status;
- }
-
- DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u conflicts with "
- "aperture [%Lx, %Lx)\n", gEfiCallerBaseName, __FUNCTION__,
- Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length,
- (UINT32)Descriptor->GcdIoType, Base, Base + Length));
- return EFI_INVALID_PARAMETER;
-}
-
-/**
- Add IO space to GCD.
- The routine checks the GCD database and only adds those which are
- not added in the specified range to GCD.
-
- @param Base Base address of the IO space.
- @param Length Length of the IO space.
-
- @retval EFI_SUCCES The IO space was added successfully.
-**/
-EFI_STATUS
-AddIoSpace (
- IN UINT64 Base,
- IN UINT64 Length
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- UINTN NumberOfDescriptors;
- EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap;
-
- Status = gDS->GetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "%a: %a: GetIoSpaceMap(): %r\n",
- gEfiCallerBaseName, __FUNCTION__, Status));
- return Status;
- }
-
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- Status = IntersectIoDescriptor (Base, Length, &IoSpaceMap[Index]);
- if (EFI_ERROR (Status)) {
- goto FreeIoSpaceMap;
- }
- }
-
- DEBUG_CODE (
- //
- // Make sure there are adjacent descriptors covering [Base, Base + Length).
- // It is possible that they have not been merged; merging can be prevented
- // by allocation.
- //
- UINT64 CheckBase;
- EFI_STATUS CheckStatus;
- EFI_GCD_IO_SPACE_DESCRIPTOR Descriptor;
-
- for (CheckBase = Base;
- CheckBase < Base + Length;
- CheckBase = Descriptor.BaseAddress + Descriptor.Length) {
- CheckStatus = gDS->GetIoSpaceDescriptor (CheckBase, &Descriptor);
- ASSERT_EFI_ERROR (CheckStatus);
- ASSERT (Descriptor.GcdIoType == EfiGcdIoTypeIo);
- }
- );
-
-FreeIoSpaceMap:
- FreePool (IoSpaceMap);
-
- return Status;
-}
-
-/**
- Ensure the compatibility of a memory space descriptor with the MMIO aperture.
-
- The memory space descriptor can come from the GCD memory space map, or it can
- represent a gap between two neighboring memory space descriptors. In the
- latter case, the GcdMemoryType field is expected to be
- EfiGcdMemoryTypeNonExistent.
-
- If the memory space descriptor already has type
- EfiGcdMemoryTypeMemoryMappedIo, and its capabilities are a superset of the
- required capabilities, then no action is taken -- it is by definition
- compatible with the aperture.
-
- Otherwise, the intersection of the memory space descriptor is calculated with
- the aperture. If the intersection is the empty set (no overlap), no action is
- taken; the memory space descriptor is compatible with the aperture.
-
- Otherwise, the type of the descriptor is investigated again. If the type is
- EfiGcdMemoryTypeNonExistent (representing a gap, or a genuine descriptor with
- such a type), then an attempt is made to add the intersection as MMIO space
- to the GCD memory space map, with the specified capabilities. This ensures
- continuity for the aperture, and the descriptor is deemed compatible with the
- aperture.
-
- Otherwise, the memory space descriptor is incompatible with the MMIO
- aperture.
-
- @param[in] Base Base address of the aperture.
- @param[in] Length Length of the aperture.
- @param[in] Capabilities Capabilities required by the aperture.
- @param[in] Descriptor The descriptor to ensure compatibility with the
- aperture for.
-
- @retval EFI_SUCCESS The descriptor is compatible. The GCD memory
- space map may have been updated, for
- continuity within the aperture.
- @retval EFI_INVALID_PARAMETER The descriptor is incompatible.
- @return Error codes from gDS->AddMemorySpace().
-**/
-EFI_STATUS
-IntersectMemoryDescriptor (
- IN UINT64 Base,
- IN UINT64 Length,
- IN UINT64 Capabilities,
- IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
- )
-{
- UINT64 IntersectionBase;
- UINT64 IntersectionEnd;
- EFI_STATUS Status;
-
- if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo &&
- (Descriptor->Capabilities & Capabilities) == Capabilities) {
- return EFI_SUCCESS;
- }
-
- IntersectionBase = MAX (Base, Descriptor->BaseAddress);
- IntersectionEnd = MIN (Base + Length,
- Descriptor->BaseAddress + Descriptor->Length);
- if (IntersectionBase >= IntersectionEnd) {
- //
- // The descriptor and the aperture don't overlap.
- //
- return EFI_SUCCESS;
- }
-
- if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
- Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
- IntersectionBase, IntersectionEnd - IntersectionBase,
- Capabilities);
-
- DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE,
- "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__,
- IntersectionBase, IntersectionEnd, Status));
- return Status;
- }
-
- DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "
- "with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__,
- Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length,
- (UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities,
- Base, Base + Length, Capabilities));
- return EFI_INVALID_PARAMETER;
-}
-
-/**
- Add MMIO space to GCD.
- The routine checks the GCD database and only adds those which are
- not added in the specified range to GCD.
-
- @param Base Base address of the MMIO space.
- @param Length Length of the MMIO space.
- @param Capabilities Capabilities of the MMIO space.
-
- @retval EFI_SUCCES The MMIO space was added successfully.
-**/
-EFI_STATUS
-AddMemoryMappedIoSpace (
- IN UINT64 Base,
- IN UINT64 Length,
- IN UINT64 Capabilities
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- UINTN NumberOfDescriptors;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
-
- Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",
- gEfiCallerBaseName, __FUNCTION__, Status));
- return Status;
- }
-
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- Status = IntersectMemoryDescriptor (Base, Length, Capabilities,
- &MemorySpaceMap[Index]);
- if (EFI_ERROR (Status)) {
- goto FreeMemorySpaceMap;
- }
- }
-
- DEBUG_CODE (
- //
- // Make sure there are adjacent descriptors covering [Base, Base + Length).
- // It is possible that they have not been merged; merging can be prevented
- // by allocation and different capabilities.
- //
- UINT64 CheckBase;
- EFI_STATUS CheckStatus;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
-
- for (CheckBase = Base;
- CheckBase < Base + Length;
- CheckBase = Descriptor.BaseAddress + Descriptor.Length) {
- CheckStatus = gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor);
- ASSERT_EFI_ERROR (CheckStatus);
- ASSERT (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo);
- ASSERT ((Descriptor.Capabilities & Capabilities) == Capabilities);
- }
- );
-
-FreeMemorySpaceMap:
- FreePool (MemorySpaceMap);
-
- return Status;
-}
-
-/**
-
- Entry point of this driver.
-
- @param ImageHandle Image handle of this driver.
- @param SystemTable Pointer to standard EFI system table.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol.
-
-**/
-EFI_STATUS
-EFIAPI
-InitializePciHostBridge (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- PCI_ROOT_BRIDGE *RootBridges;
- UINTN RootBridgeCount;
- UINTN Index;
- PCI_ROOT_BRIDGE_APERTURE *MemApertures[4];
- UINTN MemApertureIndex;
- BOOLEAN ResourceAssigned;
- LIST_ENTRY *Link;
-
- RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount);
- if ((RootBridges == NULL) || (RootBridgeCount == 0)) {
- return EFI_UNSUPPORTED;
- }
-
- Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **) &mMetronome);
- ASSERT_EFI_ERROR (Status);
- Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) &mCpuIo);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Most systems in the world including complex servers have only one Host Bridge.
- //
- HostBridge = AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE));
- ASSERT (HostBridge != NULL);
-
- HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE;
- HostBridge->CanRestarted = TRUE;
- InitializeListHead (&HostBridge->RootBridges);
- ResourceAssigned = FALSE;
-
- //
- // Create Root Bridge Device Handle in this Host Bridge
- //
- for (Index = 0; Index < RootBridgeCount; Index++) {
- //
- // Create Root Bridge Handle Instance
- //
- 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);
- }
- }
-
- //
- // Add all the Mem/PMem aperture to GCD
- // Mem/PMem shouldn't overlap with each other
- // Root bridge which needs to combine MEM and PMEM should only report
- // the MEM aperture in Mem
- //
- MemApertures[0] = &RootBridges[Index].Mem;
- MemApertures[1] = &RootBridges[Index].MemAbove4G;
- MemApertures[2] = &RootBridges[Index].PMem;
- MemApertures[3] = &RootBridges[Index].PMemAbove4G;
-
- for (MemApertureIndex = 0; MemApertureIndex < ARRAY_SIZE (MemApertures); MemApertureIndex++) {
- if (MemApertures[MemApertureIndex]->Base <= MemApertures[MemApertureIndex]->Limit) {
- Status = AddMemoryMappedIoSpace (
- MemApertures[MemApertureIndex]->Base,
- MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,
- EFI_MEMORY_UC
- );
- ASSERT_EFI_ERROR (Status);
- Status = gDS->SetMemorySpaceAttributes (
- MemApertures[MemApertureIndex]->Base,
- MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,
- EFI_MEMORY_UC
- );
- 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,
- &gEfiPciRootBridgeIoProtocolGuid, &RootBridge->RootBridgeIo,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- }
- PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
- return Status;
-}
-
-/**
- This routine constructs the resource descriptors for all root bridges and call PciHostBridgeResourceConflict().
-
- @param HostBridge The Host Bridge Instance where the resource adjustment happens.
-**/
-VOID
-ResourceConflict (
- IN PCI_HOST_BRIDGE_INSTANCE *HostBridge
- )
-{
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
- EFI_ACPI_END_TAG_DESCRIPTOR *End;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- LIST_ENTRY *Link;
- UINTN RootBridgeCount;
- PCI_RESOURCE_TYPE Index;
- PCI_RES_NODE *ResAllocNode;
-
- RootBridgeCount = 0;
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridgeCount++;
- }
-
- Resources = AllocatePool (
- RootBridgeCount * (TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)) +
- sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
- );
- ASSERT (Resources != NULL);
-
- for (Link = GetFirstNode (&HostBridge->RootBridges), Descriptor = Resources
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- for (Index = TypeIo; Index < TypeMax; Index++) {
- ResAllocNode = &RootBridge->ResAllocNode[Index];
-
- Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
- Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
- Descriptor->AddrRangeMin = ResAllocNode->Base;
- Descriptor->AddrRangeMax = ResAllocNode->Alignment;
- Descriptor->AddrLen = ResAllocNode->Length;
- switch (ResAllocNode->Type) {
-
- case TypeIo:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
- break;
-
- case TypePMem32:
- Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
- case TypeMem32:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
- Descriptor->AddrSpaceGranularity = 32;
- break;
-
- case TypePMem64:
- Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
- case TypeMem64:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
- Descriptor->AddrSpaceGranularity = 64;
- break;
-
- case TypeBus:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
- break;
-
- default:
- break;
- }
-
- Descriptor++;
- }
- //
- // Terminate the root bridge resources.
- //
- End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor;
- End->Desc = ACPI_END_TAG_DESCRIPTOR;
- End->Checksum = 0x0;
-
- Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (End + 1);
- }
- //
- // Terminate the host bridge resources.
- //
- End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor;
- End->Desc = ACPI_END_TAG_DESCRIPTOR;
- End->Checksum = 0x0;
-
- DEBUG ((DEBUG_ERROR, "Call PciHostBridgeResourceConflict().\n"));
- PciHostBridgeResourceConflict (HostBridge->Handle, Resources);
- FreePool (Resources);
-}
-
-/**
- Allocate Length of MMIO or IO resource with alignment BitsOfAlignment
- from GCD range [BaseAddress, Limit).
-
- @param Mmio TRUE for MMIO and FALSE for IO.
- @param Length Length of the resource to allocate.
- @param BitsOfAlignment Alignment of the resource to allocate.
- @param BaseAddress The starting address the allocation is from.
- @param Limit The ending address the allocation is to.
-
- @retval The base address of the allocated resource or MAX_UINT64 if allocation
- fails.
-**/
-UINT64
-AllocateResource (
- BOOLEAN Mmio,
- UINT64 Length,
- UINTN BitsOfAlignment,
- UINT64 BaseAddress,
- UINT64 Limit
- )
-{
- EFI_STATUS Status;
-
- if (BaseAddress < Limit) {
- //
- // Have to make sure Aligment is handled since we are doing direct address allocation
- //
- BaseAddress = ALIGN_VALUE (BaseAddress, LShiftU64 (1, BitsOfAlignment));
-
- while (BaseAddress + Length <= Limit + 1) {
- if (Mmio) {
- Status = gDS->AllocateMemorySpace (
- EfiGcdAllocateAddress,
- EfiGcdMemoryTypeMemoryMappedIo,
- BitsOfAlignment,
- Length,
- &BaseAddress,
- gImageHandle,
- NULL
- );
- } else {
- Status = gDS->AllocateIoSpace (
- EfiGcdAllocateAddress,
- EfiGcdIoTypeIo,
- BitsOfAlignment,
- Length,
- &BaseAddress,
- gImageHandle,
- NULL
- );
- }
-
- if (!EFI_ERROR (Status)) {
- return BaseAddress;
- }
- BaseAddress += LShiftU64 (1, BitsOfAlignment);
- }
- }
- return MAX_UINT64;
-}
-
-/**
-
- Enter a certain phase of the PCI enumeration process.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
- @param Phase The phase during enumeration.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_INVALID_PARAMETER Wrong phase parameter passed in.
- @retval EFI_NOT_READY Resources have not been submitted yet.
-
-**/
-EFI_STATUS
-EFIAPI
-NotifyPhase (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
- )
-{
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- LIST_ENTRY *Link;
- EFI_PHYSICAL_ADDRESS BaseAddress;
- UINTN BitsOfAlignment;
- UINT64 Alignment;
- EFI_STATUS Status;
- EFI_STATUS ReturnStatus;
- PCI_RESOURCE_TYPE Index;
- PCI_RESOURCE_TYPE Index1;
- PCI_RESOURCE_TYPE Index2;
- BOOLEAN ResNodeHandled[TypeMax];
- UINT64 MaxAlignment;
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
-
- switch (Phase) {
- case EfiPciHostBridgeBeginEnumeration:
- if (!HostBridge->CanRestarted) {
- return EFI_NOT_READY;
- }
- //
- // Reset Root Bridge
- //
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- 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;
-
- RootBridge->ResourceSubmitted = FALSE;
- }
- }
-
- HostBridge->CanRestarted = TRUE;
- break;
-
- case EfiPciHostBridgeBeginBusAllocation:
- //
- // No specific action is required here, can perform any chipset specific programing
- //
- HostBridge->CanRestarted = FALSE;
- break;
-
- case EfiPciHostBridgeEndBusAllocation:
- //
- // No specific action is required here, can perform any chipset specific programing
- //
- break;
-
- case EfiPciHostBridgeBeginResourceAllocation:
- //
- // No specific action is required here, can perform any chipset specific programing
- //
- break;
-
- case EfiPciHostBridgeAllocateResources:
- ReturnStatus = EFI_SUCCESS;
-
- //
- // Make sure the resource for all root bridges has been submitted.
- //
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (!RootBridge->ResourceSubmitted) {
- return EFI_NOT_READY;
- }
- }
-
- DEBUG ((EFI_D_INFO, "PciHostBridge: NotifyPhase (AllocateResources)\n"));
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- for (Index = TypeIo; Index < TypeBus; Index++) {
- ResNodeHandled[Index] = FALSE;
- }
-
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- DEBUG ((EFI_D_INFO, " RootBridge: %s\n", RootBridge->DevicePathStr));
-
- for (Index1 = TypeIo; Index1 < TypeBus; Index1++) {
- if (RootBridge->ResAllocNode[Index1].Status == ResNone) {
- ResNodeHandled[Index1] = TRUE;
- } else {
- //
- // Allocate the resource node with max alignment at first
- //
- MaxAlignment = 0;
- Index = TypeMax;
- for (Index2 = TypeIo; Index2 < TypeBus; Index2++) {
- if (ResNodeHandled[Index2]) {
- continue;
- }
- if (MaxAlignment <= RootBridge->ResAllocNode[Index2].Alignment) {
- MaxAlignment = RootBridge->ResAllocNode[Index2].Alignment;
- Index = Index2;
- }
- }
-
- ASSERT (Index < TypeMax);
- ResNodeHandled[Index] = TRUE;
- Alignment = RootBridge->ResAllocNode[Index].Alignment;
- BitsOfAlignment = LowBitSet64 (Alignment + 1);
- BaseAddress = MAX_UINT64;
-
- switch (Index) {
- case TypeIo:
- BaseAddress = AllocateResource (
- FALSE,
- RootBridge->ResAllocNode[Index].Length,
- MIN (15, BitsOfAlignment),
- ALIGN_VALUE (RootBridge->Io.Base, Alignment + 1),
- RootBridge->Io.Limit
- );
- break;
-
- case TypeMem64:
- BaseAddress = AllocateResource (
- TRUE,
- RootBridge->ResAllocNode[Index].Length,
- MIN (63, BitsOfAlignment),
- ALIGN_VALUE (RootBridge->MemAbove4G.Base, Alignment + 1),
- RootBridge->MemAbove4G.Limit
- );
- if (BaseAddress != MAX_UINT64) {
- break;
- }
- //
- // If memory above 4GB is not available, try memory below 4GB
- //
-
- case TypeMem32:
- BaseAddress = AllocateResource (
- TRUE,
- RootBridge->ResAllocNode[Index].Length,
- MIN (31, BitsOfAlignment),
- ALIGN_VALUE (RootBridge->Mem.Base, Alignment + 1),
- RootBridge->Mem.Limit
- );
- break;
-
- case TypePMem64:
- BaseAddress = AllocateResource (
- TRUE,
- RootBridge->ResAllocNode[Index].Length,
- MIN (63, BitsOfAlignment),
- ALIGN_VALUE (RootBridge->PMemAbove4G.Base, Alignment + 1),
- RootBridge->PMemAbove4G.Limit
- );
- if (BaseAddress != MAX_UINT64) {
- break;
- }
- //
- // If memory above 4GB is not available, try memory below 4GB
- //
- case TypePMem32:
- BaseAddress = AllocateResource (
- TRUE,
- RootBridge->ResAllocNode[Index].Length,
- MIN (31, BitsOfAlignment),
- ALIGN_VALUE (RootBridge->PMem.Base, Alignment + 1),
- RootBridge->PMem.Limit
- );
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-
- DEBUG ((DEBUG_INFO, " %s: Base/Length/Alignment = %lx/%lx/%lx - ",
- mPciResourceTypeStr[Index], BaseAddress, RootBridge->ResAllocNode[Index].Length, Alignment));
- if (BaseAddress != MAX_UINT64) {
- RootBridge->ResAllocNode[Index].Base = BaseAddress;
- RootBridge->ResAllocNode[Index].Status = ResAllocated;
- DEBUG ((DEBUG_INFO, "Success\n"));
- } else {
- ReturnStatus = EFI_OUT_OF_RESOURCES;
- DEBUG ((DEBUG_ERROR, "Out Of Resource!\n"));
- }
- }
- }
- }
-
- if (ReturnStatus == EFI_OUT_OF_RESOURCES) {
- ResourceConflict (HostBridge);
- }
-
- //
- // Set resource to zero for nodes where allocation fails
- //
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- for (Index = TypeIo; Index < TypeBus; Index++) {
- if (RootBridge->ResAllocNode[Index].Status != ResAllocated) {
- RootBridge->ResAllocNode[Index].Length = 0;
- }
- }
- }
- return ReturnStatus;
-
- case EfiPciHostBridgeSetResources:
- //
- // HostBridgeInstance->CanRestarted = FALSE;
- //
- break;
-
- case EfiPciHostBridgeFreeResources:
- //
- // HostBridgeInstance->CanRestarted = FALSE;
- //
- ReturnStatus = EFI_SUCCESS;
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- for (Index = TypeIo; Index < TypeBus; Index++) {
- if (RootBridge->ResAllocNode[Index].Status == ResAllocated) {
- switch (Index) {
- case TypeIo:
- Status = gDS->FreeIoSpace (RootBridge->ResAllocNode[Index].Base, RootBridge->ResAllocNode[Index].Length);
- if (EFI_ERROR (Status)) {
- ReturnStatus = Status;
- }
- break;
-
- case TypeMem32:
- case TypePMem32:
- case TypeMem64:
- case TypePMem64:
- Status = gDS->FreeMemorySpace (RootBridge->ResAllocNode[Index].Base, RootBridge->ResAllocNode[Index].Length);
- if (EFI_ERROR (Status)) {
- ReturnStatus = Status;
- }
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-
- RootBridge->ResAllocNode[Index].Type = Index;
- RootBridge->ResAllocNode[Index].Base = 0;
- RootBridge->ResAllocNode[Index].Length = 0;
- RootBridge->ResAllocNode[Index].Status = ResNone;
- }
- }
-
- RootBridge->ResourceSubmitted = FALSE;
- }
-
- HostBridge->CanRestarted = TRUE;
- return ReturnStatus;
-
- case EfiPciHostBridgeEndResourceAllocation:
- //
- // The resource allocation phase is completed. No specific action is required
- // here. This notification can be used to perform any chipset specific programming.
- //
- break;
-
- case EfiPciHostBridgeEndEnumeration:
- //
- // The Host Bridge Enumeration is completed. No specific action is required here.
- // This notification can be used to perform any chipset specific programming.
- //
- break;
-
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
-
- Return the device handle of the next PCI root bridge that is associated with
- this Host Bridge.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle Returns the device handle of the next PCI Root Bridge.
- On input, it holds the RootBridgeHandle returned by the most
- recent call to GetNextRootBridge().The handle for the first
- PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_NOT_FOUND Next PCI root bridge not found.
- @retval EFI_INVALID_PARAMETER Wrong parameter passed in.
-
-**/
-EFI_STATUS
-EFIAPI
-GetNextRootBridge (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN OUT EFI_HANDLE *RootBridgeHandle
- )
-{
- BOOLEAN ReturnNext;
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
-
- if (RootBridgeHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- ReturnNext = (BOOLEAN) (*RootBridgeHandle == NULL);
-
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (ReturnNext) {
- *RootBridgeHandle = RootBridge->Handle;
- return EFI_SUCCESS;
- }
-
- ReturnNext = (BOOLEAN) (*RootBridgeHandle == RootBridge->Handle);
- }
-
- if (ReturnNext) {
- ASSERT (IsNull (&HostBridge->RootBridges, Link));
- return EFI_NOT_FOUND;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-}
-
-/**
-
- Returns the attributes of a PCI Root Bridge.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The device handle of the PCI Root Bridge
- that the caller is interested in.
- @param Attributes The pointer to attributes of the PCI Root Bridge.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_INVALID_PARAMETER Attributes parameter passed in is NULL or
- RootBridgeHandle is not an EFI_HANDLE
- that was returned on a previous call to
- GetNextRootBridge().
-
-**/
-EFI_STATUS
-EFIAPI
-GetAttributes (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- OUT UINT64 *Attributes
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
-
- if (Attributes == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
- *Attributes = RootBridge->AllocationAttributes;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
-
- This is the request from the PCI enumerator to set up
- the specified PCI Root Bridge for bus enumeration process.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The PCI Root Bridge to be set up.
- @param Configuration Pointer to the pointer to the PCI bus resource descriptor.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_OUT_OF_RESOURCES Not enough pool to be allocated.
- @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle.
-
-**/
-EFI_STATUS
-EFIAPI
-StartBusEnumeration (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- OUT VOID **Configuration
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
- EFI_ACPI_END_TAG_DESCRIPTOR *End;
-
- if (Configuration == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
- *Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
- if (*Configuration == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) *Configuration;
- Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
- Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
- Descriptor->GenFlag = 0;
- Descriptor->SpecificFlag = 0;
- Descriptor->AddrSpaceGranularity = 0;
- Descriptor->AddrRangeMin = RootBridge->Bus.Base;
- Descriptor->AddrRangeMax = 0;
- Descriptor->AddrTranslationOffset = 0;
- Descriptor->AddrLen = RootBridge->Bus.Limit - RootBridge->Bus.Base + 1;
-
- End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1);
- End->Desc = ACPI_END_TAG_DESCRIPTOR;
- End->Checksum = 0x0;
-
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
-
- This function programs the PCI Root Bridge hardware so that
- it decodes the specified PCI bus range.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The PCI Root Bridge whose bus range is to be programmed.
- @param Configuration The pointer to the PCI bus resource descriptor.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_INVALID_PARAMETER Wrong parameters passed in.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBusNumbers (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- IN VOID *Configuration
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
- EFI_ACPI_END_TAG_DESCRIPTOR *End;
-
- if (Configuration == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
- End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1);
-
- //
- // Check the Configuration is valid
- //
- if ((Descriptor->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) ||
- (Descriptor->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) ||
- (End->Desc != ACPI_END_TAG_DESCRIPTOR)
- ) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
-
- if (Descriptor->AddrLen == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((Descriptor->AddrRangeMin < RootBridge->Bus.Base) ||
- (Descriptor->AddrRangeMin + Descriptor->AddrLen - 1 > RootBridge->Bus.Limit)
- ) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Update the Bus Range
- //
- RootBridge->ResAllocNode[TypeBus].Base = Descriptor->AddrRangeMin;
- RootBridge->ResAllocNode[TypeBus].Length = Descriptor->AddrLen;
- RootBridge->ResAllocNode[TypeBus].Status = ResAllocated;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
-
- Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The PCI Root Bridge whose I/O and memory resource requirements.
- are being submitted.
- @param Configuration The pointer to the PCI I/O and PCI memory resource descriptor.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_INVALID_PARAMETER Wrong parameters passed in.
-**/
-EFI_STATUS
-EFIAPI
-SubmitResources (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- IN VOID *Configuration
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
- PCI_RESOURCE_TYPE Type;
-
- //
- // Check the input parameter: Configuration
- //
- if (Configuration == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
- DEBUG ((EFI_D_INFO, "PciHostBridge: SubmitResources for %s\n", RootBridge->DevicePathStr));
- //
- // Check the resource descriptors.
- // If the Configuration includes one or more invalid resource descriptors, all the resource
- // descriptors are ignored and the function returns EFI_INVALID_PARAMETER.
- //
- for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
- if (Descriptor->ResType > ACPI_ADDRESS_SPACE_TYPE_BUS) {
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((EFI_D_INFO, " %s: Granularity/SpecificFlag = %ld / %02x%s\n",
- mAcpiAddressSpaceTypeStr[Descriptor->ResType], Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
- (Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0 ? L" (Prefetchable)" : L""
- ));
- DEBUG ((EFI_D_INFO, " Length/Alignment = 0x%lx / 0x%lx\n", Descriptor->AddrLen, Descriptor->AddrRangeMax));
- switch (Descriptor->ResType) {
- case ACPI_ADDRESS_SPACE_TYPE_MEM:
- if (Descriptor->AddrSpaceGranularity != 32 && Descriptor->AddrSpaceGranularity != 64) {
- return EFI_INVALID_PARAMETER;
- }
- if (Descriptor->AddrSpaceGranularity == 32 && Descriptor->AddrLen >= SIZE_4GB) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // If the PCI root bridge does not support separate windows for nonprefetchable and
- // prefetchable memory, then the PCI bus driver needs to include requests for
- // prefetchable memory in the nonprefetchable memory pool.
- //
- if (((RootBridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) &&
- ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0)
- ) {
- return EFI_INVALID_PARAMETER;
- }
- case ACPI_ADDRESS_SPACE_TYPE_IO:
- //
- // Check aligment, it should be of the form 2^n-1
- //
- if (GetPowerOfTwo64 (Descriptor->AddrRangeMax + 1) != (Descriptor->AddrRangeMax + 1)) {
- return EFI_INVALID_PARAMETER;
- }
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
- if (Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR) {
- return EFI_INVALID_PARAMETER;
- }
-
- for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
- if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
- if (Descriptor->AddrSpaceGranularity == 32) {
- if ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) {
- Type = TypePMem32;
- } else {
- Type = TypeMem32;
- }
- } else {
- ASSERT (Descriptor->AddrSpaceGranularity == 64);
- if ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) {
- Type = TypePMem64;
- } else {
- Type = TypeMem64;
- }
- }
- } else {
- ASSERT (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO);
- Type = TypeIo;
- }
- RootBridge->ResAllocNode[Type].Length = Descriptor->AddrLen;
- RootBridge->ResAllocNode[Type].Alignment = Descriptor->AddrRangeMax;
- RootBridge->ResAllocNode[Type].Status = ResSubmitted;
- }
- RootBridge->ResourceSubmitted = TRUE;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
-
- This function returns the proposed resource settings for the specified
- PCI Root Bridge.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The PCI Root Bridge handle.
- @param Configuration The pointer to the pointer to the PCI I/O
- and memory resource descriptor.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_OUT_OF_RESOURCES Not enough pool to be allocated.
- @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle.
-
-**/
-EFI_STATUS
-EFIAPI
-GetProposedResources (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- OUT VOID **Configuration
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- UINTN Index;
- UINTN Number;
- VOID *Buffer;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
- EFI_ACPI_END_TAG_DESCRIPTOR *End;
- UINT64 ResStatus;
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
- for (Index = 0, Number = 0; Index < TypeBus; Index++) {
- if (RootBridge->ResAllocNode[Index].Status != ResNone) {
- Number++;
- }
- }
-
- Buffer = AllocateZeroPool (Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Buffer;
- for (Index = 0; Index < TypeBus; Index++) {
- ResStatus = RootBridge->ResAllocNode[Index].Status;
- if (ResStatus != ResNone) {
- Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
- Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;;
- Descriptor->GenFlag = 0;
- Descriptor->AddrRangeMin = RootBridge->ResAllocNode[Index].Base;
- Descriptor->AddrRangeMax = 0;
- Descriptor->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : PCI_RESOURCE_LESS;
- Descriptor->AddrLen = RootBridge->ResAllocNode[Index].Length;
-
- switch (Index) {
-
- case TypeIo:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
- break;
-
- case TypePMem32:
- Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
- case TypeMem32:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
- Descriptor->AddrSpaceGranularity = 32;
- break;
-
- case TypePMem64:
- Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
- case TypeMem64:
- Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
- Descriptor->AddrSpaceGranularity = 64;
- break;
- }
-
- Descriptor++;
- }
- }
- End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor;
- End->Desc = ACPI_END_TAG_DESCRIPTOR;
- End->Checksum = 0;
-
- *Configuration = Buffer;
-
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
-
- This function is called for all the PCI controllers that the PCI
- bus driver finds. Can be used to Preprogram the controller.
-
- @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
- @param RootBridgeHandle The PCI Root Bridge handle.
- @param PciAddress Address of the controller on the PCI bus.
- @param Phase The Phase during resource allocation.
-
- @retval EFI_SUCCESS Succeed.
- @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle.
-
-**/
-EFI_STATUS
-EFIAPI
-PreprocessController (
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
- IN EFI_HANDLE RootBridgeHandle,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
- IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
- )
-{
- LIST_ENTRY *Link;
- PCI_HOST_BRIDGE_INSTANCE *HostBridge;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
-
- if ((UINT32) Phase > EfiPciBeforeResourceCollection) {
- return EFI_INVALID_PARAMETER;
- }
-
- HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This);
- for (Link = GetFirstNode (&HostBridge->RootBridges)
- ; !IsNull (&HostBridge->RootBridges, Link)
- ; Link = GetNextNode (&HostBridge->RootBridges, Link)
- ) {
- RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
- if (RootBridgeHandle == RootBridge->Handle) {
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
|