AcpiMadt.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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 "AcpiPlatform.h"
  6. EFI_ACPI_6_3_GIC_ITS_STRUCTURE GicItsTemplate = {
  7. EFI_ACPI_6_3_GIC_ITS,
  8. sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE),
  9. EFI_ACPI_RESERVED_WORD,
  10. 0, /* GicItsId */
  11. 0, /* PhysicalBaseAddress */
  12. 0, /* Reserved2 */
  13. };
  14. EFI_ACPI_6_3_GICR_STRUCTURE GicRTemplate = {
  15. EFI_ACPI_6_3_GICR,
  16. sizeof (EFI_ACPI_6_3_GICR_STRUCTURE),
  17. EFI_ACPI_RESERVED_WORD,
  18. AC01_GICR_MASTER_BASE_ADDRESS, /* DiscoveryRangeBaseAddress */
  19. 0x1000000, /* DiscoveryRangeLength */
  20. };
  21. EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDTemplate = {
  22. EFI_ACPI_6_3_GICD,
  23. sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE),
  24. EFI_ACPI_RESERVED_WORD,
  25. 0, /* GicDistHwId */
  26. AC01_GICD_MASTER_BASE_ADDRESS, /* GicDistBase */
  27. 0, /* GicDistVector */
  28. 0x3, /* GicVersion */
  29. {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}
  30. };
  31. EFI_ACPI_6_3_GIC_STRUCTURE GiccTemplate = {
  32. EFI_ACPI_6_3_GIC,
  33. sizeof (EFI_ACPI_6_3_GIC_STRUCTURE),
  34. EFI_ACPI_RESERVED_WORD,
  35. 0, /* GicId */
  36. 0, /* AcpiCpuUid */
  37. 0, /* Flags */
  38. 0,
  39. 23, /* PmuIrq */
  40. 0,
  41. 0,
  42. 0,
  43. 0,
  44. 25, /* GsivId */
  45. 0, /* GicRBase */
  46. 0, /* Mpidr */
  47. 0, /* ProcessorPowerEfficiencyClass */
  48. 0, /* Reserved2 */
  49. 21, /* SPE irq */
  50. };
  51. EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MADTTableHeaderTemplate = {
  52. __ACPI_HEADER (
  53. EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
  54. 0, /* need fill in */
  55. EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
  56. ),
  57. };
  58. EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTablePointer;
  59. UINT32
  60. AcpiInstallMadtProcessorNode (
  61. VOID *EntryPointer,
  62. UINT32 CpuId
  63. )
  64. {
  65. EFI_ACPI_6_3_GIC_STRUCTURE *MadtProcessorEntryPointer = EntryPointer;
  66. UINT32 SocketId;
  67. UINT32 ClusterId;
  68. UINTN Size;
  69. Size = sizeof (GiccTemplate);
  70. CopyMem (MadtProcessorEntryPointer, &GiccTemplate, Size);
  71. SocketId = SOCKET_ID (CpuId);
  72. ClusterId = CLUSTER_ID (CpuId);
  73. //
  74. // GICv2 compatibility mode is not supported.
  75. // Hence, set GIC's CPU Interface Number to 0.
  76. //
  77. MadtProcessorEntryPointer->CPUInterfaceNumber = 0;
  78. MadtProcessorEntryPointer->AcpiProcessorUid =
  79. (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
  80. (ClusterId << 8) + (CpuId % PLATFORM_CPU_NUM_CORES_PER_CPM);
  81. MadtProcessorEntryPointer->Flags = 1;
  82. MadtProcessorEntryPointer->MPIDR =
  83. (((ClusterId << 8) + (CpuId % PLATFORM_CPU_NUM_CORES_PER_CPM)) << 8);
  84. MadtProcessorEntryPointer->MPIDR += (((UINT64)SocketId) << 32);
  85. return Size;
  86. }
  87. UINT32
  88. AcpiInstallMadtGicD (
  89. VOID *EntryPointer
  90. )
  91. {
  92. EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GicDEntryPointer = EntryPointer;
  93. UINTN Size;
  94. Size = sizeof (GicDTemplate);
  95. CopyMem (GicDEntryPointer, &GicDTemplate, Size);
  96. return Size;
  97. }
  98. UINT32
  99. AcpiInstallMadtGicR (
  100. VOID *EntryPointer,
  101. UINT32 SocketId
  102. )
  103. {
  104. EFI_ACPI_6_3_GICR_STRUCTURE *GicREntryPointer = EntryPointer;
  105. UINTN Size;
  106. /*
  107. * If the Slave socket is not present, discard the Slave socket
  108. * GIC redistributor region
  109. */
  110. if (SocketId == 1 && !IsSlaveSocketActive ()) {
  111. return 0;
  112. }
  113. Size = sizeof (GicRTemplate);
  114. CopyMem (GicREntryPointer, &GicRTemplate, Size);
  115. if (SocketId == 1) {
  116. GicREntryPointer->DiscoveryRangeBaseAddress = AC01_GICR_SLAVE_BASE_ADDRESS;
  117. }
  118. return Size;
  119. }
  120. UINT32
  121. AcpiInstallMadtGicIts (
  122. VOID *EntryPointer,
  123. UINT32 Index
  124. )
  125. {
  126. EFI_ACPI_6_3_GIC_ITS_STRUCTURE *GicItsEntryPointer = EntryPointer;
  127. UINTN Size, Offset;
  128. UINT64 GicBase = AC01_GICD_MASTER_BASE_ADDRESS;
  129. UINT32 ItsId = Index;
  130. if (Index > SOCKET0_LAST_RC) { /* Socket 1, Index: 8-15 */
  131. GicBase = AC01_GICD_SLAVE_BASE_ADDRESS;
  132. Index -= (SOCKET0_LAST_RC + 1); /* Socket 1, Index:8 -> RCA0 */
  133. }
  134. Size = sizeof (GicItsTemplate);
  135. CopyMem (GicItsEntryPointer, &GicItsTemplate, Size);
  136. Offset = 0x40000 + Index * 0x20000;
  137. GicItsEntryPointer->GicItsId = ItsId;
  138. GicItsEntryPointer->PhysicalBaseAddress = Offset + GicBase;
  139. return Size;
  140. }
  141. /*
  142. * Install MADT table.
  143. */
  144. EFI_STATUS
  145. AcpiInstallMadtTable (
  146. VOID
  147. )
  148. {
  149. EFI_ACPI_6_3_GIC_STRUCTURE *GiccEntryPointer = NULL;
  150. EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
  151. UINTN MadtTableKey = 0;
  152. INTN Index;
  153. EFI_STATUS Status;
  154. UINTN Size;
  155. UINTN Length;
  156. UINT32 *CoreOrder;
  157. UINT32 SktMaxCoreNum;
  158. Status = gBS->LocateProtocol (
  159. &gEfiAcpiTableProtocolGuid,
  160. NULL,
  161. (VOID **)&AcpiTableProtocol
  162. );
  163. if (EFI_ERROR (Status)) {
  164. return Status;
  165. }
  166. Size = sizeof (MADTTableHeaderTemplate) +
  167. sizeof (GiccTemplate) * GetNumberOfActiveCores () +
  168. sizeof (GicDTemplate) +
  169. sizeof (GicRTemplate) * GetNumberOfActiveSockets () +
  170. sizeof (GicItsTemplate) * (SOCKET0_LAST_RC - SOCKET0_FIRST_RC + 1);
  171. if (IsSlaveSocketActive ()) {
  172. Size += (sizeof (GicItsTemplate) * (SOCKET1_LAST_RC - SOCKET1_FIRST_RC + 1));
  173. } else if (!IsSlaveSocketAvailable ()) {
  174. Size += sizeof (GicItsTemplate) * 2; /* RCA0/1 */
  175. }
  176. MadtTablePointer =
  177. (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (Size);
  178. if (MadtTablePointer == NULL) {
  179. return EFI_OUT_OF_RESOURCES;
  180. }
  181. GiccEntryPointer =
  182. (EFI_ACPI_6_3_GIC_STRUCTURE *)((UINT64)MadtTablePointer +
  183. sizeof (MADTTableHeaderTemplate));
  184. /* Install Gic interface for each processor */
  185. Length = 0;
  186. CoreOrder = CpuGetCoreOrder ();
  187. ASSERT (CoreOrder != NULL);
  188. SktMaxCoreNum = PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM;
  189. for (Index = 0; Index < SktMaxCoreNum; Index++) {
  190. if (IsCpuEnabled (CoreOrder[Index])) {
  191. Length += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Length), CoreOrder[Index]);
  192. }
  193. }
  194. for (Index = 0; Index < SktMaxCoreNum; Index++) {
  195. if (IsCpuEnabled (CoreOrder[Index] + SktMaxCoreNum)) {
  196. Length += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Length), CoreOrder[Index] + SktMaxCoreNum);
  197. }
  198. }
  199. /* Install Gic Distributor */
  200. Length += AcpiInstallMadtGicD ((VOID *)((UINT64)GiccEntryPointer + Length));
  201. /* Install Gic Redistributor */
  202. for (Index = 0; Index < PLATFORM_CPU_MAX_SOCKET; Index++) {
  203. Length += AcpiInstallMadtGicR ((VOID *)((UINT64)GiccEntryPointer + Length), Index);
  204. }
  205. /* Install Gic ITS */
  206. if (!IsSlaveSocketAvailable ()) {
  207. for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
  208. Length += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Length), Index);
  209. }
  210. }
  211. for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
  212. Length += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Length), Index);
  213. }
  214. if (IsSlaveSocketActive ()) {
  215. for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
  216. Length += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Length), Index);
  217. }
  218. }
  219. CopyMem (
  220. MadtTablePointer,
  221. &MADTTableHeaderTemplate,
  222. sizeof (MADTTableHeaderTemplate)
  223. );
  224. Length += sizeof (MADTTableHeaderTemplate);
  225. MadtTablePointer->Header.Length = Length;
  226. ASSERT (Size == Length);
  227. CopyMem (
  228. MadtTablePointer->Header.OemId,
  229. PcdGetPtr (PcdAcpiDefaultOemId),
  230. sizeof (MadtTablePointer->Header.OemId)
  231. );
  232. AcpiUpdateChecksum ((UINT8 *)MadtTablePointer, MadtTablePointer->Header.Length);
  233. Status = AcpiTableProtocol->InstallAcpiTable (
  234. AcpiTableProtocol,
  235. (VOID *)MadtTablePointer,
  236. MadtTablePointer->Header.Length,
  237. &MadtTableKey
  238. );
  239. FreePool ((VOID *)MadtTablePointer);
  240. if (EFI_ERROR (Status)) {
  241. return Status;
  242. }
  243. return EFI_SUCCESS;
  244. }