SmmSiliconAcpiEnableLib.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /** @file
  2. Kaby Lake RVP 3 SMM Silicon ACPI Enable library
  3. Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Base.h>
  7. #include <PiDxe.h>
  8. #include <Library/BaseLib.h>
  9. #include <Library/IoLib.h>
  10. #include <Library/PcdLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <PchAccess.h>
  13. #include <Library/MmPciLib.h>
  14. #include <Library/PchCycleDecodingLib.h>
  15. /**
  16. Clear Port 80h
  17. SMI handler to enable ACPI mode
  18. Dispatched on reads from APM port with value EFI_ACPI_ENABLE_SW_SMI
  19. Disables the SW SMI Timer.
  20. ACPI events are disabled and ACPI event status is cleared.
  21. SCI mode is then enabled.
  22. Clear SLP SMI status
  23. Enable SLP SMI
  24. Disable SW SMI Timer
  25. Clear all ACPI event status and disable all ACPI events
  26. Disable PM sources except power button
  27. Clear status bits
  28. Disable GPE0 sources
  29. Clear status bits
  30. Disable GPE1 sources
  31. Clear status bits
  32. Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
  33. Enable SCI
  34. **/
  35. EFI_STATUS
  36. EFIAPI
  37. SiliconEnableAcpi (
  38. IN BOOLEAN EnableSci
  39. )
  40. {
  41. UINT32 OutputValue;
  42. UINT32 SmiEn;
  43. UINT32 SmiSts;
  44. UINT32 ULKMC;
  45. UINTN LpcBaseAddress;
  46. UINT16 AcpiBaseAddr;
  47. UINT32 Pm1Cnt;
  48. LpcBaseAddress = MmPciBase (
  49. DEFAULT_PCI_BUS_NUMBER_PCH,
  50. PCI_DEVICE_NUMBER_PCH_LPC,
  51. PCI_FUNCTION_NUMBER_PCH_LPC
  52. );
  53. //
  54. // Get the ACPI Base Address
  55. //
  56. PchAcpiBaseGet (&AcpiBaseAddr);
  57. //
  58. // BIOS must also ensure that CF9GR is cleared and locked before handing control to the
  59. // OS in order to prevent the host from issuing global resets and resetting ME
  60. //
  61. // EDK2: To match PCCG current BIOS behavior, do not lock CF9 Global Reset
  62. // MmioWrite32 (
  63. // PmcBaseAddress + R_PCH_PMC_ETR3),
  64. // PmInit);
  65. //
  66. // Clear Port 80h
  67. //
  68. IoWrite8 (0x80, 0);
  69. //
  70. // Disable SW SMI Timer and clean the status
  71. //
  72. SmiEn = IoRead32 (AcpiBaseAddr + R_PCH_SMI_EN);
  73. SmiEn &= ~(B_PCH_SMI_EN_LEGACY_USB2 | B_PCH_SMI_EN_SWSMI_TMR | B_PCH_SMI_EN_LEGACY_USB);
  74. IoWrite32 (AcpiBaseAddr + R_PCH_SMI_EN, SmiEn);
  75. SmiSts = IoRead32 (AcpiBaseAddr + R_PCH_SMI_STS);
  76. SmiSts |= B_PCH_SMI_EN_LEGACY_USB2 | B_PCH_SMI_EN_SWSMI_TMR | B_PCH_SMI_EN_LEGACY_USB;
  77. IoWrite32 (AcpiBaseAddr + R_PCH_SMI_STS, SmiSts);
  78. //
  79. // Disable port 60/64 SMI trap if they are enabled
  80. //
  81. ULKMC = MmioRead32 (LpcBaseAddress + R_PCH_LPC_ULKMC) & ~(B_PCH_LPC_ULKMC_60REN | B_PCH_LPC_ULKMC_60WEN | B_PCH_LPC_ULKMC_64REN | B_PCH_LPC_ULKMC_64WEN | B_PCH_LPC_ULKMC_A20PASSEN);
  82. MmioWrite32 (LpcBaseAddress + R_PCH_LPC_ULKMC, ULKMC);
  83. //
  84. // Disable PM sources except power button
  85. //
  86. IoWrite16 (AcpiBaseAddr + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
  87. //
  88. // Clear PM status except Power Button status for RapidStart Resume
  89. //
  90. IoWrite16 (AcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xFEFF);
  91. //
  92. // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
  93. //
  94. IoWrite8 (R_PCH_RTC_INDEX_ALT, R_PCH_RTC_REGD);
  95. IoWrite8 (R_PCH_RTC_TARGET_ALT, 0x0);
  96. //
  97. // Write ALT_GPI_SMI_EN to disable GPI1 (SMC_EXTSMI#)
  98. //
  99. OutputValue = IoRead32 (AcpiBaseAddr + 0x38);
  100. OutputValue = OutputValue & ~(1 << (UINTN) PcdGet8 (PcdSmcExtSmiBitPosition));
  101. IoWrite32 (AcpiBaseAddr + 0x38, OutputValue);
  102. //
  103. // Enable SCI
  104. //
  105. if (EnableSci) {
  106. Pm1Cnt = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
  107. Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
  108. IoWrite32 (AcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
  109. }
  110. return EFI_SUCCESS;
  111. }
  112. EFI_STATUS
  113. EFIAPI
  114. SiliconDisableAcpi (
  115. IN BOOLEAN DisableSci
  116. )
  117. {
  118. UINT16 AcpiBaseAddr;
  119. UINT32 Pm1Cnt;
  120. //
  121. // Get the ACPI Base Address
  122. //
  123. PchAcpiBaseGet (&AcpiBaseAddr);
  124. //
  125. // Disable SCI
  126. //
  127. if (DisableSci) {
  128. Pm1Cnt = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
  129. Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN;
  130. IoWrite32 (AcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
  131. }
  132. return EFI_SUCCESS;
  133. }