/** @file
|
Source code file for Platform Init PEI module
|
|
Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Uefi.h>
|
#include <PiPei.h>
|
#include <CpuRegs.h>
|
#include <PchAccess.h>
|
#include <Library/IoLib.h>
|
#include <Library/HobLib.h>
|
#include <Library/PcdLib.h>
|
#include <Library/DebugLib.h>
|
#include <Library/PchInfoLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <Library/PeiServicesLib.h>
|
#include <Library/MmPciLib.h>
|
#include <IndustryStandard/Pci30.h>
|
#include <Library/PchCycleDecodingLib.h>
|
#include <Library/GpioLib.h>
|
#include <Ppi/EndOfPeiPhase.h>
|
#include <Guid/SmramMemoryReserve.h>
|
#include <Library/ConfigBlockLib.h>
|
#include <Ppi/SiPolicy.h>
|
#include <SaPolicyCommon.h>
|
|
#include <Guid/FirmwareFileSystem2.h>
|
|
#include <GpioPinsSklLp.h>
|
#include <Library/TimerLib.h>
|
|
/**
|
Clear any SMI status or wake status left from boot.
|
|
@retval EFI_SUCCESS The function completed successfully.
|
**/
|
EFI_STATUS
|
ClearIchSmiAndWake (
|
VOID
|
)
|
{
|
EFI_STATUS Status;
|
EFI_BOOT_MODE BootMode;
|
UINT16 ABase;
|
UINT16 Pm1Sts;
|
UINT32 Pm1Cnt;
|
UINT32 Data32;
|
UINT32 Gpe0Sts;
|
UINT32 SmiSts;
|
UINT16 DevActSts;
|
UINT16 TcoBase;
|
UINT16 Tco1Sts;
|
UINT16 LpcDeviceId;
|
UINTN LanBaseAddress;
|
UINT16 LanPmcs;
|
|
Status = PeiServicesGetBootMode (&BootMode);
|
ASSERT_EFI_ERROR (Status);
|
if (BootMode == BOOT_ON_S3_RESUME) {
|
return EFI_SUCCESS;
|
}
|
|
PchAcpiBaseGet (&ABase);
|
|
PchTcoBaseGet (&TcoBase);
|
|
//
|
// Read the ACPI registers
|
//
|
Pm1Sts = IoRead16 (ABase + R_PCH_ACPI_PM1_STS);
|
Pm1Cnt = IoRead32 (ABase + R_PCH_ACPI_PM1_CNT);
|
|
Gpe0Sts = IoRead32 (ABase + R_PCH_ACPI_GPE0_STS_127_96);
|
SmiSts = IoRead32 (ABase + R_PCH_SMI_STS);
|
|
Data32 = 0;
|
//
|
// Before clear B_PCH_ACPI_GPE0_STS_127_96_PME_B0, PMES bit of internal device must be cleared at first.
|
//
|
Data32 = (Gpe0Sts & B_PCH_ACPI_GPE0_STS_127_96_PME_B0);
|
if (Data32 != 0) {
|
//
|
// Check if Internal LAN waked up system
|
//
|
LanBaseAddress = MmPciBase (
|
DEFAULT_PCI_BUS_NUMBER_PCH,
|
PCI_DEVICE_NUMBER_PCH_LAN,
|
PCI_FUNCTION_NUMBER_PCH_LAN
|
);
|
LanPmcs = MmioRead16 (LanBaseAddress + R_PCH_LAN_PMCS);
|
if ((LanPmcs & B_PCH_LAN_PMCS_PMES) != 0) {
|
//
|
// Clear PMES bit
|
//
|
MmioOr16 (LanBaseAddress + R_PCH_LAN_PMCS, B_PCH_LAN_PMCS_PMES);
|
DEBUG ((DEBUG_INFO, "Clear LAN PMES bit!\n"));
|
}
|
}
|
|
LpcDeviceId = GetLpcDid ();
|
//
|
// Clear any SMI or wake state from the boot
|
//
|
Pm1Sts |=
|
(
|
B_PCH_ACPI_PM1_STS_WAK |
|
B_PCH_ACPI_PM1_STS_PRBTNOR |
|
B_PCH_ACPI_PM1_STS_RTC |
|
B_PCH_ACPI_PM1_STS_PWRBTN |
|
B_PCH_ACPI_PM1_STS_GBL |
|
B_PCH_ACPI_PM1_STS_TMROF
|
);
|
|
Gpe0Sts |=
|
(
|
B_PCH_ACPI_GPE0_STS_127_96_PME_B0 |
|
B_PCH_ACPI_GPE0_STS_127_96_PME |
|
B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP |
|
B_PCH_ACPI_GPE0_STS_127_96_RI |
|
B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK |
|
B_PCH_ACPI_GPE0_STS_127_96_TC0SCI |
|
B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG |
|
B_PCH_ACPI_GPE0_STS_127_96_LAN_WAKE
|
);
|
|
//
|
// PCH Desktop
|
//
|
if (IS_PCH_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
|
Gpe0Sts |= B_PCH_ACPI_GPE0_STS_127_96_BATLOW;
|
}
|
|
SmiSts |=
|
(
|
B_PCH_SMI_STS_SMBUS |
|
B_PCH_SMI_STS_PERIODIC |
|
B_PCH_SMI_STS_TCO |
|
B_PCH_SMI_STS_MCSMI |
|
B_PCH_SMI_STS_SWSMI_TMR |
|
B_PCH_SMI_STS_APM |
|
B_PCH_SMI_STS_ON_SLP_EN |
|
B_PCH_SMI_STS_BIOS
|
);
|
//
|
// Write them back
|
//
|
IoWrite16 (ABase + R_PCH_ACPI_PM1_STS, Pm1Sts);
|
IoWrite32 (ABase + R_PCH_ACPI_GPE0_STS_127_96, Gpe0Sts);
|
IoWrite32 (ABase + R_PCH_SMI_STS, SmiSts);
|
|
DevActSts = IoRead16 (ABase + R_PCH_DEVACT_STS);
|
Tco1Sts = IoRead16 (TcoBase + R_PCH_TCO1_STS);
|
|
DevActSts |=
|
(
|
B_PCH_DEVACT_STS_KBC |
|
B_PCH_DEVACT_STS_PIRQDH |
|
B_PCH_DEVACT_STS_PIRQCG |
|
B_PCH_DEVACT_STS_PIRQBF |
|
B_PCH_DEVACT_STS_PIRQAE
|
);
|
Tco1Sts |=
|
(
|
B_PCH_TCO1_STS_DMISERR |
|
B_PCH_TCO1_STS_DMISMI |
|
B_PCH_TCO1_STS_DMISCI |
|
B_PCH_TCO1_STS_BIOSWR |
|
B_PCH_TCO1_STS_NEWCENTURY |
|
B_PCH_TCO1_STS_TIMEOUT |
|
B_PCH_TCO1_STS_TCO_INT |
|
B_PCH_TCO1_STS_SW_TCO_SMI
|
);
|
|
//
|
// clear GPI SMI STS
|
//
|
GpioClearAllGpiSmiSts ();
|
|
IoWrite16 (TcoBase + R_PCH_TCO1_STS, Tco1Sts);
|
|
//
|
// We do not want to write 1 to clear INTRD_DET bit.
|
//
|
IoWrite16 ((UINTN) (TcoBase + R_PCH_TCO2_STS), (UINT16) ~B_PCH_TCO2_STS_INTRD_DET);
|
|
IoWrite16 (ABase + R_PCH_DEVACT_STS, DevActSts);
|
|
//
|
// Clear Power Failure (PWR_FLR), It was used to check S3_Resume State.
|
//
|
// MmioOr8 (
|
// LpcBaseAddress + R_PCH_PMC_GEN_PMCON_B,
|
// B_PCH_PMC_GEN_PMCON_B_PWR_FLR
|
// );
|
|
return EFI_SUCCESS;
|
}
|
|
/**
|
Late Silicon Initialization
|
**/
|
VOID
|
LateSiliconInit (
|
VOID
|
)
|
{
|
ClearIchSmiAndWake ();
|
}
|
|