+++ /dev/null
-/** @file\r
-* Implementation of the Pci Host Bridge Resource Allocation for the Xpress-RICH3 PCIe Root Complex\r
-*\r
-* Copyright (c) 2011-2015, ARM Ltd. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-#include "PciHostBridge.h"\r
-\r
-EFI_STATUS\r
-PciHbRaNotifyPhase (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
- PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT64 AddrLen;\r
- UINTN BitsOfAlignment;\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
-\r
- PCI_TRACE ("PciHbRaNotifyPhase()");\r
-\r
- // Check RootBridge Signature\r
- ASSERT (HostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);\r
-\r
- // The enumeration cannot be restarted after the process has been further than the first phase\r
- if (Phase == EfiPciHostBridgeBeginEnumeration) {\r
- if (!HostBridgeInstance->CanRestarted) {\r
- return EFI_NOT_READY;\r
- }\r
- } else {\r
- HostBridgeInstance->CanRestarted = FALSE;\r
- }\r
-\r
- switch (Phase) {\r
- case EfiPciHostBridgeBeginEnumeration:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginEnumeration)");\r
- // Resets the host bridge PCI apertures and internal data structures\r
- Status = HWPciRbInit (HostBridgeInstance->CpuIo);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- break;\r
-\r
- case EfiPciHostBridgeBeginBusAllocation:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginBusAllocation)");\r
- // The bus allocation phase is about to begin\r
- break;\r
-\r
- case EfiPciHostBridgeEndBusAllocation:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndBusAllocation)");\r
- // The bus allocation and bus programming phase is complete. All the PCI-to-PCI bridges have been given and written back\r
- // a bus number range into their configuration\r
- break;\r
-\r
- case EfiPciHostBridgeBeginResourceAllocation:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginResourceAllocation)");\r
- // The resource allocation phase is about to begin.\r
- break;\r
-\r
- case EfiPciHostBridgeAllocateResources:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeAllocateResources)");\r
- // Allocates resources per previously submitted requests for all the PCI root bridges. The resources have been submitted to\r
- // PciHbRaSubmitResources() before.\r
-\r
- RootBridgeInstance = HostBridgeInstance->RootBridge;\r
- if (RootBridgeInstance->ResAlloc[ResTypeIo].Length != 0) {\r
- BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeIo].Alignment) + 1; // Get the number of '1' in Alignment\r
- AddrLen = RootBridgeInstance->ResAlloc[ResTypeIo].Length;\r
-\r
- Status = gDS->AllocateIoSpace (\r
- EfiGcdAllocateAnySearchBottomUp,\r
- EfiGcdIoTypeIo,\r
- BitsOfAlignment,\r
- AddrLen,\r
- &BaseAddress,\r
- HostBridgeInstance->ImageHandle,\r
- NULL\r
- );\r
- // If error then ResAlloc[n].Base ==0\r
- if (!EFI_ERROR (Status)) {\r
- RootBridgeInstance->ResAlloc[ResTypeIo].Base = (UINTN)BaseAddress;\r
- }\r
- }\r
-\r
- if (RootBridgeInstance->ResAlloc[ResTypeMem32].Length != 0) {\r
- BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeMem32].Alignment) + 1; // Get the number of '1' in Alignment\r
- AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem32].Length;\r
-\r
- // Top of the 32bit PCI Memory space\r
- BaseAddress = FixedPcdGet64 (PcdPciMmio32Base) + FixedPcdGet64 (PcdPciMmio32Size);\r
-\r
- Status = gDS->AllocateMemorySpace (\r
- EfiGcdAllocateMaxAddressSearchTopDown,\r
- EfiGcdMemoryTypeMemoryMappedIo,\r
- BitsOfAlignment,\r
- AddrLen,\r
- &BaseAddress,\r
- HostBridgeInstance->ImageHandle,\r
- NULL\r
- );\r
-\r
- // Ensure the allocation is in the 32bit PCI memory space\r
- if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 (PcdPciMmio32Base))) {\r
- RootBridgeInstance->ResAlloc[ResTypeMem32].Base = (UINTN)BaseAddress;\r
- }\r
- }\r
- if (RootBridgeInstance->ResAlloc[ResTypePMem32].Length != 0) {\r
- BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypePMem32].Alignment) + 1; // Get the number of '1' in Alignment\r
- AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem32].Length;\r
-\r
- // Top of the 32bit PCI Memory space\r
- BaseAddress = FixedPcdGet64 (PcdPciMmio32Base) + FixedPcdGet64 (PcdPciMmio32Size);\r
-\r
- Status = gDS->AllocateMemorySpace (\r
- EfiGcdAllocateMaxAddressSearchTopDown,\r
- EfiGcdMemoryTypeMemoryMappedIo,\r
- BitsOfAlignment,\r
- AddrLen,\r
- &BaseAddress,\r
- HostBridgeInstance->ImageHandle,\r
- NULL\r
- );\r
-\r
- // Ensure the allocation is in the 32bit PCI memory space\r
- if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 (PcdPciMmio32Base))) {\r
- RootBridgeInstance->ResAlloc[ResTypePMem32].Base = (UINTN)BaseAddress;\r
- }\r
- }\r
- if (RootBridgeInstance->ResAlloc[ResTypeMem64].Length != 0) {\r
- BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeMem64].Alignment) + 1; // Get the number of '1' in Alignment\r
- AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem64].Length;\r
-\r
- // Top of the 64bit PCI Memory space\r
- BaseAddress = FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size);\r
-\r
- Status = gDS->AllocateMemorySpace (\r
- EfiGcdAllocateMaxAddressSearchTopDown,\r
- EfiGcdMemoryTypeMemoryMappedIo,\r
- BitsOfAlignment,\r
- AddrLen,\r
- &BaseAddress,\r
- HostBridgeInstance->ImageHandle,\r
- NULL\r
- );\r
-\r
- // Ensure the allocation is in the 64bit PCI memory space\r
- if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 (PcdPciMmio64Base))) {\r
- RootBridgeInstance->ResAlloc[ResTypeMem64].Base = (UINTN)BaseAddress;\r
- }\r
- }\r
- if (RootBridgeInstance->ResAlloc[ResTypePMem64].Length != 0) {\r
- BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypePMem64].Alignment) + 1; //Get the number of '1' in Alignment\r
- AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem64].Length;\r
-\r
- // Top of the 64bit PCI Memory space\r
- BaseAddress = FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size);\r
-\r
- Status = gDS->AllocateMemorySpace (\r
- EfiGcdAllocateMaxAddressSearchTopDown,\r
- EfiGcdMemoryTypeMemoryMappedIo,\r
- BitsOfAlignment,\r
- AddrLen,\r
- &BaseAddress,\r
- HostBridgeInstance->ImageHandle,\r
- NULL\r
- );\r
-\r
- // Ensure the allocation is in the 64bit PCI memory space\r
- if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 (PcdPciMmio64Base))) {\r
- RootBridgeInstance->ResAlloc[ResTypePMem64].Base = (UINTN)BaseAddress;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case EfiPciHostBridgeSetResources:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeSetResources)");\r
- // Programs the host bridge hardware to decode previously allocated resources (proposed resources)\r
- // for all the PCI root bridges. The PCI bus driver will now program the resources\r
- break;\r
-\r
- case EfiPciHostBridgeFreeResources:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeFreeResources)");\r
- // Deallocates resources that were previously allocated for all the PCI root bridges and resets the\r
- // I/O and memory apertures to their initial state.*/\r
- break;\r
-\r
- case EfiPciHostBridgeEndResourceAllocation:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndResourceAllocation)");\r
- break;\r
-\r
- case EfiPciHostBridgeEndEnumeration:\r
- PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndEnumeration)");\r
- break;\r
-\r
- default:\r
- DEBUG ((EFI_D_INFO, "PciHbRaNotifyPhase(Phase:%d)\n", Phase));\r
- ASSERT (0);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- * PciHbRaGetNextRootBridge() returns the next root bridge attached to the 'This' PCI Host Bridge.\r
- * As we have only got one PCI Root Bridge in this PCI interface, we return either this root bridge\r
- * if it the first time we call this function (*RootBridgeHandle == NULL) or we return EFI_NOT_FOUND\r
- **/\r
-EFI_STATUS\r
-PciHbRaGetNextRootBridge (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN OUT EFI_HANDLE *RootBridgeHandle\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
-\r
- PCI_TRACE ("PciHbRaGetNextRootBridge()");\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
- ASSERT (HostBridgeInstance->RootBridge != NULL);\r
-\r
- //Check RootBridge Signature\r
- ASSERT (HostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);\r
-\r
- if (*RootBridgeHandle == NULL) {\r
- *RootBridgeHandle = HostBridgeInstance->RootBridge->Handle;\r
- return EFI_SUCCESS;\r
- } else if (*RootBridgeHandle == HostBridgeInstance->RootBridge->Handle) {\r
- return EFI_NOT_FOUND;\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-}\r
-\r
-/** PciHbRaGetAllocAttributes() returns the resource allocation attributes supported by this PCI Root Bridge.\r
- * A PCI Root bridge could support these types :\r
- * - EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM : does not support separate windows for nonprefetchable and prefetchable memory.\r
- * - EFI_PCI_HOST_BRIDGE_MEM64_DECODE : supports 64-bit memory windows\r
- **/\r
-EFI_STATUS\r
-PciHbRaGetAllocAttributes (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- OUT UINT64 *Attributes\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
-\r
- PCI_TRACE ("PciHbRaGetAllocAttributes()");\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
-\r
- // Check if the RootBridgeHandle is the one managed by this PCI Host Bridge\r
- ASSERT (HostBridgeInstance->RootBridge != NULL);\r
- if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Attributes = HostBridgeInstance->RootBridge->MemAllocAttributes;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHbRaStartBusEnumeration (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- OUT VOID **Configuration\r
- )\r
-{\r
- VOID *Buffer;\r
- UINT8 *Ptr;\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
-\r
- // Fill an ACPI descriptor table with the Bus Number Range. This information will be used by the PCI Bus driver\r
- // to set bus numbers to PCI-to-PCI bridge.\r
- PCI_TRACE ("PciHbRaStartBusEnumeration()");\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
-\r
- Buffer = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = (UINT8 *)Buffer;\r
-\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; // QWORD Address space Descriptor\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Len = 0x2B; // Length of this descriptor in bytes not including the first two fields\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; // Resource Type Bus Number Range\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->GenFlag = 0;\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->SpecificFlag = 0;\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrSpaceGranularity = 0;\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin = HostBridgeInstance->RootBridge->BusStart; // Bus Start\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMax = 0; // Bus Max\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrTranslationOffset = 0;\r
- ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen = FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1;\r
-\r
- Ptr = Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;\r
-\r
- *Configuration = Buffer;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHbRaSetBusNumbers (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- IN VOID *Configuration\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
- UINT8 *Ptr;\r
- UINTN BusStart;\r
- UINTN BusEnd;\r
- UINTN BusLen;\r
-\r
- PCI_TRACE ("PciHbRaSetBusNumbers()");\r
-\r
- Ptr = Configuration;\r
- if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Check if the passed ACPI descriptor table define a Bus Number Range\r
- if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Check if the Configuration only passed one ACPI Descriptor (+ End Descriptor)\r
- if (*((UINT8*)(Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR))) != ACPI_END_TAG_DESCRIPTOR) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
- ASSERT (HostBridgeInstance->RootBridge != NULL);\r
- if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;\r
- BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;\r
- BusEnd = BusStart + BusLen - 1;\r
-\r
- ASSERT (BusStart <= BusEnd); // We should at least have PCI_BUS_ROOT and PCI_SWITCH_BUS\r
- ASSERT ((BusStart >= HostBridgeInstance->RootBridge->BusStart) && (BusLen <= HostBridgeInstance->RootBridge->BusLength));\r
-\r
- HostBridgeInstance->RootBridge->BusStart = BusStart;\r
- HostBridgeInstance->RootBridge->BusLength = BusLen;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- * This function is used to submit all the I/O and memory resources that are required by the specified\r
- * PCI root bridge.\r
- **/\r
-EFI_STATUS\r
-PciHbRaSubmitResources (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- IN VOID *Configuration\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
- PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
- UINT8 *Ptr;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
- PCI_RESOURCE_TYPE ResType;\r
-\r
- PCI_TRACE ("PciHbRaSubmitResources()");\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
-\r
- if (Configuration == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Check if the ACPI Descriptor tables is conformed\r
- Ptr = (UINT8 *)Configuration;\r
- while (*Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // QWORD Address Space descriptor\r
- Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;\r
- }\r
- if (*Ptr != ACPI_END_TAG_DESCRIPTOR) { // End tag\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Check the RootBridgeHandle\r
- RootBridgeInstance = HostBridgeInstance->RootBridge;\r
- ASSERT (RootBridgeInstance != NULL);\r
- if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Ptr = (UINT8 *)Configuration;\r
- while ( *Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // While the entry is an ACPI Descriptor Table\r
- Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;\r
-\r
- // Check if the description is valid\r
- if (Desc->AddrLen > 0xffffffff) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Desc->AddrRangeMax >= 0xffffffff) || (Desc->AddrRangeMax != (GetPowerOfTwo64 (Desc->AddrRangeMax + 1) - 1))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- switch (Desc->ResType) {\r
- case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
- // Check invalid Address Space Granularity\r
- if ((Desc->AddrSpaceGranularity != 32) && (Desc->AddrSpaceGranularity != 64)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // check the memory resource request is supported by PCI root bridge\r
- if (RootBridgeInstance->MemAllocAttributes == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM && Desc->SpecificFlag == 0x06) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Desc->AddrSpaceGranularity == 32) {\r
- if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {\r
- ResType = ResTypePMem32;\r
- } else {\r
- ResType = ResTypeMem32;\r
- }\r
- } else {\r
- if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {\r
- ResType = ResTypePMem64;\r
- } else {\r
- ResType = ResTypeMem64;\r
- }\r
- }\r
- RootBridgeInstance->ResAlloc[ResType].Length = Desc->AddrLen;\r
- RootBridgeInstance->ResAlloc[ResType].Alignment = Desc->AddrRangeMax;\r
- RootBridgeInstance->ResAlloc[ResType].Base = Desc->AddrRangeMin;\r
- break;\r
- case ACPI_ADDRESS_SPACE_TYPE_IO:\r
- RootBridgeInstance->ResAlloc[ResTypeIo].Length = Desc->AddrLen;\r
- RootBridgeInstance->ResAlloc[ResTypeIo].Alignment = Desc->AddrRangeMax;\r
- RootBridgeInstance->ResAlloc[ResTypeIo].Base = 0;\r
- break;\r
- default:\r
- ASSERT (0); // Could be the case Desc->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS\r
- break;\r
- }\r
- Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/** Returns the proposed resource settings for the specified PCI root bridge. The resources have been submitted by\r
- * PciHbRaSubmitResources() before\r
- **/\r
-EFI_STATUS\r
-PciHbRaGetProposedResources (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- OUT VOID **Configuration\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
- PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
- UINT32 i;\r
- UINT32 ResAllocCount;\r
- VOID *Buffer;\r
- UINT8 *Ptr;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
-\r
- PCI_TRACE ("PciHbRaGetProposedResources()");\r
-\r
- HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
-\r
- // Check the RootBridgeHandle\r
- RootBridgeInstance = HostBridgeInstance->RootBridge;\r
- ASSERT (RootBridgeInstance != NULL);\r
- if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Count the number of Resource Allocated for this Root Bridge\r
- ResAllocCount = 0;\r
- for (i = 0; i < ResTypeMax; i++) {\r
- if (RootBridgeInstance->ResAlloc[i].Length != 0) ResAllocCount++;\r
- }\r
-\r
- if (ResAllocCount == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Buffer = AllocateZeroPool (ResAllocCount * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = Buffer;\r
- for (i = 0; i < ResTypeMax; i++) {\r
- if (RootBridgeInstance->ResAlloc[i].Length != 0) { // Base != 0 if the resource has been allocated\r
- Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;\r
-\r
- Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Desc->Len = 0x2B;\r
- Desc->GenFlag = 0;\r
- Desc->AddrRangeMax = 0;\r
-\r
- switch (i) {\r
- case ResTypeIo:\r
- Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
- Desc->SpecificFlag = 0;\r
- Desc->AddrSpaceGranularity = 0;\r
- break;\r
- case ResTypeMem32:\r
- Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Desc->SpecificFlag = 0;\r
- Desc->AddrSpaceGranularity = 32;\r
- break;\r
- case ResTypePMem32:\r
- Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Desc->SpecificFlag = ACPI_SPECFLAG_PREFETCHABLE;\r
- Desc->AddrSpaceGranularity = 32;\r
- break;\r
- case ResTypeMem64:\r
- Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Desc->SpecificFlag = 0;\r
- Desc->AddrSpaceGranularity = 64;\r
- break;\r
- case ResTypePMem64:\r
- Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Desc->SpecificFlag = ACPI_SPECFLAG_PREFETCHABLE;\r
- Desc->AddrSpaceGranularity = 64;\r
- break;\r
- }\r
- Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;\r
- Desc->AddrTranslationOffset = (RootBridgeInstance->ResAlloc[i].Base != 0) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;\r
- Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;\r
- Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
- }\r
-\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;\r
-\r
- *Configuration = Buffer;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHbRaPreprocessController (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
- IN EFI_HANDLE RootBridgeHandle,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,\r
- IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-{\r
- PCI_HOST_BRIDGE_INSTANCE* HostBridge;\r
- PCI_ROOT_BRIDGE_INSTANCE* RootBridge;\r
- UINT32 CapabilityPtr;\r
- UINT32 CapabilityEntry;\r
- UINT16 CapabilityID;\r
- UINT32 DeviceCapability;\r
-\r
- PCI_TRACE ("PciHbRaPreprocessController()");\r
-\r
- if (FeaturePcdGet (PcdPciMaxPayloadFixup)) {\r
- // Do Max payload fixup for every devices\r
- if (Phase == EfiPciBeforeResourceCollection) {\r
- // Get RootBridge Instance from Host Bridge Instance\r
- HostBridge = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
- RootBridge = HostBridge->RootBridge;\r
-\r
- // Get the first PCI Capability\r
- CapabilityPtr = PCI_CAPBILITY_POINTER_OFFSET;\r
- RootBridge->Io.Pci.Read (\r
- &RootBridge->Io,\r
- EfiPciWidthUint8,\r
- EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr),\r
- 1,\r
- &CapabilityPtr\r
- );\r
- CapabilityPtr &= 0x1FF;\r
-\r
- // Get Pci Express Capability\r
- while (CapabilityPtr != 0) {\r
- RootBridge->Io.Pci.Read (\r
- &RootBridge->Io,\r
- EfiPciWidthUint16,\r
- EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr),\r
- 1,\r
- &CapabilityEntry\r
- );\r
-\r
- CapabilityID = (UINT8)CapabilityEntry;\r
-\r
- // Is PCIe capability ?\r
- if (CapabilityID == EFI_PCI_CAPABILITY_ID_PCIEXP) {\r
- // Get PCIe Device Capabilities\r
- RootBridge->Io.Pci.Read (\r
- &RootBridge->Io,\r
- EfiPciWidthUint32,\r
- EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr + 0x8),\r
- 1,\r
- &DeviceCapability\r
- );\r
-\r
- // Force the Max Payload to 128 Bytes (128 Bytes Max Payload Size = 0)\r
- DeviceCapability &= ~ ((UINT32)(0x7 << 5 ));\r
- // Max Read Request Size to 128 Bytes (128 Bytes Max Read Request Size = 0)\r
- DeviceCapability &= ~ ((UINT32)(0x7 << 12));\r
- // Enable all error reporting\r
- DeviceCapability |= 0xF;\r
-\r
- RootBridge->Io.Pci.Write (\r
- &RootBridge->Io,\r
- EfiPciWidthUint32,\r
- EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr + 0x8),\r
- 1,\r
- &DeviceCapability\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
- CapabilityPtr = (CapabilityEntry >> 8) & 0xFF;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r