AcpiPlatform.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /** @file
  2. ACPI Platform Driver
  3. @copyright
  4. Copyright 1999 - 2020 Intel Corporation. <BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "AcpiPlatform.h"
  8. #include "AcpiPlatformUtils.h"
  9. #include "AcpiPlatformHooks.h"
  10. #include <Library/PcdLib.h>
  11. #include <Protocol/PciEnumerationComplete.h>
  12. #include <IioSetupDefinitions.h>
  13. #include <ProcessorPpmSetup.h>
  14. #ifndef __GNUC__
  15. #pragma optimize("", off)
  16. #endif //__GNUC__
  17. extern SOCKET_IIO_CONFIGURATION mSocketIioConfiguration;
  18. extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
  19. extern SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfiguration;
  20. extern EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable;
  21. extern EFI_GUID gEfiGlobalVariableGuid;
  22. extern EFI_GUID gEfiPmSsdtTableStorageGuid;
  23. BIOS_ACPI_PARAM *mAcpiParameter = NULL;
  24. BOOLEAN mFirstNotify;
  25. SYSTEM_CONFIGURATION mSystemConfiguration;
  26. PCH_SETUP mPchSetup;
  27. UINT8 mKBPresent = 0;
  28. UINT8 mMousePresent = 0;
  29. EFI_IIO_UDS_PROTOCOL *mIioUds2 = NULL;
  30. extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr;
  31. UINT8 mPStateEnable = 0;
  32. VOID
  33. EFIAPI
  34. AcpiOnPciEnumCmplCallback (
  35. IN EFI_EVENT Event,
  36. IN VOID *Context
  37. )
  38. {
  39. EFI_STATUS Status;
  40. Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &Context);
  41. if (EFI_ERROR (Status)) {
  42. //
  43. // Skip the first dummy event signal.
  44. //
  45. return;
  46. }
  47. gBS->CloseEvent (Event);
  48. DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
  49. AcpiVtdTablesInstall ();
  50. }
  51. VOID
  52. EFIAPI
  53. AcpiOnEndOfDxeCallback (
  54. IN EFI_EVENT Event,
  55. IN VOID *Context
  56. )
  57. {
  58. DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
  59. //
  60. // Installing ACPI Tables: NFIT, PCAT
  61. //
  62. InstallAndPatchAcpiTable (NVDIMM_FW_INTERFACE_TABLE_SIGNATURE);
  63. InstallAndPatchAcpiTable (NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE);
  64. }
  65. //
  66. // Enable SCI for ACPI aware OS at ExitBootServices
  67. //
  68. VOID
  69. EFIAPI
  70. AcpiOnExitBootServicesCallback (
  71. IN EFI_EVENT Event,
  72. IN VOID *Context
  73. )
  74. {
  75. UINT16 Pm1Cnt;
  76. gBS->CloseEvent (Event);
  77. DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
  78. //
  79. // Enable SCI
  80. //
  81. Pm1Cnt = IoRead16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT);
  82. Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
  83. IoWrite16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT, Pm1Cnt);
  84. }
  85. /**
  86. Disables the SW SMI Timer.
  87. ACPI events are disabled and ACPI event status is cleared.
  88. SCI mode is then enabled.
  89. Disable SW SMI Timer
  90. Clear all ACPI event status and disable all ACPI events
  91. Disable PM sources except power button
  92. Clear status bits
  93. Disable GPE0 sources
  94. Clear status bits
  95. Disable GPE1 sources
  96. Clear status bits
  97. Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
  98. Enable SCI
  99. @param Event - not used
  100. @param Context - not used
  101. @retval None
  102. **/
  103. STATIC
  104. VOID
  105. AcpiEnableAtReadyToBoot (
  106. VOID
  107. )
  108. {
  109. UINT32 SmiEn;
  110. UINT8 Data8;
  111. UINT16 Pm1En;
  112. ASSERT (mAcpiParameter->PmBase != 0);
  113. SmiEn = IoRead32 (mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN);
  114. //
  115. // Disable SW SMI Timer and legacy USB
  116. //
  117. SmiEn &= ~(B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB | B_ACPI_IO_SMI_EN_LEGACY_USB2);
  118. //
  119. // And enable SMI on write to B_ACPI_IO_PM1_CNT_SLP_EN when SLP_TYP is written
  120. //
  121. SmiEn |= B_ACPI_IO_SMI_EN_ON_SLP_EN;
  122. IoWrite32(mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN, SmiEn);
  123. //
  124. // Disable PM sources except power button
  125. //
  126. Pm1En = B_ACPI_IO_PM1_EN_PWRBTN;
  127. IoWrite16(mAcpiParameter->PmBase + R_ACPI_IO_PM1_EN, Pm1En);
  128. //
  129. // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
  130. //
  131. Data8 = RTC_ADDRESS_REGISTER_D;
  132. IoWrite8(R_IOPORT_CMOS_STANDARD_INDEX, Data8);
  133. Data8 = 0x0;
  134. IoWrite8(R_IOPORT_CMOS_STANDARD_DATA, Data8);
  135. //
  136. // Do platform specific stuff for ACPI enable SMI
  137. //
  138. }
  139. /**
  140. Executes ACPI Platform actions related with ready to boot event
  141. @param Event - not used
  142. @param Context - not used
  143. @retval None
  144. **/
  145. STATIC
  146. VOID
  147. EFIAPI
  148. AcpiOnReadyToBootCallback (
  149. IN EFI_EVENT Event,
  150. IN VOID *Context
  151. )
  152. {
  153. EFI_STATUS Status;
  154. EFI_ACPI_DESCRIPTION_HEADER Table = {0};
  155. EFI_ACPI_TABLE_VERSION TableVersion;
  156. UINTN TableHandle;
  157. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  158. EFI_CPUID_REGISTER CpuidRegisters;
  159. SETUP_DATA SetupData;
  160. UINT8 ARIForward;
  161. DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
  162. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
  163. if (EFI_ERROR (Status)) {
  164. ASSERT_EFI_ERROR (Status);
  165. return;
  166. }
  167. if (mFirstNotify) {
  168. return;
  169. }
  170. mFirstNotify = TRUE;
  171. DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
  172. Status = GetEntireConfig (&SetupData);
  173. ASSERT_EFI_ERROR (Status);
  174. CopyMem (&mSystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
  175. CopyMem (&mSocketIioConfiguration, &(SetupData.SocketConfig.IioConfig), sizeof(SOCKET_IIO_CONFIGURATION));
  176. CopyMem (&mSocketPowermanagementConfiguration, &(SetupData.SocketConfig.PowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION));
  177. CopyMem (&mSocketProcessorCoreConfiguration, &(SetupData.SocketConfig.SocketProcessorCoreConfiguration), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
  178. CopyMem (&mPchSetup, &(SetupData.PchSetup), sizeof(PCH_SETUP));
  179. mAcpiParameter->TpmEnable = mSystemConfiguration.TpmEnable;
  180. //
  181. // CpuPm.Asl: External (CSEN, FieldUnitObj)
  182. //
  183. mAcpiParameter->CStateEnable = TRUE;
  184. //
  185. // CpuPm.Asl: External (C3EN, FieldUnitObj)
  186. //
  187. mAcpiParameter->C3Enable = mSocketPowermanagementConfiguration.C3Enable;
  188. //
  189. // CpuPm.Asl: External (C6EN, FieldUnitObj)
  190. //
  191. AsmCpuid (CPUID_MONITOR_MWAIT, &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
  192. //
  193. // If C6 is not supported by CPU, disregard setup C6 knob value
  194. //
  195. if (((CpuidRegisters.RegEdx >> 12) & 0xF) > 0) {
  196. if (mSocketPowermanagementConfiguration.C6Enable == PPM_AUTO) {
  197. mAcpiParameter->C6Enable = 1; // POR Default = Enabled
  198. } else {
  199. mAcpiParameter->C6Enable = mSocketPowermanagementConfiguration.C6Enable;
  200. }
  201. } else {
  202. mAcpiParameter->C6Enable = 0;
  203. DEBUG ((DEBUG_INFO, "Cpu does not support C6 state\n"));
  204. }
  205. if (mAcpiParameter->C6Enable && mAcpiParameter->C3Enable) { //C3 and C6 enable are exclusive
  206. mAcpiParameter->C6Enable = 1;
  207. mAcpiParameter->C3Enable = 0;
  208. }
  209. //
  210. // CpuPm.Asl: External (C7EN, FieldUnitObj)
  211. //
  212. mAcpiParameter->C7Enable = 0;
  213. //
  214. // CpuPm.Asl: External (OSCX, FieldUnitObj)
  215. //
  216. mAcpiParameter->OSCX = mSocketPowermanagementConfiguration.OSCx;
  217. //
  218. // CpuPm.Asl: External (MWOS, FieldUnitObj)
  219. //
  220. mAcpiParameter->MonitorMwaitEnable = 1;
  221. //
  222. // CpuPm.Asl: External (PSEN, FieldUnitObj)
  223. //
  224. mAcpiParameter->PStateEnable = mPStateEnable;
  225. //
  226. // CpuPm.Asl: External (HWAL, FieldUnitObj)
  227. //
  228. mAcpiParameter->HWAllEnable = mSocketPowermanagementConfiguration.ProcessorEistPsdFunc;
  229. mAcpiParameter->KBPresent = mKBPresent;
  230. mAcpiParameter->MousePresent = mMousePresent;
  231. mAcpiParameter->TStateEnable = mSocketPowermanagementConfiguration.TStateEnable;
  232. //
  233. // Debug mode indicator for Acpi use
  234. //
  235. mAcpiParameter->DebugModeIndicator = (UINT8)PcdGet8 (PcdDebugModeEnable);
  236. DEBUG ((DEBUG_ERROR, "DebugModeIndicator = %x\n", mAcpiParameter->DebugModeIndicator));
  237. //
  238. // Fine grained T state
  239. //
  240. AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
  241. if ((((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.ECMD) && mSocketPowermanagementConfiguration.TStateEnable) {
  242. mAcpiParameter->TStateFineGrained = 1;
  243. }
  244. if (((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.HWP_Notification != 0) {
  245. mAcpiParameter->HwpInterrupt = 1;
  246. }
  247. //
  248. // CpuPm.Asl: External (HWEN, FieldUnitObj)
  249. //
  250. mAcpiParameter->HWPMEnable = DetectHwpFeature ();
  251. mAcpiParameter->EmcaEn = mSystemConfiguration.EmcaEn;
  252. mAcpiParameter->WheaSupportEn = mSystemConfiguration.WheaSupportEn;
  253. mAcpiParameter->PcieAcpiHotPlugEnable = (UINT8) (BOOLEAN) (mSocketIioConfiguration.PcieAcpiHotPlugEnable != 0);
  254. //
  255. // Initialize USB3 mode from setup data
  256. //
  257. // If mode != manual control
  258. // just copy mode from setup
  259. //
  260. if (mPchSetup.PchUsbManualMode != 1) {
  261. mAcpiParameter->XhciMode = mPchSetup.PchUsbManualMode;
  262. }
  263. //
  264. // Get ACPI IO Base Address
  265. //
  266. mAcpiParameter->PmBase = DynamicSiLibraryProtocol->PmcGetAcpiBase ();
  267. DEBUG ((DEBUG_INFO, "ACPI IO Base Address = %x\n", mAcpiParameter->PmBase));
  268. //
  269. // When X2APIC enabled and VTD support enabled, Enable ApicIdOverrided parameter to update ACPI table.
  270. //
  271. if (mSocketIioConfiguration.VTdSupport && mSocketProcessorCoreConfiguration.ProcessorX2apic) {
  272. mAcpiParameter->ApicIdOverrided = 1;
  273. }
  274. //
  275. // Find the AcpiTable protocol
  276. //
  277. Status = LocateSupportProtocol (
  278. &gEfiAcpiTableProtocolGuid,
  279. gEfiAcpiTableStorageGuid,
  280. (VOID **) &AcpiTable,
  281. FALSE
  282. );
  283. ASSERT_EFI_ERROR (Status);
  284. TableVersion = EFI_ACPI_TABLE_VERSION_2_0;
  285. Table.Signature = EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE;
  286. Status = PlatformUpdateTables ((EFI_ACPI_COMMON_HEADER *)&Table, &TableVersion);
  287. if (!EFI_ERROR (Status)) {
  288. //
  289. // Add SPCR table
  290. //
  291. if (mSpcrTable != NULL) {
  292. DEBUG ((DEBUG_INFO, "mSpcrTable->Header.Length=%d\n", mSpcrTable->Header.Length));
  293. DEBUG ((DEBUG_INFO, "install=%x\n", &(AcpiTable->InstallAcpiTable)));
  294. DEBUG ((DEBUG_INFO, "acpit=%x\n", AcpiTable));
  295. DEBUG ((DEBUG_INFO, "mSpcr=%x\n", mSpcrTable));
  296. DEBUG ((DEBUG_INFO, "len =%d\n", mSpcrTable->Header.Length));
  297. TableHandle = 0;
  298. Status = AcpiTable->InstallAcpiTable (
  299. AcpiTable,
  300. mSpcrTable,
  301. mSpcrTable->Header.Length,
  302. &TableHandle
  303. );
  304. ASSERT_EFI_ERROR (Status);
  305. } else {
  306. DEBUG ((DEBUG_INFO, "Warning: mSpcrTable is NULL\n"));
  307. }
  308. }
  309. if (mSpcrTable != NULL) {
  310. gBS->FreePool (mSpcrTable);
  311. }
  312. AcpiEnableAtReadyToBoot();
  313. Status = GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFIGURATION, ARIForward), &ARIForward, sizeof(UINT8));
  314. ASSERT_EFI_ERROR (Status);
  315. if (!ARIForward) {
  316. DisableAriForwarding ();
  317. }
  318. }
  319. /**
  320. Installs ACPI Platform tables
  321. @param None
  322. @retval EFI_SUCCESS - Operation completed successfully.
  323. **/
  324. STATIC
  325. EFI_STATUS
  326. EFIAPI
  327. AcpiPlatformEarlyAcpiTablesInstall (
  328. VOID
  329. )
  330. {
  331. EFI_STATUS Status;
  332. EFI_STATUS AcpiStatus;
  333. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  334. EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  335. INTN Instance = 0;
  336. EFI_ACPI_COMMON_HEADER *CurrentTable;
  337. EFI_ACPI_TABLE_VERSION TableVersion;
  338. UINTN TableHandle;
  339. UINT32 FvStatus;
  340. UINT32 Size;
  341. //
  342. // Find the AcpiTable protocol
  343. //
  344. Status = LocateSupportProtocol (
  345. &gEfiAcpiTableProtocolGuid,
  346. gEfiAcpiTableStorageGuid,
  347. (VOID **) &AcpiTable,
  348. FALSE
  349. );
  350. ASSERT_EFI_ERROR (Status);
  351. //
  352. // Locate the firmware volume protocol
  353. //
  354. Status = LocateSupportProtocol (
  355. &gEfiFirmwareVolume2ProtocolGuid,
  356. gEfiAcpiTableStorageGuid,
  357. (VOID **) &FwVol,
  358. TRUE
  359. );
  360. ASSERT_EFI_ERROR (Status);
  361. //
  362. // Read tables from the storage file.
  363. //
  364. while (!EFI_ERROR (Status)) {
  365. CurrentTable = NULL;
  366. TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
  367. TableHandle = 0;
  368. Status = FwVol->ReadSection (
  369. FwVol,
  370. &gEfiAcpiTableStorageGuid,
  371. EFI_SECTION_RAW,
  372. Instance,
  373. (VOID **) &CurrentTable,
  374. (UINTN *) &Size,
  375. &FvStatus
  376. );
  377. if (!EFI_ERROR (Status)) {
  378. DEBUG ((DEBUG_INFO, "[ACPI] Table '%c%c%c%c' found in FwVol\n",
  379. ((CHAR8*)&CurrentTable->Signature)[0], ((CHAR8*)&CurrentTable->Signature)[1],
  380. ((CHAR8*)&CurrentTable->Signature)[2], ((CHAR8*)&CurrentTable->Signature)[3]));
  381. //
  382. // Check if table should be processed or will be updated later
  383. //
  384. if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE
  385. && CurrentTable->Signature != NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE
  386. ) {
  387. //
  388. // Allow platform specific code to reject the table or update it
  389. //
  390. AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable); //SystemBoard);
  391. if (!EFI_ERROR (AcpiStatus)) {
  392. //
  393. // Perform any table specific updates.
  394. //
  395. AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
  396. if (!EFI_ERROR (AcpiStatus)) {
  397. //
  398. // Add the table
  399. //
  400. if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
  401. //
  402. // Install the table
  403. //
  404. AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
  405. if (!EFI_ERROR (AcpiStatus)) {
  406. ASSERT_EFI_ERROR (AcpiStatus);
  407. return AcpiStatus;
  408. }
  409. }
  410. }
  411. }
  412. }
  413. //
  414. // Increment the instance
  415. //
  416. Instance++;
  417. }
  418. }
  419. //
  420. // Build any from-scratch ACPI tables. Halt on errors for debug builds, but
  421. // for release builds it is safe to continue.
  422. //
  423. Status = PlatformBuildTables ();
  424. ASSERT_EFI_ERROR (Status);
  425. return EFI_SUCCESS;
  426. }
  427. /**
  428. Installs ACPI Platform tables that wasn't installed in the early phase
  429. @param None
  430. @retval EFI_SUCCESS - Operation completed successfully.
  431. **/
  432. STATIC
  433. EFI_STATUS
  434. EFIAPI
  435. AcpiPlatformLateAcpiTablesInstall (
  436. VOID
  437. )
  438. {
  439. //
  440. // Install xHCI ACPI Table
  441. //
  442. InstallXhciAcpiTable ();
  443. return EFI_SUCCESS;
  444. }
  445. /**
  446. Installs ACPI PmSsdt tables
  447. @param None
  448. @retval EFI_SUCCESS - Operation completed successfully.
  449. **/
  450. STATIC
  451. EFI_STATUS
  452. EFIAPI
  453. PmSsdtEarlyAcpiTablesInstall (
  454. VOID
  455. )
  456. {
  457. EFI_STATUS Status;
  458. EFI_STATUS AcpiStatus;
  459. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  460. EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  461. INTN Instance = 0;
  462. EFI_ACPI_COMMON_HEADER *CurrentTable;
  463. EFI_ACPI_TABLE_VERSION TableVersion;
  464. UINTN TableHandle;
  465. UINT32 FvStatus;
  466. UINT32 Size;
  467. //
  468. // Find the AcpiTable protocol
  469. //
  470. Status = LocateSupportProtocol (
  471. &gEfiAcpiTableProtocolGuid,
  472. gEfiPmSsdtTableStorageGuid,
  473. (VOID **) &AcpiTable,
  474. FALSE
  475. );
  476. ASSERT_EFI_ERROR (Status);
  477. //
  478. // Locate the firmware volume protocol
  479. //
  480. Status = LocateSupportProtocol (
  481. &gEfiFirmwareVolume2ProtocolGuid,
  482. gEfiPmSsdtTableStorageGuid,
  483. (VOID **) &FwVol,
  484. TRUE
  485. );
  486. ASSERT_EFI_ERROR (Status);
  487. //
  488. // Read tables from the storage file.
  489. //
  490. while (!EFI_ERROR (Status)) {
  491. CurrentTable = NULL;
  492. TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
  493. TableHandle = 0;
  494. Status = FwVol->ReadSection (
  495. FwVol,
  496. &gEfiPmSsdtTableStorageGuid,
  497. EFI_SECTION_RAW,
  498. Instance,
  499. (VOID **) &CurrentTable,
  500. (UINTN *) &Size,
  501. &FvStatus
  502. );
  503. if (!EFI_ERROR (Status)) {
  504. //
  505. // Check if table should be processed or will be updated later
  506. //
  507. if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
  508. //
  509. // Allow platform specific code to reject the table or update it
  510. //
  511. AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
  512. if (!EFI_ERROR (AcpiStatus)) {
  513. //
  514. // Perform any table specific updates.
  515. //
  516. AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
  517. if (!EFI_ERROR (AcpiStatus)) {
  518. //
  519. // Add the table
  520. //
  521. if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
  522. //
  523. // Install the table
  524. //
  525. AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
  526. if (!EFI_ERROR (AcpiStatus)) {
  527. ASSERT_EFI_ERROR (AcpiStatus);
  528. return AcpiStatus;
  529. }
  530. }
  531. }
  532. }
  533. }
  534. //
  535. // Increment the instance
  536. //
  537. Instance++;
  538. }
  539. }
  540. return EFI_SUCCESS;
  541. } // PmSsdtEarlyAcpiTablesInstall()
  542. /**
  543. Entry point for Acpi platform driver.
  544. @param ImageHandle - A handle for the image that is initializing this driver.
  545. @param SystemTable - A pointer to the EFI system table.
  546. @retval EFI_SUCCESS - Driver initialized successfully.
  547. @retval EFI_LOAD_ERROR - Failed to Initialize or has been loaded.
  548. @retval EFI_OUT_OF_RESOURCES - Could not allocate needed resources.
  549. **/
  550. EFI_STATUS
  551. EFIAPI
  552. AcpiPlatformEntryPoint (
  553. IN EFI_HANDLE ImageHandle,
  554. IN EFI_SYSTEM_TABLE *SystemTable
  555. )
  556. {
  557. EFI_STATUS Status;
  558. EFI_EVENT Event;
  559. VOID *HobList;
  560. VOID *RgstPtr;
  561. DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
  562. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
  563. if (EFI_ERROR (Status)) {
  564. ASSERT_EFI_ERROR (Status);
  565. return Status;
  566. }
  567. mFirstNotify = FALSE;
  568. //
  569. // Report Status Code to indicate Acpi Init
  570. //
  571. REPORT_STATUS_CODE (
  572. EFI_PROGRESS_CODE,
  573. (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_BS_ACPI_INIT)
  574. );
  575. Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, (VOID **) &mIioUds2);
  576. if (EFI_ERROR (Status)) {
  577. ASSERT_EFI_ERROR (Status);
  578. return Status;
  579. }
  580. mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
  581. //
  582. // Update HOB variable for PCI resource information
  583. // Get the HOB list. If it is not present, then ASSERT.
  584. //
  585. Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
  586. ASSERT_EFI_ERROR (Status);
  587. //
  588. // Initialize Platform Hooks
  589. //
  590. PlatformHookInit ();
  591. //
  592. // Install ACPI PLatform Tables
  593. //
  594. Status = AcpiPlatformEarlyAcpiTablesInstall ();
  595. ASSERT_EFI_ERROR (Status);
  596. //
  597. // Install ACPI PMSsdt Tables
  598. //
  599. Status = PmSsdtEarlyAcpiTablesInstall ();
  600. ASSERT_EFI_ERROR (Status);
  601. //
  602. // Install ACPI PLatform Tables that wasn't installed yet (NFIT/xHCI)
  603. //
  604. Status = AcpiPlatformLateAcpiTablesInstall ();
  605. ASSERT_EFI_ERROR (Status);
  606. //
  607. // Register ready to boot event handler
  608. //
  609. Status = EfiCreateEventReadyToBootEx (TPL_NOTIFY, AcpiOnReadyToBootCallback, NULL, &Event);
  610. ASSERT_EFI_ERROR (Status);
  611. //
  612. // Create PCI Enumeration Completed callback.
  613. //
  614. Event = EfiCreateProtocolNotifyEvent (&gEfiPciEnumerationCompleteProtocolGuid, TPL_CALLBACK,
  615. AcpiOnPciEnumCmplCallback, NULL, &RgstPtr);
  616. ASSERT (Event != NULL);
  617. //
  618. // Register EndOfDxe handler
  619. //
  620. Status = gBS->CreateEventEx (
  621. EVT_NOTIFY_SIGNAL,
  622. TPL_CALLBACK,
  623. AcpiOnEndOfDxeCallback,
  624. NULL,
  625. &gEfiEndOfDxeEventGroupGuid,
  626. &Event
  627. );
  628. ASSERT_EFI_ERROR (Status);
  629. //
  630. // Register ExitBootServicesEvent handler
  631. //
  632. Status = gBS->CreateEventEx (
  633. EVT_NOTIFY_SIGNAL,
  634. TPL_CALLBACK,
  635. AcpiOnExitBootServicesCallback,
  636. NULL,
  637. &gEfiEventExitBootServicesGuid,
  638. &Event
  639. );
  640. ASSERT_EFI_ERROR (Status);
  641. return EFI_SUCCESS;
  642. } // AcpiPlatformEntryPoint()