PcieInitPei.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /** @file
  2. Copyright (c) 2020 - 2023, Ampere Computing LLC. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <Guid/RootComplexConfigHii.h>
  7. #include <Guid/RootComplexInfoHob.h>
  8. #include <Library/AmpereCpuLib.h>
  9. #include <Library/BaseMemoryLib.h>
  10. #include <Library/BoardPcieLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/HobLib.h>
  13. #include <Library/Ac01PcieLib.h>
  14. #include <Library/PeiServicesLib.h>
  15. #include <Platform/Ac01.h>
  16. #include <Ppi/ReadOnlyVariable2.h>
  17. #include "RootComplexNVParam.h"
  18. #define TCU_OFFSET 0
  19. #define SNPSRAM_OFFSET 0x9000
  20. #define HB_CSR_OFFSET 0x01000000
  21. #define PCIE0_CSR_OFFSET 0x01010000
  22. #define SERDES_CSR_OFFSET 0x01200000
  23. #define MMCONFIG_OFFSET 0x10000000
  24. #define PCIE_CSR_SIZE 0x10000
  25. STATIC AC01_ROOT_COMPLEX mRootComplexList[AC01_PCIE_MAX_ROOT_COMPLEX];
  26. STATIC UINT64 mCsrBase[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_CSR_BASE_LIST };
  27. STATIC UINT64 mMmio32Base[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE_LIST };
  28. STATIC UINT64 mMmio32Base1P[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE_1P_LIST };
  29. STATIC UINT64 mMmio32Size[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_SIZE_LIST };
  30. STATIC UINT64 mMmio32Size1P[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_SIZE_1P_LIST };
  31. STATIC UINT64 mMmioBase[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO_BASE_LIST };
  32. STATIC UINT64 mMmioSize[AC01_PCIE_MAX_ROOT_COMPLEX] = { AC01_PCIE_MMIO_SIZE_LIST };
  33. VOID
  34. BuildRootComplexData (
  35. VOID
  36. )
  37. {
  38. AC01_ROOT_COMPLEX *RootComplex;
  39. BOOLEAN ConfigFound;
  40. EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
  41. EFI_STATUS Status;
  42. ROOT_COMPLEX_CONFIG_VARSTORE_DATA RootComplexConfig;
  43. UINT8 RCIndex;
  44. UINT8 PcieIndex;
  45. UINTN DataSize;
  46. ConfigFound = FALSE;
  47. //
  48. // Get the Root Complex config from NVRAM
  49. //
  50. Status = PeiServicesLocatePpi (
  51. &gEfiPeiReadOnlyVariable2PpiGuid,
  52. 0,
  53. NULL,
  54. (VOID **)&VariablePpi
  55. );
  56. if (!EFI_ERROR (Status)) {
  57. DataSize = sizeof (RootComplexConfig);
  58. Status = VariablePpi->GetVariable (
  59. VariablePpi,
  60. ROOT_COMPLEX_CONFIG_VARSTORE_NAME,
  61. &gRootComplexConfigFormSetGuid,
  62. NULL,
  63. &DataSize,
  64. &RootComplexConfig
  65. );
  66. if (!EFI_ERROR (Status)) {
  67. ConfigFound = TRUE;
  68. }
  69. }
  70. ZeroMem (&mRootComplexList, sizeof (AC01_ROOT_COMPLEX) * AC01_PCIE_MAX_ROOT_COMPLEX);
  71. //
  72. // Adjust Root Complex MMIO32 base address in 1P or 2P configuration
  73. //
  74. if (!IsSlaveSocketAvailable ()) {
  75. CopyMem ((VOID *)&mMmio32Base, (VOID *)&mMmio32Base1P, sizeof (mMmio32Base1P));
  76. CopyMem ((VOID *)&mMmio32Size, (VOID *)&mMmio32Size1P, sizeof (mMmio32Size1P));
  77. }
  78. for (RCIndex = 0; RCIndex < AC01_PCIE_MAX_ROOT_COMPLEX; RCIndex++) {
  79. RootComplex = &mRootComplexList[RCIndex];
  80. RootComplex->Active = ConfigFound ? RootComplexConfig.RCStatus[RCIndex] : TRUE;
  81. RootComplex->DevMapLow = ConfigFound ? RootComplexConfig.RCBifurcationLow[RCIndex] : 0;
  82. RootComplex->DevMapHigh = ConfigFound ? RootComplexConfig.RCBifurcationHigh[RCIndex] : 0;
  83. RootComplex->Socket = RCIndex / AC01_PCIE_MAX_RCS_PER_SOCKET;
  84. RootComplex->ID = RCIndex % AC01_PCIE_MAX_RCS_PER_SOCKET;
  85. RootComplex->CsrBase = mCsrBase[RCIndex];
  86. RootComplex->TcuBase = RootComplex->CsrBase + TCU_OFFSET;
  87. RootComplex->HostBridgeBase = RootComplex->CsrBase + HB_CSR_OFFSET;
  88. RootComplex->SerdesBase = RootComplex->CsrBase + SERDES_CSR_OFFSET;
  89. RootComplex->MmcfgBase = RootComplex->CsrBase + MMCONFIG_OFFSET;
  90. RootComplex->MmioBase = mMmioBase[RCIndex];
  91. RootComplex->MmioSize = mMmioSize[RCIndex];
  92. RootComplex->Mmio32Base = mMmio32Base[RCIndex];
  93. RootComplex->Mmio32Size = mMmio32Size[RCIndex];
  94. RootComplex->Type = (RootComplex->ID < MaxRootComplexA) ? RootComplexTypeA : RootComplexTypeB;
  95. RootComplex->MaxPcieController = (RootComplex->Type == RootComplexTypeB)
  96. ? MaxPcieControllerOfRootComplexB : MaxPcieControllerOfRootComplexA;
  97. RootComplex->Logical = BoardPcieGetSegmentNumber (RootComplex);
  98. for (PcieIndex = 0; PcieIndex < RootComplex->MaxPcieController; PcieIndex++) {
  99. RootComplex->Pcie[PcieIndex].ID = PcieIndex;
  100. RootComplex->Pcie[PcieIndex].CsrBase = RootComplex->CsrBase + PCIE0_CSR_OFFSET + PcieIndex * PCIE_CSR_SIZE;
  101. RootComplex->Pcie[PcieIndex].SnpsRamBase = RootComplex->Pcie[PcieIndex].CsrBase + SNPSRAM_OFFSET;
  102. RootComplex->Pcie[PcieIndex].DevNum = PcieIndex + 1;
  103. }
  104. ParseRootComplexNVParamData (RootComplex);
  105. DEBUG ((
  106. DEBUG_INFO,
  107. " + S%d - RootComplex%a%d, MMCfgBase:0x%lx, MmioBase:0x%lx, Mmio32Base:0x%lx, Enabled:%a\n",
  108. RootComplex->Socket,
  109. (RootComplex->Type == RootComplexTypeA) ? "A" : "B",
  110. RootComplex->ID,
  111. RootComplex->MmcfgBase,
  112. RootComplex->MmioBase,
  113. RootComplex->Mmio32Base,
  114. (RootComplex->Active) ? "Y" : "N"
  115. ));
  116. DEBUG ((DEBUG_INFO, " + DevMapLo/Hi: 0x%x/0x%x\n", RootComplex->DevMapLow, RootComplex->DevMapHigh));
  117. for (PcieIndex = 0; PcieIndex < RootComplex->MaxPcieController; PcieIndex++) {
  118. DEBUG ((
  119. DEBUG_INFO,
  120. " + PCIE%d:0x%lx - Enabled:%a - DevNum:0x%x\n",
  121. PcieIndex,
  122. RootComplex->Pcie[PcieIndex].CsrBase,
  123. (RootComplex->Pcie[PcieIndex].Active) ? "Y" : "N",
  124. RootComplex->Pcie[PcieIndex].DevNum
  125. ));
  126. }
  127. }
  128. }
  129. EFI_STATUS
  130. EFIAPI
  131. PcieInitEntry (
  132. IN EFI_PEI_FILE_HANDLE FileHandle,
  133. IN CONST EFI_PEI_SERVICES **PeiServices
  134. )
  135. {
  136. AC01_ROOT_COMPLEX *RootComplex;
  137. EFI_STATUS Status;
  138. UINT8 Index;
  139. BuildRootComplexData ();
  140. //
  141. // Initialize Root Complex and underneath controllers
  142. //
  143. for (Index = 0; Index < AC01_PCIE_MAX_ROOT_COMPLEX; Index++) {
  144. RootComplex = &mRootComplexList[Index];
  145. if (!RootComplex->Active) {
  146. continue;
  147. }
  148. Status = Ac01PcieCoreSetupRC (RootComplex, FALSE, 0);
  149. if (EFI_ERROR (Status)) {
  150. DEBUG ((DEBUG_ERROR, "RootComplex[%d]: Init Failed\n", Index));
  151. RootComplex->Active = FALSE;
  152. continue;
  153. }
  154. }
  155. Ac01PcieCorePostSetupRC (mRootComplexList);
  156. //
  157. // Build Root Complex info Hob
  158. //
  159. BuildGuidDataHob (
  160. &gRootComplexInfoHobGuid,
  161. (VOID *)&mRootComplexList,
  162. sizeof (mRootComplexList)
  163. );
  164. return EFI_SUCCESS;
  165. }