From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: michael.a.kubacki@intel.com) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by groups.io with SMTP; Fri, 16 Aug 2019 17:16:53 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:16:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="182319283" Received: from makuback-desk1.amr.corp.intel.com ([10.7.159.162]) by orsmga006.jf.intel.com with ESMTP; 16 Aug 2019 17:16:52 -0700 From: "Kubacki, Michael A" To: devel@edk2.groups.io Cc: Sai Chaganty , Chasel Chiu , Nate DeSimone , Liming Gao , Michael D Kinney , Ankit Sinha Subject: [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE library instances Date: Fri, 16 Aug 2019 17:15:44 -0700 Message-Id: <20190817001603.30632-19-michael.a.kubacki@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20190817001603.30632-1-michael.a.kubacki@intel.com> References: <20190817001603.30632-1-michael.a.kubacki@intel.com> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082 Adds PCH DXE library class instances. * DxePchPolicyLib * DxeResetSystemLib * DxeRuntimeResetSystemLib Cc: Sai Chaganty Cc: Chasel Chiu Cc: Nate DeSimone Cc: Liming Gao Cc: Michael D Kinney Cc: Ankit Sinha Signed-off-by: Michael Kubacki --- Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf | 41 +++ Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf | 49 +++ Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf | 52 ++++ Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c | 218 +++++++++++++ Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c | 310 +++++++++++++++++++ Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c | 323 ++++++++++++++++++++ 6 files changed, 993 insertions(+) diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf new file mode 100644 index 0000000000..8845ab796c --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf @@ -0,0 +1,41 @@ +## @file +# Component description file for the PeiPchPolicy library. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = DxePchPolicyLib +FILE_GUID = E2179D04-7026-48A5-9475-309CEA2F21A3 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = DxePchPolicyLib + + +[LibraryClasses] +BaseMemoryLib +UefiBootServicesTableLib +DebugLib +ConfigBlockLib +SiConfigBlockLib +PchInfoLib + + +[Packages] +MdePkg/MdePkg.dec +CoffeelakeSiliconPkg/SiPkg.dec + +[Sources] +DxePchPolicyLib.c + + +[Guids] +gHdAudioDxeConfigGuid +gGpioDxeConfigGuid + +[Protocols] +gPchPolicyProtocolGuid ## PRODUCES diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf new file mode 100644 index 0000000000..0bb2d6e247 --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf @@ -0,0 +1,49 @@ +## @file +# Component description file for Intel Ich7 Reset System Library. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = DxeResetSystemLib +FILE_GUID = 239383BC-499E-4DC5-8CDC-F85AF27B1BC4 +VERSION_STRING = 1.0 +MODULE_TYPE = DXE_DRIVER +UEFI_SPECIFICATION_VERSION = 2.00 +LIBRARY_CLASS = ResetSystemLib +CONSTRUCTOR = DxeResetSystemLibConstructor +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[LibraryClasses] +IoLib +BaseLib +DebugLib +TimerLib +BaseMemoryLib +UefiBootServicesTableLib +PmcLib + + +[Packages] +MdePkg/MdePkg.dec +CoffeelakeSiliconPkg/SiPkg.dec + + +[Sources] +DxeResetSystemLib.c + + +[Protocols] +gPchResetCallbackProtocolGuid ## CONSUMES + + +[Guids] +gPchGlobalResetGuid diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf new file mode 100644 index 0000000000..a1777293ab --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf @@ -0,0 +1,52 @@ +## @file +# Component description file for Intel Ich7 Reset System Library. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = DxeRuntimeResetSystemLib +FILE_GUID = 1026813A-E46F-43D1-B709-FF1F996F2E72 +VERSION_STRING = 1.0 +MODULE_TYPE = DXE_RUNTIME_DRIVER +UEFI_SPECIFICATION_VERSION = 2.00 +LIBRARY_CLASS = ResetSystemLib +CONSTRUCTOR = DxeRuntimeResetSystemLibConstructor +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[LibraryClasses] +IoLib +BaseLib +DebugLib +TimerLib +BaseMemoryLib +UefiRuntimeLib +DxeServicesTableLib +UefiBootServicesTableLib +PmcLib + + +[Packages] +MdePkg/MdePkg.dec +CoffeelakeSiliconPkg/SiPkg.dec + + +[Sources] +DxeRuntimeResetSystemLib.c + + +[Protocols] +gPchResetCallbackProtocolGuid ## CONSUMES + + +[Guids] +gPchGlobalResetGuid +gEfiEventVirtualAddressChangeGuid diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c new file mode 100644 index 0000000000..62c8a91eb9 --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c @@ -0,0 +1,218 @@ +/** @file + This file provide services for DXE phase policy default initialization + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Load DXE Config block default for HD Audio + + @param[in] ConfigBlockPointer Pointer to config block +**/ +VOID +LoadHdAudioDxeConfigDefault ( + IN VOID *ConfigBlockPointer + ) +{ + PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig; + HdAudioDxeConfig = ConfigBlockPointer; + + DEBUG ((DEBUG_INFO, "HdaDxeConfig->Header.GuidHob.Name = %g\n", &HdAudioDxeConfig->Header.GuidHob.Name)); + DEBUG ((DEBUG_INFO, "HdaDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdAudioDxeConfig->Header.GuidHob.Header.HobLength)); + + HdAudioDxeConfig->DspEndpointDmic = PchHdaDmic4chArray; + HdAudioDxeConfig->NhltDefaultFlow = TRUE; +} + +/** + Load DXE Config block default for GPIO + + @param[in] ConfigBlockPointer Pointer to config block +**/ +VOID +LoadGpioDxeConfigDefault ( + IN VOID *ConfigBlockPointer + ) +{ + PCH_GPIO_DXE_CONFIG *GpioDxeConfig; + GpioDxeConfig = ConfigBlockPointer; + + DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Name = %g\n", &GpioDxeConfig->Header.GuidHob.Name)); + DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GpioDxeConfig->Header.GuidHob.Header.HobLength)); + + GpioDxeConfig->HideGpioAcpiDevice = 0; +} + +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY mPchDxeIpBlocks [] = { + {&gHdAudioDxeConfigGuid, sizeof (PCH_HDAUDIO_DXE_CONFIG), HDAUDIO_DXE_CONFIG_REVISION, LoadHdAudioDxeConfigDefault}, + {&gGpioDxeConfigGuid, sizeof (PCH_GPIO_DXE_CONFIG), GPIO_DXE_CONFIG_REVISION, LoadGpioDxeConfigDefault} +}; + +/** + Print PCH_HDAUDIO_DXE_CONFIG. + + @param[in] HdaDxeConfig Pointer to a PCH_HDAUDIO_DXE_CONFIG that provides the HD Audio settings +**/ +VOID +PchPrintHdAudioDxeConfig ( + IN CONST PCH_HDAUDIO_DXE_CONFIG *HdaDxeConfig + ) +{ + DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio DXE Config ------------------\n")); + DEBUG ((DEBUG_INFO, " DSP Endpoint: DMIC : %d\n", HdaDxeConfig->DspEndpointDmic)); + DEBUG ((DEBUG_INFO, " DSP Endpoint: I2S : %d\n", HdaDxeConfig->DspEndpointI2s)); + DEBUG ((DEBUG_INFO, " DSP Endpoint: BT : %d\n", HdaDxeConfig->DspEndpointBluetooth)); + DEBUG ((DEBUG_INFO, " DSP Feature Mask : 0x%x\n", HdaDxeConfig->DspFeatureMask)); + DEBUG ((DEBUG_INFO, " Nhlt Default Flow : %d\n", HdaDxeConfig->NhltDefaultFlow)); +} + +/** + Print PCH_GPIO_DXE_CONFIG. + + @param[in] GpioDxeConfig Pointer to a PCH_GPIO_DXE_CONFIG that provides the GPIO settings +**/ +VOID +PchPrintGpioDxeConfig ( + IN CONST PCH_GPIO_DXE_CONFIG *GpioDxeConfig + ) +{ + DEBUG ((DEBUG_INFO, "------------------ PCH GPIO DXE Config ------------------\n")); + DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", GpioDxeConfig->HideGpioAcpiDevice)); +} + +/** + This function prints the PCH DXE phase policy. + + @param[in] PchPolicy - PCH DXE Policy protocol +**/ +VOID +PchPrintPolicyProtocol ( + IN PCH_POLICY_PROTOCOL *PchPolicy + ) +{ + DEBUG_CODE_BEGIN(); + EFI_STATUS Status; + PCH_HDAUDIO_DXE_CONFIG *HdaDxeConfig; + PCH_GPIO_DXE_CONFIG *GpioDxeConfig; + + // + // Get requisite IP Config Blocks which needs to be used here + // + Status = GetConfigBlock ((VOID *) PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdaDxeConfig); + ASSERT_EFI_ERROR (Status); + Status = GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOID *)&GpioDxeConfig); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print Start ------------------------\n")); + DEBUG ((DEBUG_INFO, " Revision : %x\n", PchPolicy->TableHeader.Header.Revision)); + + PchPrintHdAudioDxeConfig (HdaDxeConfig); + PchPrintGpioDxeConfig (GpioDxeConfig); + + DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print End --------------------------\n")); + DEBUG_CODE_END(); +} + +/** + CreatePchDxeConfigBlocks generates the config blocksg of PCH DXE Policy. + It allocates and zero out buffer, and fills in the Intel default settings. + + @param[out] PchPolicy The pointer to get PCH DXE Protocol instance + + @retval EFI_SUCCESS The policy default is initialized. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer +**/ +EFI_STATUS +EFIAPI +CreatePchDxeConfigBlocks ( + IN OUT PCH_POLICY_PROTOCOL **DxePchPolicy + ) +{ + UINT16 TotalBlockSize; + EFI_STATUS Status; + PCH_POLICY_PROTOCOL *PchPolicyInit; + UINT16 RequiredSize; + + + DEBUG ((DEBUG_INFO, "PCH Create Dxe Config Blocks\n")); + + PchPolicyInit = NULL; + + TotalBlockSize = GetComponentConfigBlockTotalSize (&mPchDxeIpBlocks[0], sizeof (mPchDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)); + + DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize)); + + RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize; + + Status = CreateConfigBlockTable (RequiredSize, (VOID *) &PchPolicyInit); + ASSERT_EFI_ERROR (Status); + + // + // General initialization + // + PchPolicyInit->TableHeader.Header.Revision = PCH_POLICY_PROTOCOL_REVISION; + // + // Add config blocks. + // + Status = AddComponentConfigBlocks ((VOID *) PchPolicyInit, &mPchDxeIpBlocks[0], sizeof (mPchDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)); + ASSERT_EFI_ERROR (Status); + + // + // Assignment for returning SaInitPolicy config block base address + // + *DxePchPolicy = PchPolicyInit; + return Status; +} + +/** + PchInstallPolicyProtocol installs PCH Policy. + While installed, RC assumes the Policy is ready and finalized. So please update and override + any setting before calling this function. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SaPolicy The pointer to SA Policy Protocol instance + + @retval EFI_SUCCESS The policy is installed. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer + +**/ +EFI_STATUS +EFIAPI +PchInstallPolicyProtocol ( + IN EFI_HANDLE ImageHandle, + IN PCH_POLICY_PROTOCOL *PchPolicy + ) +{ + + EFI_STATUS Status; + + /// + /// Print PCH DXE Policy + /// + PchPrintPolicyProtocol (PchPolicy); + + /// + /// Install protocol to to allow access to this Policy. + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gPchPolicyProtocolGuid, + PchPolicy, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c new file mode 100644 index 0000000000..fd3c280605 --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c @@ -0,0 +1,310 @@ +/** @file + System reset library services. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mDxeResetSystemPwrmBase; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mDxeResetSystemABase; + +/** + Dump reset message for debug build readability +**/ +VOID +DumpResetMessage ( + VOID + ) +{ + DEBUG_CODE_BEGIN (); + UINTN Index; + // + // ****************************** + // ** SYSTEM REBOOT !!! ** + // ****************************** + // + for (Index = 0; Index < 30; Index++) { + DEBUG ((DEBUG_INFO, "*")); + } + DEBUG ((DEBUG_INFO, "\n** SYSTEM REBOOT !!! **\n")); + for (Index = 0; Index < 30; Index++) { + DEBUG ((DEBUG_INFO, "*")); + } + DEBUG ((DEBUG_INFO, "\n")); + DEBUG_CODE_END (); +} + +/** + Execute call back function for Pch Reset. + + @param[in] ResetType Reset Types which includes GlobalReset. + @param[in] ResetTypeGuid Pointer to an EFI_GUID, which is the Reset Type Guid. +**/ +VOID +EFIAPI +PchResetCallback ( + IN EFI_RESET_TYPE ResetType, + IN EFI_GUID *ResetTypeGuid + ) +{ + EFI_STATUS Status; + UINTN NumHandles; + EFI_HANDLE *HandleBuffer; + UINTN Index; + PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback; + + /// + /// Retrieve all instances of Pch Reset Callback protocol + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gPchResetCallbackProtocolGuid, + NULL, + &NumHandles, + &HandleBuffer + ); + + if (EFI_ERROR (Status)) { + /// + /// Those drivers that need to install Pch Reset Callback protocol have the responsibility + /// to make sure themselves execute before Pch Reset Runtime driver. + /// + if (Status == EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n")); + } + return; + } + + for (Index = 0; Index < NumHandles; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gPchResetCallbackProtocolGuid, + (VOID **) &PchResetCallback + ); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR (Status)) { + PchResetCallback->ResetCallback (ResetType, ResetTypeGuid); + } + } +} + +/** + Calling this function causes a system-wide reset. This sets + all circuitry within the system to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + System reset should not return, if it returns, it means the system does + not support cold reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetCold, NULL); + + DumpResetMessage (); + + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); +} + +/** + Calling this function causes a system-wide initialization. The processors + are set to their initial state, and pending cycles are not corrupted. + + System reset should not return, if it returns, it means the system does + not support warm reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetWarm, NULL); + + DumpResetMessage (); + // + // In case there are pending capsules to process, need to flush the cache. + // + AsmWbinvd (); + + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_HARDRESET); +} + +/** + Calling this function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + System shutdown should not return, if it returns, it means the system does + not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + UINT32 Data32; + + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetShutdown, NULL); + + /// + /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5 + /// + IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_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 + /// + IoWrite16 (mDxeResetSystemABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN); + + /// + /// Finally, transform system into S5 sleep state + /// + Data32 = IoRead32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT); + + Data32 = (UINT32) ((Data32 &~(B_ACPI_IO_PM1_CNT_SLP_TYP + B_ACPI_IO_PM1_CNT_SLP_EN)) | V_ACPI_IO_PM1_CNT_S5); + + IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32); + + Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN; + + DumpResetMessage (); + + IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32); + + return; +} + +/** + Internal function to execute the required HECI command for GlobalReset, + if failed will use PCH Reest. + +**/ +STATIC +VOID +PchGlobalReset ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid); + + // + // PCH BIOS Spec Section 4.6 GPIO Reset Requirement + // + MmioOr32 ( + mDxeResetSystemPwrmBase + R_PMC_PWRM_ETR3, + (UINT32) B_PMC_PWRM_ETR3_CF9GR + ); + + DumpResetMessage (); + + // + // ME Global Reset should fail after EOP is sent. Go to use PCH Reset. + // + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); +} + +/** + Calling this function causes the system to enter a power state for platform specific. + + @param[in] DataSize The size of ResetData in bytes. + @param[in] ResetData Optional element used to introduce a platform specific reset. + The exact type of the reset is defined by the EFI_GUID that follows + the Null-terminated Unicode string. + +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + EFI_GUID *GuidPtr; + + if (ResetData == NULL) { + DEBUG ((DEBUG_ERROR, "[DxeResetSystemLib] ResetData is not available.\n")); + return; + } + GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID)); + if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) { + PchGlobalReset(); + } else { + return; + } +} + +/** + Calling this function causes the system to enter a power state for capsule update. + + Reset update should not return, if it returns, it means the system does + not support capsule update. + +**/ +VOID +EFIAPI +EnterS3WithImmediateWake ( + VOID + ) +{ + ASSERT (FALSE); +} + +/** + The library constructuor. + + The function does the necessary initialization work for this library DXE instance. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS The function always return EFI_SUCCESS for now. + It will ASSERT on error for debug version. +**/ +EFI_STATUS +EFIAPI +DxeResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + mDxeResetSystemABase = PmcGetAcpiBase (); + mDxeResetSystemPwrmBase = PmcGetPwrmBase (); + + return EFI_SUCCESS; +} + diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c new file mode 100644 index 0000000000..a39e171804 --- /dev/null +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c @@ -0,0 +1,323 @@ +/** @file + System reset library services. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mDxeRuntimeResetSystemPwrmBase; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mDxeRuntimeResetSystemABase; + +/** + Dump reset message for debug build readability +**/ +VOID +DumpResetMessage ( + VOID + ) +{ + DEBUG_CODE_BEGIN (); + UINTN Index; + // + // ****************************** + // ** SYSTEM REBOOT !!! ** + // ****************************** + // + if (!EfiAtRuntime ()) { + for (Index = 0; Index < 30; Index++) { + DEBUG ((DEBUG_INFO, "*")); + } + DEBUG ((DEBUG_INFO, "\n** SYSTEM REBOOT !!! **\n")); + for (Index = 0; Index < 30; Index++) { + DEBUG ((DEBUG_INFO, "*")); + } + DEBUG ((DEBUG_INFO, "\n")); + } + DEBUG_CODE_END (); +} + +/** + Execute call back function for Pch Reset. + + @param[in] ResetType Reset Types which includes GlobalReset. + @param[in] ResetTypeGuid Pointer to an EFI_GUID, which is the Reset Type Guid. +**/ +VOID +EFIAPI +PchResetCallback ( + IN EFI_RESET_TYPE ResetType, + IN EFI_GUID *ResetTypeGuid + ) +{ + EFI_STATUS Status; + UINTN NumHandles; + EFI_HANDLE *HandleBuffer; + UINTN Index; + PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback; + + if (!EfiAtRuntime ()) { + /// + /// Retrieve all instances of Pch Reset Callback protocol + /// + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gPchResetCallbackProtocolGuid, + NULL, + &NumHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + /// + /// Those drivers that need to install Pch Reset Callback protocol have the responsibility + /// to make sure themselves execute before Pch Reset Runtime driver. + /// + if (Status == EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n")); + } + return; + } + + for (Index = 0; Index < NumHandles; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gPchResetCallbackProtocolGuid, + (VOID **) &PchResetCallback + ); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR (Status)) { + PchResetCallback->ResetCallback (ResetType, ResetTypeGuid); + } + } + } +} + +/** + Calling this function causes a system-wide reset. This sets + all circuitry within the system to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + System reset should not return, if it returns, it means the system does + not support cold reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetCold, NULL); + + DumpResetMessage (); + + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); +} + +/** + Calling this function causes a system-wide initialization. The processors + are set to their initial state, and pending cycles are not corrupted. + + System reset should not return, if it returns, it means the system does + not support warm reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetWarm, NULL); + + DumpResetMessage (); + // + // In case there are pending capsules to process, need to flush the cache. + // + AsmWbinvd (); + + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_HARDRESET); +} + +/** + Calling this function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + System shutdown should not return, if it returns, it means the system does + not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + UINT32 Data32; + + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetShutdown, NULL); + + /// + /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5 + /// + IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_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 + /// + IoWrite16 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN); + + /// + /// Finally, transform system into S5 sleep state + /// + Data32 = IoRead32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT); + + Data32 = (UINT32) ((Data32 &~(B_ACPI_IO_PM1_CNT_SLP_TYP + B_ACPI_IO_PM1_CNT_SLP_EN)) | V_ACPI_IO_PM1_CNT_S5); + + IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32); + + Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN; + + DumpResetMessage (); + + IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32); + + return; +} + +/** + Internal function to execute the required HECI command for GlobalReset, + if failed will use PCH Reest. + +**/ +STATIC +VOID +PchGlobalReset ( + VOID + ) +{ + // + // Loop through callback functions of PchResetCallback Protocol + // + PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid); + + DumpResetMessage (); + + // + // Let ME do global reset if Me Fw is available + // + if (!EfiAtRuntime ()) { + // + // PCH BIOS Spec Section 4.6 GPIO Reset Requirement + // + MmioOr32 ( + mDxeRuntimeResetSystemPwrmBase + R_PMC_PWRM_ETR3, + (UINT32) B_PMC_PWRM_ETR3_CF9GR + ); + } + + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); +} + +/** + Calling this function causes the system to enter a power state for platform specific. + + @param[in] DataSize The size of ResetData in bytes. + @param[in] ResetData Optional element used to introduce a platform specific reset. + The exact type of the reset is defined by the EFI_GUID that follows + the Null-terminated Unicode string. + +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + EFI_GUID *GuidPtr; + + if (ResetData == NULL) { + if (!EfiAtRuntime ()) { + DEBUG ((DEBUG_ERROR, "[DxeRuntimeResetSystemLib] ResetData is not available.\n")); + } + return; + } + GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID)); + if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) { + PchGlobalReset (); + } else { + return; + } +} + +/** + Calling this function causes the system to enter a power state for capsule update. + + Reset update should not return, if it returns, it means the system does + not support capsule update. + +**/ +VOID +EFIAPI +EnterS3WithImmediateWake ( + VOID + ) +{ + ASSERT (FALSE); +} + +/** + The library constructuor. + + The function does the necessary initialization work for this library instance. + + The PMC PCI configuration and PWRM space memory ranges are converted into EFI_RUNTIME_XXX + in PciHostBridgeEntryPoint + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS The function always return EFI_SUCCESS for now. + It will ASSERT on error for debug version. + @retval EFI_ERROR Please reference LocateProtocol for error code details. +**/ +EFI_STATUS +EFIAPI +DxeRuntimeResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + mDxeRuntimeResetSystemABase = PmcGetAcpiBase (); + mDxeRuntimeResetSystemPwrmBase = PmcGetPwrmBase (); + + return EFI_SUCCESS; +} + -- 2.16.2.windows.1