PciHostBridgeLib.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /** @file
  2. *
  3. * PCI Host Bridge Library instance for StarFive JH7110 SOC
  4. *
  5. * Copyright (c) 2023, Minda Chen <minda.chen@starfivetech.com>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause-Patent
  8. *
  9. **/
  10. #include <IndustryStandard/JH7110.h>
  11. #include <IndustryStandard/Pci22.h>
  12. #include <Library/DebugLib.h>
  13. #include <Library/DevicePathLib.h>
  14. #include <Library/MemoryAllocationLib.h>
  15. #include <Library/PcdLib.h>
  16. #include <Library/PciHostBridgeLib.h>
  17. #include <PiDxe.h>
  18. #include <Protocol/PciRootBridgeIo.h>
  19. #include <Protocol/PciHostBridgeResourceAllocation.h>
  20. #pragma pack(1)
  21. typedef PACKED struct {
  22. ACPI_HID_DEVICE_PATH AcpiDevicePath;
  23. EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
  24. } EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
  25. #pragma pack ()
  26. STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
  27. {
  28. {
  29. {
  30. ACPI_DEVICE_PATH,
  31. ACPI_DP,
  32. {
  33. (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
  34. (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
  35. }
  36. },
  37. EISA_PNP_ID (0x0A08), // PCI Express
  38. 0
  39. },
  40. {
  41. END_DEVICE_PATH_TYPE,
  42. END_ENTIRE_DEVICE_PATH_SUBTYPE,
  43. {
  44. END_DEVICE_PATH_LENGTH,
  45. 0
  46. }
  47. }
  48. },
  49. };
  50. GLOBAL_REMOVE_IF_UNREFERENCED
  51. CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
  52. L"Mem", L"I/O", L"Bus"
  53. };
  54. // These should come from the PCD...
  55. #define JH7110_PCI_SEG0_BUSNUM_MIN 0x00
  56. #define JH7110_PCI_SEG0_BUSNUM_MAX 0xFF
  57. #define JH7110_PCI_SEG0_PORTIO_MIN 0x01
  58. #define JH7110_PCI_SEG0_PORTIO_MAX 0x00 // MIN>MAX disables PIO
  59. #define JH7110_PCI_SEG0_PORTIO_OFFSET 0x00
  60. // The bridge thinks its MMIO is here (which means it can't access this area in phy ram)
  61. #define JH7110_PCI_SEG0_MMIO32_MIN (0x38000000)
  62. #define JH7110_PCI_SEG0_MMIO32_MAX (JH7110_PCI_SEG0_MMIO32_MIN + 0x8000000)
  63. // The CPU views it via a window here..
  64. //#define BCM2711_PCI_SEG0_MMIO32_XLATE (PCIE_CPU_MMIO_WINDOW - PCIE_TOP_OF_MEM_WIN)
  65. // We might be able to size another region?
  66. #define JH7110_PCI_SEG0_MMIO64_MIN (0x980000000)
  67. #define JH7110_PCI_SEG0_MMIO64_MAX (0x9c0000000)
  68. //
  69. // See description in MdeModulePkg/Include/Library/PciHostBridgeLib.h
  70. //
  71. PCI_ROOT_BRIDGE mPciRootBridges[] = {
  72. {
  73. 0, // Segment
  74. 0, // Supports
  75. 0, // Attributes
  76. FALSE, // DmaAbove4G
  77. FALSE, // NoExtendedConfigSpace (true=256 byte config, false=4k)
  78. FALSE, // ResourceAssigned
  79. EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
  80. EFI_PCI_HOST_BRIDGE_MEM64_DECODE, // AllocationAttributes
  81. { JH7110_PCI_SEG0_BUSNUM_MIN,
  82. JH7110_PCI_SEG0_BUSNUM_MAX }, // Bus
  83. { JH7110_PCI_SEG0_PORTIO_MIN,
  84. JH7110_PCI_SEG0_PORTIO_MAX,
  85. MAX_UINT64 - JH7110_PCI_SEG0_PORTIO_OFFSET + 1 }, // Io
  86. { JH7110_PCI_SEG0_MMIO32_MIN,
  87. JH7110_PCI_SEG0_MMIO32_MAX, 0},// Mem
  88. {JH7110_PCI_SEG0_MMIO64_MIN, JH7110_PCI_SEG0_MMIO64_MAX, 0}, // MemAbove4G
  89. { MAX_UINT64, 0x0 }, // Pefetchable Mem
  90. { MAX_UINT64, 0x0 }, // Pefetchable MemAbove4G
  91. (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0]
  92. }
  93. };
  94. /**
  95. Return all the root bridge instances in an array.
  96. @param Count Return the count of root bridge instances.
  97. @return All the root bridge instances in an array.
  98. The array should be passed into PciHostBridgeFreeRootBridges()
  99. when it's not used.
  100. **/
  101. PCI_ROOT_BRIDGE *
  102. EFIAPI
  103. PciHostBridgeGetRootBridges (
  104. OUT UINTN *Count
  105. )
  106. {
  107. *Count = ARRAY_SIZE (mPciRootBridges);
  108. return mPciRootBridges;
  109. }
  110. /**
  111. Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
  112. @param Bridges The root bridge instances array.
  113. @param Count The count of the array.
  114. **/
  115. VOID
  116. EFIAPI
  117. PciHostBridgeFreeRootBridges (
  118. PCI_ROOT_BRIDGE *Bridges,
  119. UINTN Count
  120. )
  121. {
  122. }
  123. /**
  124. Inform the platform that the resource conflict happens.
  125. @param HostBridgeHandle Handle of the Host Bridge.
  126. @param Configuration Pointer to PCI I/O and PCI memory resource
  127. descriptors. The Configuration contains the resources
  128. for all the root bridges. The resource for each root
  129. bridge is terminated with END descriptor and an
  130. additional END is appended indicating the end of the
  131. entire resources. The resource descriptor field
  132. values follow the description in
  133. EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
  134. .SubmitResources().
  135. **/
  136. VOID
  137. EFIAPI
  138. PciHostBridgeResourceConflict (
  139. EFI_HANDLE HostBridgeHandle,
  140. VOID *Configuration
  141. )
  142. {
  143. EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
  144. UINTN RootBridgeIndex;
  145. DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
  146. RootBridgeIndex = 0;
  147. Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
  148. while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
  149. DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
  150. for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
  151. ASSERT (Descriptor->ResType <
  152. ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
  153. DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
  154. mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
  155. Descriptor->AddrLen, Descriptor->AddrRangeMax
  156. ));
  157. if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
  158. DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
  159. Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
  160. ((Descriptor->SpecificFlag &
  161. EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
  162. ) != 0) ? L" (Prefetchable)" : L""
  163. ));
  164. }
  165. }
  166. //
  167. // Skip the END descriptor for root bridge
  168. //
  169. ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
  170. Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
  171. (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
  172. );
  173. }
  174. }