PciHostBridgeLib which is need by PciHostBridgeDxe, provide root bridges and deal with resource conflict.
Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ming Huang ming.huang@linaro.org --- Platform/Hisilicon/D06/D06.dsc | 2 +- Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.inf | 36 ++ Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.c | 635 ++++++++++++++++++++ 3 files changed, 672 insertions(+), 1 deletion(-)
diff --git a/Platform/Hisilicon/D06/D06.dsc b/Platform/Hisilicon/D06/D06.dsc index 3de09ea870..c6de9f04ad 100644 --- a/Platform/Hisilicon/D06/D06.dsc +++ b/Platform/Hisilicon/D06/D06.dsc @@ -418,7 +418,7 @@ <LibraryClasses> PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf - PciHostBridgeLib|MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf + PciHostBridgeLib|Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.inf }
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf diff --git a/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000000..8a998681a3 --- /dev/null +++ b/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -0,0 +1,36 @@ +## @file +# +# Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR> +# Copyright (c) 2018, Linaro Limited. 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. +# +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = PciHostBridgeLib + FILE_GUID = 61b7276a-fc67-11e5-82fd-47ea9896dd5d + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciHostBridgeLib|DXE_DRIVER + +[Sources] + PciHostBridgeLib.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DevicePathLib + MemoryAllocationLib + UefiBootServicesTableLib diff --git a/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.c new file mode 100644 index 0000000000..d1a436d9bc --- /dev/null +++ b/Platform/Hisilicon/D06/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -0,0 +1,635 @@ +/** @file + + Copyright (c) 2018, Hisilicon Limited. All rights reserved.<BR> + Copyright (c) 2018, Linaro Limited. 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 <PiDxe.h> +#include <Library/DebugLib.h> +#include <Library/DevicePathLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PciHostBridgeLib.h> +#include <Protocol/PciHostBridgeResourceAllocation.h> +#include <Protocol/PciRootBridgeIo.h> + +#define ENUM_HB_NUM 8 + +#define EFI_PCI_SUPPORT (EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \ + EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \ + EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | \ + EFI_PCI_ATTRIBUTE_ISA_IO_16 | \ + EFI_PCI_ATTRIBUTE_VGA_MEMORY | \ + EFI_PCI_ATTRIBUTE_VGA_IO_16 | \ + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16) + +#define EFI_PCI_ATTRIBUTE EFI_PCI_SUPPORT + +#pragma pack(1) +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH; +#pragma pack () + +STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath [ENUM_HB_NUM] = { +//Host Bridge 0 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A03), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 2 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A04), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 4 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A05), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 5 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A06), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 6 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A07), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 8 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A08), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 10 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A09), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + }, + +//Host Bridge 11 + { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8)sizeof (ACPI_HID_DEVICE_PATH), + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8) + } + }, + EISA_PNP_ID(0x0A0A), // PCI + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } + } +}; + +STATIC PCI_ROOT_BRIDGE gRootBridge [ENUM_HB_NUM] = { +//Host Bridge 0 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 00, + 0x3F + }, + { // Io (32K) + 0, + 0x7FFF + }, + { // Mem (256M - 64K - 1) + 0xE0000000, + 0xEFFEFFFF + }, + { // MemAbove4G (8T + 256G) + 0x80000000000, + 0x83FFFFFFFFF + }, + { // PMem + 0xE0000000, + 0xEFFEFFFF + }, + { // PMemAbove4G + 0x80000000000, + 0x83FFFFFFFFF + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0] + }, + + //Host Bridge 2 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0x7A, + 0x7A + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + MAX_UINT32, + 0 + }, + { // MemAbove4G + 0x20c000000, + 0x20c1fffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[1] + }, + + //Host Bridge 4 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0x7C, + 0x7D + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + MAX_UINT32, + 0 + }, + { // MemAbove4G + 0x120000000, + 0x13fffffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[2] + }, + + //Host Bridge 5 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0x74, + 0x76 + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + 0xA2000000, + 0xA2ffffff + }, + { // MemAbove4G + 0x144000000, + 0x147ffffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[3] + }, + //Host Bridge 6 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0x80, + 0x9F + }, + { // Io (32K) + 0x0, + 0x7FFF + }, + { // Mem (256M - 64K -1) + 0xF0000000, + 0xFFFEFFFF + }, + { // MemAbove4G (8T + 256G) + 0x480000000000, + 0x483FFFFFFFFF + }, + { // PMem + 0xF0000000, + 0xFFFEFFFF + }, + { // PMemAbove4G + 0x480000000000, + 0x483FFFFFFFFF + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[4] + }, + + //Host Bridge 8 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0xBA, + 0xBA + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + MAX_UINT32, + 0 + }, + { // MemAbove4G + 0x40020c000000, + 0x40020c1fffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[5] + }, + + //Host Bridge 10 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0xBC, + 0xBD + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + MAX_UINT32, + 0 + }, + { // MemAbove4G + 0x400120000000, + 0x40013fffffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[6] + }, + + //Host Bridge 11 + { + 0, // Segment + EFI_PCI_SUPPORT, // Supports + EFI_PCI_ATTRIBUTE, // Attributes + TRUE, // DmaAbove4G + FALSE, // NoExtendedConfigSpace + FALSE, // ResourceAssigned + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, + { // Bus + 0xB4, + 0xB6 + }, + { // Io + MAX_UINT32, + 0 + }, + { // Mem + 0xA3000000, + 0xA3ffffff + }, + { // MemAbove4G + 0x400144000000, + 0x400147ffffff + }, + { // PMem + MAX_UINT32, + 0 + }, + { // PMemAbove4G + MAX_UINT64, + 0 + }, + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[7] + } + +}; + +/** + Return all the root bridge instances in an array. + + @param Count Return the count of root bridge instances. + + @return All the root bridge instances in an array. + The array should be passed into PciHostBridgeFreeRootBridges() + when it's not used. +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeGetRootBridges ( + UINTN *Count + ) +{ + *Count = ENUM_HB_NUM; + + return gRootBridge; +} + +/** + Free the root bridge instances array returned from PciHostBridgeGetRootBridges(). + + @param Bridges The root bridge instances array. + @param Count The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ) +{ + if (Bridges == NULL && Count == 0) { + return; + } + + do { + --Count; + FreePool (Bridges[Count].DevicePath); + } while (Count > 0); + + FreePool (Bridges); +} + +STATIC CONST CHAR16 mPciHostBridgeLibAcpiAddressSpaceTypeStr[][4] = { + L"Mem", L"I/O", L"Bus" +}; + +/** + Inform the platform that the resource conflict happens. + + @param HostBridgeHandle Handle of the Host Bridge. + @param Configuration Pointer to PCI I/O and PCI memory resource + descriptors. The Configuration contains the resources + for all the root bridges. The resource for each root + bridge is terminated with END descriptor and an + additional END is appended indicating the end of the + entire resources. The resource descriptor field + values follow the description in + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + .SubmitResources(). +**/ +VOID +EFIAPI +PciHostBridgeResourceConflict ( + EFI_HANDLE HostBridgeHandle, + VOID *Configuration + ) +{ + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + UINTN RootBridgeIndex; + + DEBUG ((DEBUG_ERROR, "\n PciHostBridge: Resource conflict happens!\n")); + RootBridgeIndex = 0; + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration; + while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) { + DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); + for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { + ASSERT (Descriptor->ResType < + ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr) + ); + DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n", + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType], + Descriptor->AddrLen, Descriptor->AddrRangeMax + )); + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n", + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, + ((Descriptor->SpecificFlag & + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE + ) != 0) ? L" (Prefetchable)" : L"" + )); + } + } + // + // Skip the END descriptor for root bridge + // + ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR); + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1 + ); + } +}