AcpiPlatform.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  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, &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, &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. &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. BOOLEAN Installed;
  334. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  335. EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  336. INTN Instance = 0;
  337. EFI_ACPI_COMMON_HEADER *CurrentTable;
  338. EFI_ACPI_TABLE_VERSION TableVersion;
  339. UINTN TableHandle;
  340. UINT32 FvStatus;
  341. UINT32 Size;
  342. //
  343. // Find the AcpiTable protocol
  344. //
  345. Status = LocateSupportProtocol (
  346. &gEfiAcpiTableProtocolGuid,
  347. gEfiAcpiTableStorageGuid,
  348. &AcpiTable,
  349. FALSE
  350. );
  351. ASSERT_EFI_ERROR (Status);
  352. //
  353. // Locate the firmware volume protocol
  354. //
  355. Status = LocateSupportProtocol (
  356. &gEfiFirmwareVolume2ProtocolGuid,
  357. gEfiAcpiTableStorageGuid,
  358. &FwVol,
  359. TRUE
  360. );
  361. ASSERT_EFI_ERROR (Status);
  362. //
  363. // Read tables from the storage file.
  364. //
  365. while (!EFI_ERROR (Status)) {
  366. CurrentTable = NULL;
  367. TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
  368. TableHandle = 0;
  369. Installed = FALSE;
  370. Status = FwVol->ReadSection (
  371. FwVol,
  372. &gEfiAcpiTableStorageGuid,
  373. EFI_SECTION_RAW,
  374. Instance,
  375. &CurrentTable,
  376. (UINTN *) &Size,
  377. &FvStatus
  378. );
  379. if (!EFI_ERROR (Status)) {
  380. DEBUG ((DEBUG_INFO, "[ACPI] Table '%c%c%c%c' found in FwVol\n",
  381. ((CHAR8*)&CurrentTable->Signature)[0], ((CHAR8*)&CurrentTable->Signature)[1],
  382. ((CHAR8*)&CurrentTable->Signature)[2], ((CHAR8*)&CurrentTable->Signature)[3]));
  383. //
  384. // Check if table should be processed or will be updated later
  385. //
  386. if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE
  387. && CurrentTable->Signature != NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE
  388. ) {
  389. //
  390. // Allow platform specific code to reject the table or update it
  391. //
  392. AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable); //SystemBoard);
  393. if (!EFI_ERROR (AcpiStatus)) {
  394. //
  395. // Perform any table specific updates.
  396. //
  397. AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
  398. if (!EFI_ERROR (AcpiStatus)) {
  399. //
  400. // Add the table
  401. //
  402. if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
  403. //
  404. // Install the table
  405. //
  406. AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
  407. if (!EFI_ERROR (AcpiStatus)) {
  408. Installed = TRUE;
  409. }
  410. ASSERT_EFI_ERROR (AcpiStatus);
  411. }
  412. }
  413. }
  414. }
  415. //
  416. // Increment the instance
  417. //
  418. Instance++;
  419. }
  420. }
  421. //
  422. // Build any from-scratch ACPI tables. Halt on errors for debug builds, but
  423. // for release builds it is safe to continue.
  424. //
  425. Status = PlatformBuildTables ();
  426. ASSERT_EFI_ERROR (Status);
  427. return EFI_SUCCESS;
  428. }
  429. /**
  430. Installs ACPI Platform tables that wasn't installed in the early phase
  431. @param None
  432. @retval EFI_SUCCESS - Operation completed successfully.
  433. **/
  434. STATIC
  435. EFI_STATUS
  436. EFIAPI
  437. AcpiPlatformLateAcpiTablesInstall (
  438. VOID
  439. )
  440. {
  441. //
  442. // Install xHCI ACPI Table
  443. //
  444. InstallXhciAcpiTable ();
  445. return EFI_SUCCESS;
  446. }
  447. /**
  448. Installs ACPI PmSsdt tables
  449. @param None
  450. @retval EFI_SUCCESS - Operation completed successfully.
  451. **/
  452. STATIC
  453. EFI_STATUS
  454. EFIAPI
  455. PmSsdtEarlyAcpiTablesInstall (
  456. VOID
  457. )
  458. {
  459. EFI_STATUS Status;
  460. EFI_STATUS AcpiStatus;
  461. BOOLEAN Installed;
  462. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  463. EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  464. INTN Instance = 0;
  465. EFI_ACPI_COMMON_HEADER *CurrentTable;
  466. EFI_ACPI_TABLE_VERSION TableVersion;
  467. UINTN TableHandle;
  468. UINT32 FvStatus;
  469. UINT32 Size;
  470. //
  471. // Find the AcpiTable protocol
  472. //
  473. Status = LocateSupportProtocol (
  474. &gEfiAcpiTableProtocolGuid,
  475. gEfiPmSsdtTableStorageGuid,
  476. &AcpiTable,
  477. FALSE
  478. );
  479. ASSERT_EFI_ERROR (Status);
  480. //
  481. // Locate the firmware volume protocol
  482. //
  483. Status = LocateSupportProtocol (
  484. &gEfiFirmwareVolume2ProtocolGuid,
  485. gEfiPmSsdtTableStorageGuid,
  486. &FwVol,
  487. TRUE
  488. );
  489. ASSERT_EFI_ERROR (Status);
  490. //
  491. // Read tables from the storage file.
  492. //
  493. while (!EFI_ERROR (Status)) {
  494. CurrentTable = NULL;
  495. TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
  496. TableHandle = 0;
  497. Installed = FALSE;
  498. Status = FwVol->ReadSection (
  499. FwVol,
  500. &gEfiPmSsdtTableStorageGuid,
  501. EFI_SECTION_RAW,
  502. Instance,
  503. &CurrentTable,
  504. (UINTN *) &Size,
  505. &FvStatus
  506. );
  507. if (!EFI_ERROR (Status)) {
  508. //
  509. // Check if table should be processed or will be updated later
  510. //
  511. if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
  512. //
  513. // Allow platform specific code to reject the table or update it
  514. //
  515. AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
  516. if (!EFI_ERROR (AcpiStatus)) {
  517. //
  518. // Perform any table specific updates.
  519. //
  520. AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
  521. if (!EFI_ERROR (AcpiStatus)) {
  522. //
  523. // Add the table
  524. //
  525. if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
  526. //
  527. // Install the table
  528. //
  529. AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
  530. if (!EFI_ERROR (AcpiStatus)) {
  531. Installed = TRUE;
  532. }
  533. ASSERT_EFI_ERROR (AcpiStatus);
  534. }
  535. }
  536. }
  537. }
  538. //
  539. // Increment the instance
  540. //
  541. Instance++;
  542. }
  543. }
  544. return EFI_SUCCESS;
  545. } // PmSsdtEarlyAcpiTablesInstall()
  546. /**
  547. Entry point for Acpi platform driver.
  548. @param ImageHandle - A handle for the image that is initializing this driver.
  549. @param SystemTable - A pointer to the EFI system table.
  550. @retval EFI_SUCCESS - Driver initialized successfully.
  551. @retval EFI_LOAD_ERROR - Failed to Initialize or has been loaded.
  552. @retval EFI_OUT_OF_RESOURCES - Could not allocate needed resources.
  553. **/
  554. EFI_STATUS
  555. EFIAPI
  556. AcpiPlatformEntryPoint (
  557. IN EFI_HANDLE ImageHandle,
  558. IN EFI_SYSTEM_TABLE *SystemTable
  559. )
  560. {
  561. EFI_STATUS Status;
  562. EFI_EVENT Event;
  563. VOID *HobList;
  564. VOID *RgstPtr;
  565. DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
  566. Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
  567. if (EFI_ERROR (Status)) {
  568. ASSERT_EFI_ERROR (Status);
  569. return Status;
  570. }
  571. mFirstNotify = FALSE;
  572. //
  573. // Report Status Code to indicate Acpi Init
  574. //
  575. REPORT_STATUS_CODE (
  576. EFI_PROGRESS_CODE,
  577. (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_BS_ACPI_INIT)
  578. );
  579. Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, &mIioUds2);
  580. if (EFI_ERROR (Status)) {
  581. ASSERT_EFI_ERROR (Status);
  582. return Status;
  583. }
  584. mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
  585. //
  586. // Update HOB variable for PCI resource information
  587. // Get the HOB list. If it is not present, then ASSERT.
  588. //
  589. Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
  590. ASSERT_EFI_ERROR (Status);
  591. //
  592. // Initialize Platform Hooks
  593. //
  594. PlatformHookInit ();
  595. //
  596. // Install ACPI PLatform Tables
  597. //
  598. Status = AcpiPlatformEarlyAcpiTablesInstall ();
  599. ASSERT_EFI_ERROR (Status);
  600. //
  601. // Install ACPI PMSsdt Tables
  602. //
  603. Status = PmSsdtEarlyAcpiTablesInstall ();
  604. ASSERT_EFI_ERROR (Status);
  605. //
  606. // Install ACPI PLatform Tables that wasn't installed yet (NFIT/xHCI)
  607. //
  608. Status = AcpiPlatformLateAcpiTablesInstall ();
  609. ASSERT_EFI_ERROR (Status);
  610. //
  611. // Register ready to boot event handler
  612. //
  613. Status = EfiCreateEventReadyToBootEx (TPL_NOTIFY, AcpiOnReadyToBootCallback, NULL, &Event);
  614. ASSERT_EFI_ERROR (Status);
  615. //
  616. // Create PCI Enumeration Completed callback.
  617. //
  618. Event = EfiCreateProtocolNotifyEvent (&gEfiPciEnumerationCompleteProtocolGuid, TPL_CALLBACK,
  619. AcpiOnPciEnumCmplCallback, NULL, &RgstPtr);
  620. ASSERT (Event != NULL);
  621. //
  622. // Register EndOfDxe handler
  623. //
  624. Status = gBS->CreateEventEx (
  625. EVT_NOTIFY_SIGNAL,
  626. TPL_CALLBACK,
  627. AcpiOnEndOfDxeCallback,
  628. NULL,
  629. &gEfiEndOfDxeEventGroupGuid,
  630. &Event
  631. );
  632. ASSERT_EFI_ERROR (Status);
  633. //
  634. // Register ExitBootServicesEvent handler
  635. //
  636. Status = gBS->CreateEventEx (
  637. EVT_NOTIFY_SIGNAL,
  638. TPL_CALLBACK,
  639. AcpiOnExitBootServicesCallback,
  640. NULL,
  641. &gEfiEventExitBootServicesGuid,
  642. &Event
  643. );
  644. ASSERT_EFI_ERROR (Status);
  645. return EFI_SUCCESS;
  646. } // AcpiPlatformEntryPoint()