/** @file Copyright (c) 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include EFI_STATUS EFIAPI PchResetCallback ( IN PCH_RESET_TYPE PchResetType ); /** Initialize an Pch Reset ppi/protocol instance. @param[in] PchResetInstance Pointer to PchResetInstance to initialize @retval EFI_SUCCESS The protocol instance was properly initialized @exception EFI_UNSUPPORTED The PCH is not supported by this module **/ EFI_STATUS PchResetConstructor ( PCH_RESET_INSTANCE *PchResetInstance ) { UINTN PmcBaseAddress; /// /// Initialize the Reset protocol instance /// PchResetInstance->Signature = PCH_RESET_SIGNATURE; PchResetInstance->Handle = NULL; /// /// Sanity check to ensure PMC ACPI/PM BASE initialization has occurred previously. /// PmcBaseAddress = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PMC, PCI_FUNCTION_NUMBER_PCH_PMC ); PchResetInstance->PchPmcBase = PmcBaseAddress; PchPwrmBaseGet (&(PchResetInstance->PchPwrmBase)); ASSERT (PchResetInstance->PchPwrmBase != 0); PchAcpiBaseGet (&(PchResetInstance->PchAcpiBase)); ASSERT (PchResetInstance->PchAcpiBase != 0); return EFI_SUCCESS; } /** Execute Pch Reset from the host controller. @param[in] PchResetInstance Pointer to PchResetInstance to initialize @param[in] PchResetType Pch Reset Types which includes ColdReset, WarmReset, ShutdownReset, PowerCycleReset, GlobalReset, GlobalResetWithEc @retval EFI_SUCCESS Successfully completed. @retval EFI_INVALID_PARAMETER If ResetType is invalid. **/ EFI_STATUS PchReset ( IN PCH_RESET_INSTANCE *PchResetInstance, IN PCH_RESET_TYPE PchResetType ) { UINTN PmcBaseAddress; UINT16 ABase; UINT8 OutputData; UINT32 Data32; UINT16 Data16; EFI_STATUS Status; PmcBaseAddress = PchResetInstance->PchPmcBase; ABase = PchResetInstance->PchAcpiBase; switch (PchResetType) { case ColdReset: IoWrite8 ((UINTN) R_PCH_RST_CNT, (UINT8) V_PCH_RST_CNT_HARDSTARTSTATE); OutputData = V_PCH_RST_CNT_FULLRESET; break; case WarmReset: IoWrite8 ((UINTN) R_PCH_RST_CNT, (UINT8) V_PCH_RST_CNT_SOFTSTARTSTATE); OutputData = V_PCH_RST_CNT_HARDRESET; break; case ShutdownReset: /// /// Firstly, ACPI decode must be enabled /// MmioOr8 ( PmcBaseAddress + R_PCH_PMC_ACPI_CNT, (UINT8) (B_PCH_PMC_ACPI_CNT_ACPI_EN) ); /// /// Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5 /// IoWrite32 ((UINTN) (ABase + R_PCH_ACPI_GPE0_EN_127_96), 0); /// /// Secondly, PwrSts register must be cleared /// /// Write a "1" to bit[8] of power button status register at /// (PM_BASE + PM1_STS_OFFSET) to clear this bit /// Data16 = B_PCH_SMI_STS_PM1_STS_REG; IoWrite16 ((UINTN) (ABase + R_PCH_SMI_STS), Data16); /// /// Finally, transform system into S5 sleep state /// Data32 = IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_CNT)); Data32 = (UINT32) ((Data32 &~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S5); IoWrite32 ((UINTN) (ABase + R_PCH_ACPI_PM1_CNT), Data32); Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN; IoWrite32 ((UINTN) (ABase + R_PCH_ACPI_PM1_CNT), Data32); return EFI_SUCCESS; case PowerCycleReset: case GlobalReset: case GlobalResetWithEc: /// /// PCH BIOS Spec Section 4.6 GPIO Reset Requirement /// if ((PchResetType == GlobalReset) || (PchResetType == GlobalResetWithEc)) { MmioOr32 ( PmcBaseAddress + R_PCH_PMC_ETR3, (UINT32) (B_PCH_PMC_ETR3_CF9GR) ); } OutputData = V_PCH_RST_CNT_FULLRESET; break; default: return EFI_INVALID_PARAMETER; } DEBUG ((DEBUG_ERROR, "Resetting the platform (%02x)...\n", OutputData)); Status = PchResetCallback (PchResetType); if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) { IoWrite8 ((UINTN) R_PCH_RST_CNT, OutputData); /// /// Waiting for system reset /// CpuDeadLoop (); } return Status; }