AcpiPlatformLib.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /** @file
  2. ACPI Platform Driver Hooks
  3. @copyright
  4. Copyright 1996 - 2020 Intel Corporation. <BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. //
  8. // Statements that include other files
  9. //
  10. #include "AcpiPlatformLibLocal.h"
  11. #include <Protocol/AcpiSystemDescriptionTable.h>
  12. #include <Library/UbaPlatLib.h>
  13. #include <Library/PlatformSpecificAcpiTableLib.h>
  14. #include <Protocol/DynamicSiLibraryProtocol.h>
  15. #include <Protocol/DynamicSiLibraryProtocol2.h>
  16. extern BIOS_ACPI_PARAM *mAcpiParameter;
  17. EFI_PLATFORM_INFO *mPlatformInfo;
  18. EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess;
  19. EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
  20. extern EFI_IIO_UDS_PROTOCOL *mIioUds;
  21. CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr;
  22. UINT32 mNumOfBitShift;
  23. BOOLEAN mX2ApicEnabled;
  24. SYSTEM_MEMORY_MAP_HOB *mSystemMemoryMap;
  25. SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration;
  26. SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration;
  27. SOCKET_IIO_CONFIGURATION mSocketIioConfiguration;
  28. SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
  29. SOCKET_COMMONRC_CONFIGURATION mSocketCommonRcConfiguration;
  30. SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfiguration;
  31. CPU_CONFIG_CONTEXT_BUFFER *mCpuConfigLibConfigContextBuffer = NULL;
  32. EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable = NULL;
  33. /**
  34. The constructor function of AcpiPlatormL Library.
  35. The constructor function caches the value of PCD entry
  36. @param ImageHandle The firmware allocated handle for the EFI image.
  37. @param SystemTable A pointer to the EFI System Table.
  38. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
  39. **/
  40. EFI_STATUS
  41. EFIAPI
  42. AcpiPlatformLibConstructor (
  43. VOID
  44. )
  45. {
  46. EFI_STATUS Status;
  47. EFI_HOB_GUID_TYPE *GuidHob;
  48. DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
  49. mCpuConfigLibConfigContextBuffer = (CPU_CONFIG_CONTEXT_BUFFER *) (UINTN) PcdGet64 (PcdCpuConfigContextBuffer);
  50. if (mCpuConfigLibConfigContextBuffer == NULL) {
  51. ASSERT_EFI_ERROR (RETURN_NOT_FOUND);
  52. return RETURN_NOT_FOUND;
  53. }
  54. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
  55. if (EFI_ERROR (Status)) {
  56. ASSERT_EFI_ERROR (Status);
  57. return Status;
  58. }
  59. GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
  60. if (GuidHob == NULL) {
  61. ASSERT (GuidHob != NULL);
  62. return EFI_NOT_FOUND;
  63. }
  64. mPlatformInfo = GET_GUID_HOB_DATA (GuidHob);
  65. //
  66. // Locate the IIO Protocol Interface
  67. //
  68. Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, (VOID **) &mIioUds);
  69. if (EFI_ERROR (Status)) {
  70. ASSERT_EFI_ERROR (Status);
  71. return Status;
  72. }
  73. Status = gBS->LocateProtocol (&gEfiCpuCsrAccessGuid, NULL, (VOID **) &mCpuCsrAccess);
  74. if (EFI_ERROR (Status)) {
  75. ASSERT_EFI_ERROR (Status);
  76. return Status;
  77. }
  78. mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
  79. mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
  80. ASSERT (mSystemMemoryMap != NULL);
  81. mMpService = NULL;
  82. Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &mMpService);
  83. if (EFI_ERROR (Status)) {
  84. ASSERT_EFI_ERROR (Status);
  85. return Status;
  86. }
  87. //
  88. // Determine the number of processors
  89. //
  90. mMpService->GetNumberOfProcessors (
  91. mMpService,
  92. &mNumberOfCPUs,
  93. &mNumberOfEnabledCPUs
  94. );
  95. ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
  96. if (mNumberOfCPUs > MAX_CPU_NUM) {
  97. mNumberOfCPUs = MAX_CPU_NUM;
  98. }
  99. Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
  100. if (EFI_ERROR (Status)) {
  101. ASSERT_EFI_ERROR (Status);
  102. return Status;
  103. }
  104. return EFI_SUCCESS;
  105. }
  106. /**
  107. Platform hook to initialize Platform Specific ACPI Parameters
  108. @retval EFI_SUCCESS Platform specific parameters in mAcpiParameter
  109. initialized successfully.
  110. @retval EFI_INVALID_PARAMETER mAcpiParameter global was NULL.
  111. **/
  112. EFI_STATUS
  113. PlatformHookAfterAcpiParamInit (
  114. VOID
  115. )
  116. {
  117. EFI_STATUS Status;
  118. Status = EFI_SUCCESS;
  119. if (mAcpiParameter == NULL) {
  120. ASSERT (mAcpiParameter != NULL);
  121. return EFI_INVALID_PARAMETER;
  122. }
  123. DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParameter));
  124. //
  125. // Call for Local APIC ID Reorder
  126. //
  127. Status = SortCpuLocalApicInTable ();
  128. if (EFI_ERROR (Status)) {
  129. DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: SortCpuLocalApicInTable failed: %r\n", Status));
  130. return Status;
  131. }
  132. return Status;
  133. }
  134. EFI_STATUS
  135. AcpiPlatformHooksIsActiveTable (
  136. IN OUT EFI_ACPI_COMMON_HEADER *Table
  137. )
  138. {
  139. EFI_NFIT_TABLE_UPDATE_PROTOCOL *NfitTableUpdateProtocol;
  140. EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
  141. EFI_STATUS Status;
  142. SETUP_DATA SetupData;
  143. SYSTEM_CONFIGURATION SystemConfiguration;
  144. UINT8 *OemSkuAcpiName;
  145. Status = GetEntireConfig (&SetupData);
  146. ASSERT_EFI_ERROR (Status);
  147. CopyMem (&SystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
  148. if (mSystemMemoryMap == NULL) {
  149. ASSERT (FALSE);
  150. return EFI_NOT_FOUND;
  151. }
  152. TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
  153. if (TableHeader->Signature == ACPI_PMTT_TABLE_SIGNATURE) {
  154. if (!mSystemMemoryMap->DcpmmPresent) {
  155. return EFI_NOT_FOUND;
  156. }
  157. }
  158. if (TableHeader->Signature == EFI_BDAT_TABLE_SIGNATURE) {
  159. if (mSocketMemoryConfiguration.bdatEn == 0) {
  160. return EFI_NOT_FOUND;
  161. }
  162. }
  163. if (TableHeader->Signature == NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE) {
  164. if (mSystemMemoryMap->DcpmmPresent == 0) {
  165. return EFI_NOT_FOUND;
  166. }
  167. }
  168. if (TableHeader->Signature == NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
  169. Status = gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL, (VOID **) &NfitTableUpdateProtocol);
  170. if (EFI_ERROR (Status)){
  171. // If NfitTableUpdateProtocol is not found we assume no NVDIMM is present - it means don't publish NFIT
  172. DEBUG ((DEBUG_ERROR, "NfitTableUpdateProtocol is not installed.\n"));
  173. return EFI_NOT_FOUND;
  174. }
  175. }
  176. if (TableHeader->Signature == EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE) {
  177. //
  178. // Initialize the SPCR table pointer.
  179. // SPCR table is not ready yet, update it before booting.
  180. //
  181. mSpcrTable = (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *) Table;
  182. return EFI_NOT_READY;
  183. }
  184. if ((TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE) ||
  185. (TableHeader->Signature == EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE) ||
  186. (TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) ||
  187. TableHeader->Signature == EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE) {
  188. //
  189. // Only publish SRAT/SLIT/MSCT/HMAT if NUMA is enabled in setup.
  190. //
  191. if (!mSocketCommonRcConfiguration.NumaEn) {
  192. DEBUG ((DEBUG_INFO, "[ACPI] NUMA disabled, do not publish '%c%c%c%c' table\n",
  193. ((CHAR8*)&TableHeader->Signature)[0], ((CHAR8*)&TableHeader->Signature)[1],
  194. ((CHAR8*)&TableHeader->Signature)[2], ((CHAR8*)&TableHeader->Signature)[3]));
  195. return EFI_NOT_FOUND;
  196. }
  197. }
  198. if (TableHeader->Signature == EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE) {
  199. return EFI_NOT_FOUND;
  200. }
  201. if (TableHeader->Signature == EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
  202. OemSkuAcpiName = PcdGetPtr (PcdOemSkuAcpiName);
  203. if (OemSkuAcpiName == NULL) {
  204. return EFI_UNSUPPORTED;
  205. }
  206. if ( (0 == CompareMem (&(TableHeader->OemTableId), OemSkuAcpiName, 8)) ) {
  207. Status = PlatformGetAcpiFixTableDataPointer ((VOID ** ) &mAmlOffsetTablePointer);
  208. if (!EFI_ERROR(Status)) {
  209. DEBUG((DEBUG_INFO, "[ACPI] Platform DSDT Fixup table found\n"));
  210. DEBUG((DEBUG_INFO, "[ACPI] Platform SRP: Using %a DSDT\n", OemSkuAcpiName));
  211. return EFI_SUCCESS;
  212. } else {
  213. DEBUG((DEBUG_ERROR, "[ACPI] Platform DSDT Fixup table not found.\n"));
  214. return EFI_UNSUPPORTED;
  215. }
  216. } else {
  217. DEBUG ((DEBUG_INFO, "[ACPI] Platform DSDT OemSkuAcpiName '%c%c%c%c%c%c%c%c':\n",
  218. ((CHAR8*)OemSkuAcpiName)[0], ((CHAR8*)OemSkuAcpiName)[1],
  219. ((CHAR8*)OemSkuAcpiName)[2], ((CHAR8*)OemSkuAcpiName)[3],
  220. ((CHAR8*)OemSkuAcpiName)[4], ((CHAR8*)OemSkuAcpiName)[5],
  221. ((CHAR8*)OemSkuAcpiName)[6], ((CHAR8*)OemSkuAcpiName)[7]));
  222. DEBUG ((DEBUG_INFO, " no match for OemTableId '%c%c%c%c%c%c%c%c' from FwVol.\n",
  223. ((CHAR8*)&TableHeader->OemTableId)[0], ((CHAR8*)&TableHeader->OemTableId)[1],
  224. ((CHAR8*)&TableHeader->OemTableId)[2], ((CHAR8*)&TableHeader->OemTableId)[3],
  225. ((CHAR8*)&TableHeader->OemTableId)[4], ((CHAR8*)&TableHeader->OemTableId)[5],
  226. ((CHAR8*)&TableHeader->OemTableId)[6], ((CHAR8*)&TableHeader->OemTableId)[7]));
  227. return EFI_UNSUPPORTED;
  228. }
  229. }
  230. //
  231. // Hooks for checking additional platform ACPI Table is active or not.
  232. // If ACPI Table is not in list, it should be reported and returned EFI_SUCCESS.
  233. //
  234. return PlatformAcpiReportHooksTableIsActive (Table);
  235. }
  236. /**
  237. This function will update any runtime platform specific information.
  238. This currently includes:
  239. Setting OEM table values, ID, table ID, creator ID and creator revision.
  240. Enabling the proper processor entries in the APIC tables.
  241. @param Table - The table to update
  242. @retval EFI_SUCCESS - The function completed successfully.
  243. **/
  244. EFI_STATUS
  245. PlatformUpdateTables (
  246. IN OUT EFI_ACPI_COMMON_HEADER *Table,
  247. IN OUT EFI_ACPI_TABLE_VERSION *Version
  248. )
  249. {
  250. EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
  251. EFI_STATUS Status;
  252. UINT64 TempOemTableId;
  253. UINT32 Data32;
  254. DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
  255. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
  256. if (EFI_ERROR (Status)) {
  257. ASSERT_EFI_ERROR (Status);
  258. return Status;
  259. }
  260. TableHeader = NULL;
  261. Status = EFI_SUCCESS;
  262. //
  263. // By default, a table belongs in all ACPI table versions published.
  264. // Some tables will override this because they have different versions of the table.
  265. //
  266. *Version = EFI_ACPI_TABLE_VERSION_2_0;
  267. if (Table->Signature != EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE &&
  268. Table->Signature != EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
  269. Table->Signature != SIGNATURE_32('N', 'F', 'I', 'T') &&
  270. Table->Signature != SIGNATURE_32('P', 'C', 'A', 'T') &&
  271. Table->Signature != SIGNATURE_32('O', 'E', 'M', '1') &&
  272. Table->Signature != SIGNATURE_32('O', 'E', 'M', '2') &&
  273. Table->Signature != SIGNATURE_32('O', 'E', 'M', '3') &&
  274. Table->Signature != SIGNATURE_32('O', 'E', 'M', '4'))
  275. {
  276. TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
  277. //
  278. // Update the OEMID and OEM Table ID.
  279. //
  280. TempOemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
  281. CopyMem (TableHeader->OemId, PcdGetPtr(PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
  282. CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader->OemTableId));
  283. //
  284. // Update the creator ID
  285. //
  286. TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
  287. //
  288. // Update the creator revision
  289. //
  290. TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
  291. }
  292. //
  293. // Complete this function
  294. //
  295. //ASSERT (mMaxNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
  296. //
  297. // Assign a invalid intial value for update
  298. //
  299. //
  300. // Update the processors in the APIC table
  301. //
  302. DEBUG ((DEBUG_INFO, "[ACPI] Patching '%c%c%c%c' table...\n",
  303. ((CHAR8*)&Table->Signature)[0], ((CHAR8*)&Table->Signature)[1],
  304. ((CHAR8*)&Table->Signature)[2], ((CHAR8*)&Table->Signature)[3]));
  305. switch (Table->Signature) {
  306. //
  307. // Do not allow a prebuilt MADT, since it is built dynamically.
  308. //
  309. case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
  310. DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: Prebuilt MADT found\n"));
  311. Status = EFI_INVALID_PARAMETER;
  312. ASSERT_EFI_ERROR (Status);
  313. break;
  314. case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
  315. Status = PatchFadtTable (Table);
  316. break;
  317. case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
  318. //
  319. // Patch the memory resource
  320. //
  321. Status = PatchDsdtTable (Table);
  322. break;
  323. case EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
  324. Status = PatchSsdtTable (Table,Version);
  325. break;
  326. case EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
  327. //
  328. // Adjust HPET Table to correct the Base Address
  329. // Get the address bits in RCRB that configure HPET MMIO space
  330. // and create an offset to the pre-defined HEPT base address
  331. //
  332. DynamicSiLibraryProtocol2->PchHpetBaseGet (&Data32);
  333. //
  334. // Add the offset to the base address and copy into HPET DSDT table
  335. //
  336. ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table)->BaseAddressLower32Bit.Address = Data32;
  337. break;
  338. case EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
  339. Status = PatchMcfgAcpiTable (Table);
  340. break;
  341. case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
  342. Status = PatchSpcrAcpiTable (Table);
  343. break;
  344. case ACPI_PMTT_TABLE_SIGNATURE:
  345. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  346. Status = PatchPlatformMemoryTopologyTable (Table);
  347. }
  348. break;
  349. case EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE:
  350. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  351. Status = PatchHmatAcpiTable (Table);
  352. }
  353. break;
  354. case EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE:
  355. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  356. Status = PatchMsctAcpiTable (Table);
  357. }
  358. break;
  359. case EFI_MIGT_ACPI_TABLE_SIGNATURE:
  360. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  361. if (PcdGetBool (ReservedB)) {
  362. Status = PatchMigtAcpiTable (Table);
  363. }
  364. }
  365. break;
  366. case EFI_BDAT_TABLE_SIGNATURE:
  367. if (!PcdGetBool (PcdPlatformNotSupportAcpiBdatTable)) {
  368. Status = PatchBdatAcpiTable (Table);
  369. }
  370. break;
  371. case NVDIMM_FW_INTERFACE_TABLE_SIGNATURE:
  372. Status = UpdateNfitTable (Table);
  373. break;
  374. case NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE:
  375. Status = UpdatePcatTable (Table);
  376. break;
  377. //Patch Dynamic OEM SSDT table
  378. case OEM1_SSDT_TABLE_SIGNATURE:
  379. Status = PatchOem1SsdtTable (Table); //CPU EIST
  380. break;
  381. case OEM2_SSDT_TABLE_SIGNATURE:
  382. Status = PatchOem2SsdtTable (Table); //CPU HWP
  383. break;
  384. case OEM3_SSDT_TABLE_SIGNATURE:
  385. Status = PatchOem3SsdtTable (Table); //CPU TST
  386. break;
  387. case OEM4_SSDT_TABLE_SIGNATURE:
  388. Status = PatchOem4SsdtTable (Table); //CPU CST
  389. break;
  390. case ACPI_WSMT_SIGNATURE:
  391. (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags) = (UINT32 ) (WSMT_PROTECTION_FLAG & PcdGet32(PcdWsmtProtectionFlags));
  392. DEBUG ((DEBUG_INFO, "[WSMT] ProtectionFlags = 0x%x\n", (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags)));
  393. break;
  394. default:
  395. //
  396. // Hooks for Platform only table. If the ACPI Table is Platform only, add this table in below hook. then continue to update other Table.
  397. //
  398. Status = PatchPlatformSpecificAcpiTableHooks (Table);
  399. break;
  400. }
  401. //
  402. //
  403. // Update the hardware signature in the FACS structure
  404. //
  405. //
  406. //
  407. return Status;
  408. }
  409. /**
  410. Give the platform a chance to build tables.
  411. Some tables can be built from scratch more efficiently than being prebuilt
  412. and updated. This function builds any such tables for the platform.
  413. @retval EFI_SUCCESS Any platform tables were successfully built.
  414. **/
  415. EFI_STATUS
  416. PlatformBuildTables (
  417. VOID
  418. )
  419. {
  420. EFI_STATUS ReturnStatus = EFI_SUCCESS;
  421. EFI_STATUS Status;
  422. Status = InstallMadtFromScratch ();
  423. if (EFI_ERROR (Status)) {
  424. ReturnStatus = Status;
  425. }
  426. if (mSocketCommonRcConfiguration.NumaEn) {
  427. Status = InstallSlitTable ();
  428. if (EFI_ERROR (Status)) {
  429. ReturnStatus = Status;
  430. }
  431. Status = InstallSratTable ();
  432. if (EFI_ERROR (Status)) {
  433. ReturnStatus = Status;
  434. }
  435. }
  436. //
  437. // Return the first error code that occured, or success.
  438. //
  439. return ReturnStatus;
  440. }