summaryrefslogtreecommitdiff
path: root/Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c')
-rw-r--r--Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c b/Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c
new file mode 100644
index 0000000000..7b3c894700
--- /dev/null
+++ b/Silicon/Intel/LewisburgPkg/LibraryPrivate/BasePchResetCommonLib/PchResetCommon.c
@@ -0,0 +1,174 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/MmPciBaseLib.h>
+#include <IncludePrivate/Library/PchResetCommonLib.h>
+
+
+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;
+}