SmmSiliconAcpiEnableLib.c 4.4 KB

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