AcpiPlatformLib.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  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. ACPI_APIC_STRUCTURE_PTR *ProcessorLocalApicEntry;
  253. UINT64 TempOemTableId;
  254. UINT32 Data32;
  255. DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
  256. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
  257. if (EFI_ERROR (Status)) {
  258. ASSERT_EFI_ERROR (Status);
  259. return Status;
  260. }
  261. TableHeader = NULL;
  262. ProcessorLocalApicEntry = NULL;
  263. Status = EFI_SUCCESS;
  264. //
  265. // By default, a table belongs in all ACPI table versions published.
  266. // Some tables will override this because they have different versions of the table.
  267. //
  268. *Version = EFI_ACPI_TABLE_VERSION_2_0;
  269. if (Table->Signature != EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE &&
  270. Table->Signature != EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
  271. Table->Signature != SIGNATURE_32('N', 'F', 'I', 'T') &&
  272. Table->Signature != SIGNATURE_32('P', 'C', 'A', 'T') &&
  273. Table->Signature != SIGNATURE_32('O', 'E', 'M', '1') &&
  274. Table->Signature != SIGNATURE_32('O', 'E', 'M', '2') &&
  275. Table->Signature != SIGNATURE_32('O', 'E', 'M', '3') &&
  276. Table->Signature != SIGNATURE_32('O', 'E', 'M', '4'))
  277. {
  278. TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
  279. //
  280. // Update the OEMID and OEM Table ID.
  281. //
  282. TempOemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
  283. CopyMem (TableHeader->OemId, PcdGetPtr(PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
  284. CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader->OemTableId));
  285. //
  286. // Update the creator ID
  287. //
  288. TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
  289. //
  290. // Update the creator revision
  291. //
  292. TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
  293. }
  294. //
  295. // Complete this function
  296. //
  297. //ASSERT (mMaxNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
  298. //
  299. // Assign a invalid intial value for update
  300. //
  301. //
  302. // Update the processors in the APIC table
  303. //
  304. DEBUG ((DEBUG_INFO, "[ACPI] Patching '%c%c%c%c' table...\n",
  305. ((CHAR8*)&Table->Signature)[0], ((CHAR8*)&Table->Signature)[1],
  306. ((CHAR8*)&Table->Signature)[2], ((CHAR8*)&Table->Signature)[3]));
  307. switch (Table->Signature) {
  308. //
  309. // Do not allow a prebuilt MADT, since it is built dynamically.
  310. //
  311. case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
  312. DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: Prebuilt MADT found\n"));
  313. Status = EFI_INVALID_PARAMETER;
  314. ASSERT_EFI_ERROR (Status);
  315. break;
  316. case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
  317. Status = PatchFadtTable (Table);
  318. break;
  319. case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
  320. //
  321. // Patch the memory resource
  322. //
  323. Status = PatchDsdtTable (Table);
  324. break;
  325. case EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
  326. Status = PatchSsdtTable (Table,Version);
  327. break;
  328. case EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
  329. //
  330. // Adjust HPET Table to correct the Base Address
  331. // Get the address bits in RCRB that configure HPET MMIO space
  332. // and create an offset to the pre-defined HEPT base address
  333. //
  334. DynamicSiLibraryProtocol2->PchHpetBaseGet (&Data32);
  335. //
  336. // Add the offset to the base address and copy into HPET DSDT table
  337. //
  338. ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table)->BaseAddressLower32Bit.Address = Data32;
  339. break;
  340. case EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
  341. Status = PatchMcfgAcpiTable (Table);
  342. break;
  343. case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
  344. Status = PatchSpcrAcpiTable (Table);
  345. break;
  346. case ACPI_PMTT_TABLE_SIGNATURE:
  347. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  348. Status = PatchPlatformMemoryTopologyTable (Table);
  349. }
  350. break;
  351. case EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE:
  352. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  353. Status = PatchHmatAcpiTable (Table);
  354. }
  355. break;
  356. case EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE:
  357. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  358. Status = PatchMsctAcpiTable (Table);
  359. }
  360. break;
  361. case EFI_MIGT_ACPI_TABLE_SIGNATURE:
  362. if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
  363. if (PcdGetBool (ReservedB)) {
  364. Status = PatchMigtAcpiTable (Table);
  365. }
  366. }
  367. break;
  368. case EFI_BDAT_TABLE_SIGNATURE:
  369. if (!PcdGetBool (PcdPlatformNotSupportAcpiBdatTable)) {
  370. Status = PatchBdatAcpiTable (Table);
  371. }
  372. break;
  373. case NVDIMM_FW_INTERFACE_TABLE_SIGNATURE:
  374. Status = UpdateNfitTable (Table);
  375. break;
  376. case NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE:
  377. Status = UpdatePcatTable (Table);
  378. break;
  379. //Patch Dynamic OEM SSDT table
  380. case OEM1_SSDT_TABLE_SIGNATURE:
  381. Status = PatchOem1SsdtTable (Table); //CPU EIST
  382. break;
  383. case OEM2_SSDT_TABLE_SIGNATURE:
  384. Status = PatchOem2SsdtTable (Table); //CPU HWP
  385. break;
  386. case OEM3_SSDT_TABLE_SIGNATURE:
  387. Status = PatchOem3SsdtTable (Table); //CPU TST
  388. break;
  389. case OEM4_SSDT_TABLE_SIGNATURE:
  390. Status = PatchOem4SsdtTable (Table); //CPU CST
  391. break;
  392. case ACPI_WSMT_SIGNATURE:
  393. (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags) = (UINT32 ) (WSMT_PROTECTION_FLAG & PcdGet32(PcdWsmtProtectionFlags));
  394. DEBUG ((DEBUG_INFO, "[WSMT] ProtectionFlags = 0x%x\n", (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags)));
  395. break;
  396. default:
  397. //
  398. // Hooks for Platform only table. If the ACPI Table is Platform only, add this table in below hook. then continue to update other Table.
  399. //
  400. Status = PatchPlatformSpecificAcpiTableHooks (Table);
  401. break;
  402. }
  403. //
  404. //
  405. // Update the hardware signature in the FACS structure
  406. //
  407. //
  408. //
  409. return Status;
  410. }
  411. /**
  412. Give the platform a chance to build tables.
  413. Some tables can be built from scratch more efficiently than being prebuilt
  414. and updated. This function builds any such tables for the platform.
  415. @retval EFI_SUCCESS Any platform tables were successfully built.
  416. **/
  417. EFI_STATUS
  418. PlatformBuildTables (
  419. VOID
  420. )
  421. {
  422. EFI_STATUS ReturnStatus = EFI_SUCCESS;
  423. EFI_STATUS Status;
  424. Status = InstallMadtFromScratch ();
  425. if (EFI_ERROR (Status)) {
  426. ReturnStatus = Status;
  427. }
  428. if (mSocketCommonRcConfiguration.NumaEn) {
  429. Status = InstallSlitTable ();
  430. if (EFI_ERROR (Status)) {
  431. ReturnStatus = Status;
  432. }
  433. Status = InstallSratTable ();
  434. if (EFI_ERROR (Status)) {
  435. ReturnStatus = Status;
  436. }
  437. }
  438. //
  439. // Return the first error code that occured, or success.
  440. //
  441. return ReturnStatus;
  442. }