Thanks,
Chao
--------
This library provides interfaces related to restart and shutdown.REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054Cc: Bibo Mao <maobibo@loongson.cn>Cc: Chao Li <lichao@loongson.cn>Cc: Leif Lindholm <quic_llindhol@quicinc.com>Cc: Liming Gao <gaoliming@byosoft.com.cn>Cc: Michael D Kinney <michael.d.kinney@intel.com>Signed-off-by: xianglai li <lixianglai@loongson.cn>---.../BaseResetSystemAcpiGed.c | 146 ++++++++++.../BaseResetSystemAcpiGedLib.inf | 37 +++.../DxeResetSystemAcpiGed.c | 257 ++++++++++++++++++.../DxeResetSystemAcpiGedLib.inf | 41 +++.../ResetSystemAcpiLib/ResetSystemAcpiGed.c | 128 +++++++++.../ResetSystemAcpiLib/ResetSystemAcpiGed.h | 23 ++6 files changed, 632 insertions(+)create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.ccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.infcreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.ccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.infcreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.ccreate mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.hdiff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.cnew file mode 100644index 0000000000..0df629ffcd--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c@@ -0,0 +1,146 @@+/** @file+ Base ResetSystem library implementation.++ Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>++ SPDX-License-Identifier: BSD-2-Clause-Patent++**/++#include <Base.h>+#include <Library/DebugLib.h>+#include <Library/BaseMemoryLib.h>+#include <Library/MemoryAllocationLib.h>+#include "ResetSystemAcpiGed.h"+#include <Library/QemuFwCfgLib.h>++/**+ Get configuration item data by the firmware configuration file name.++ @param[in] Name - Name of file to look up.++ @return VOID* The Pointer of Value of Firmware Configuration item read.+**/+VOID *+GetFwCfgData(+CONST CHAR8 *Name+)+{+ FIRMWARE_CONFIG_ITEM FwCfgItem;+ EFI_STATUS Status;+ UINTN FwCfgSize;+ VOID *Data;++ Status = QemuFwCfgFindFile (Name, &FwCfgItem, &FwCfgSize);+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_ERROR, "%a %d read %s error Status %d \n", __func__, __LINE__, Name, Status));+ return NULL;+ }++ Data = AllocatePool (FwCfgSize);+ if (Data == NULL) {+ return NULL;+ }++ QemuFwCfgSelectItem (FwCfgItem);+ QemuFwCfgReadBytes (FwCfgSize, Data);++ return Data;+}++/**+ Find the power manager related info from ACPI table++ @retval RETURN_SUCCESS Successfully find out all the required information.+ @retval RETURN_NOT_FOUND Failed to find the required info.+**/+STATIC EFI_STATUS+GetPowerManagerByParseAcpiInfo (VOID)+{+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt = NULL;+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp = NULL;+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt = NULL;+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt = NULL;+ VOID *AcpiTables = NULL;+ UINT32 *Entry32 = NULL;+ UINTN Entry32Num;+ UINT32 *Signature = NULL;+ UINTN Idx;++ Rsdp = GetFwCfgData ("etc/acpi/rsdp");+ if (Rsdp == NULL) {+ DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/rsdp error \n", __func__, __LINE__));+ return RETURN_NOT_FOUND;+ }++ AcpiTables = GetFwCfgData ("etc/acpi/tables");+ if (AcpiTables == NULL) {+ DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/tables error \n", __func__, __LINE__));+ FreePool (Rsdp);+ return RETURN_NOT_FOUND;+ }++ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->RsdtAddress);+ Entry32 = (UINT32 *)(Rsdt + 1);+ Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;+ for (Idx = 0; Idx < Entry32Num; Idx++) {+ Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables);+ if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {+ Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;+ DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));+ goto Done;+ }+ }++ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->XsdtAddress);+ Entry32 = (UINT32 *)(Xsdt + 1);+ Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;+ for (Idx = 0; Idx < Entry32Num; Idx++) {+ Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables);+ if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {+ Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;+ DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));+ goto Done;+ }+ }++ FreePool (Rsdp);+ FreePool (AcpiTables);+ DEBUG ((DEBUG_ERROR, " Fadt Not Found\n"));+ return RETURN_NOT_FOUND;++Done:+ mPowerManager.ResetRegAddr = Fadt->ResetReg.Address;+ mPowerManager.ResetValue = Fadt->ResetValue;+ mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address;+ mPowerManager.SleepStatusRegAddr = Fadt->SleepStatusReg.Address;++ FreePool (Rsdp);+ FreePool (AcpiTables);+ return RETURN_SUCCESS;+}++/**+ The constructor function to initialize mPowerManager.++ @retval EFI_SUCCESS initialize mPowerManager success.+ @retval RETURN_NOT_FOUND Failed to initialize mPowerManager.+**/+EFI_STATUS+ResetSystemLibConstructor (+ IN EFI_HANDLE ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS Status;++ Status = GetPowerManagerByParseAcpiInfo ();+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));+ }++ ASSERT (mPowerManager.SleepControlRegAddr);+ ASSERT (mPowerManager.SleepStatusRegAddr);+ ASSERT (mPowerManager.ResetRegAddr);+ return Status;+}diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.infnew file mode 100644index 0000000000..120dd7dcff--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf@@ -0,0 +1,37 @@+## @file+# Base library instance for ResetSystem library class for loongarhch+#+# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>+#+# SPDX-License-Identifier: BSD-2-Clause-Patent+#+##++[Defines]+ INF_VERSION = 1.29+ BASE_NAME = ResetSystemLib+ FILE_GUID = 3d6faf60-804a-4ca9-a36a-1a92416919d0+ MODULE_TYPE = BASE+ VERSION_STRING = 1.0+ LIBRARY_CLASS = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE+ CONSTRUCTOR = ResetSystemLibConstructor++#+# VALID_ARCHITECTURES = LOONGARCH64+#++[Sources]+ BaseResetSystemAcpiGed.c+ ResetSystemAcpiGed.c++[Packages]+ MdeModulePkg/MdeModulePkg.dec+ MdePkg/MdePkg.dec+ OvmfPkg/OvmfPkg.dec++[LibraryClasses]+ BaseLib+ DebugLib+ QemuFwCfgLib+ MemoryAllocationLib+ IoLibdiff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.cnew file mode 100644index 0000000000..ef48946ae4--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c@@ -0,0 +1,257 @@+/** @file+ Dxe ResetSystem library implementation.++ Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>++ SPDX-License-Identifier: BSD-2-Clause-Patent++**/++#include <Base.h>+#include <Library/DebugLib.h>+#include <Library/UefiRuntimeLib.h> // EfiConvertPointer()+#include <Library/DxeServicesTableLib.h>+#include <Library/UefiBootServicesTableLib.h>+#include "ResetSystemAcpiGed.h"+#include <Library/UefiLib.h>++/**+ Modifies the attributes to Runtime type for a page size memory region.++ @param BaseAddress Specified start address++ @retval EFI_SUCCESS The attributes were set for the memory region.+ @retval EFI_INVALID_PARAMETER Length is zero.+ @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory+ resource range specified by BaseAddress and Length.+ @retval EFI_UNSUPPORTED The bit mask of attributes is not support for the memory resource+ range specified by BaseAddress and Length.+ @retval EFI_ACCESS_DEFINED The attributes for the memory resource range specified by+ BaseAddress and Length cannot be modified.+ @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of+ the memory resource range.+ @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is+ not available yet.+**/+EFI_STATUS+SetMemoryAttributesRunTime (+ UINTN Address+ )+{+ EFI_STATUS Status;+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;++ Address &= ~EFI_PAGE_MASK;++ Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor);+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a: GetMemorySpaceDescriptor failed\n", __FUNCTION__));+ return Status;+ }++ if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {+ Status = gDS->AddMemorySpace (+ EfiGcdMemoryTypeMemoryMappedIo,+ Address,+ EFI_PAGE_SIZE,+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME+ );+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a: AddMemorySpace failed\n", __FUNCTION__));+ return Status;+ }++ Status = gDS->SetMemorySpaceAttributes (+ Address,+ EFI_PAGE_SIZE,+ EFI_MEMORY_RUNTIME+ );+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUNCTION__, __LINE__));+ return Status;+ }+ } else if (!(Descriptor.Attributes & EFI_MEMORY_RUNTIME)) {+ Status = gDS->SetMemorySpaceAttributes (+ Address,+ EFI_PAGE_SIZE,+ Descriptor.Attributes | EFI_MEMORY_RUNTIME+ );++ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUNCTION__, __LINE__));+ return Status;+ }+ }+ return EFI_SUCCESS;+}++/**+ Find the power manager related info from ACPI table++ @retval RETURN_SUCCESS Successfully find out all the required information.+ @retval RETURN_NOT_FOUND Failed to find the required info.+**/+STATIC EFI_STATUS+GetPowerManagerByParseAcpiInfo (+ VOID+)+{+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt = NULL;+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp = NULL;+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt = NULL;+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt = NULL;+ UINT32 *Entry32 = NULL;+ UINTN Entry32Num;+ UINT32 *Signature = NULL;+ UINTN Idx;+ EFI_STATUS Status;++ Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);+ if (EFI_ERROR (Status)) {+ Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);+ }++ if (EFI_ERROR (Status) || (Rsdp == NULL)) {+ DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));+ return RETURN_NOT_FOUND;+ }++ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;+ Entry32 = (UINT32 *)(UINTN)(Rsdt + 1);+ Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;+ for (Idx = 0; Idx < Entry32Num; Idx++) {+ Signature = (UINT32 *)(UINTN)Entry32[Idx];+ if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {+ Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;+ DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));+ goto Done;+ }+ }++ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Rsdp->XsdtAddress;+ Entry32 = (UINT32 *)(Xsdt + 1);+ Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;+ for (Idx = 0; Idx < Entry32Num; Idx++) {+ Signature = (UINT32 *)(UINTN)Entry32[Idx];+ if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {+ Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;+ DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));+ goto Done;+ }+ }++ DEBUG ((DEBUG_ERROR, " Fadt Not Found\n"));+ return RETURN_NOT_FOUND;++Done:+ mPowerManager.ResetRegAddr = Fadt->ResetReg.Address;+ mPowerManager.ResetValue = Fadt->ResetValue;+ mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address;+ mPowerManager.SleepStatusRegAddr = Fadt->SleepStatusReg.Address;+ return RETURN_SUCCESS;+}++/**+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE+ event. It converts a pointer to a new virtual address.++ @param[in] Event Event whose notification function is being invoked.+ @param[in] Context Pointer to the notification function's context+**/+VOID+EFIAPI+ResetSystemLibAddressChangeEvent (+ IN EFI_EVENT Event,+ IN VOID *Context+ )+{+ EfiConvertPointer (0, (VOID **)&mPowerManager.SleepControlRegAddr);+ EfiConvertPointer (0, (VOID **)&mPowerManager.SleepStatusRegAddr);+ EfiConvertPointer (0, (VOID **)&mPowerManager.ResetRegAddr);+}++/**+ Notification function of ACPI Table change.++ This is a notification function registered on ACPI Table change event.+ It saves the Century address stored in ACPI FADT table.++ @param Event Event whose notification function is being invoked.+ @param Context Pointer to the notification function's context.+**/+STATIC VOID+AcpiNotificationEvent (+ IN EFI_EVENT Event,+ IN VOID *Context+ )+{+ EFI_STATUS Status;++ Status = GetPowerManagerByParseAcpiInfo ();+ if (EFI_ERROR (Status)) {+ return ;+ }++ DEBUG ((DEBUG_INFO, "%a: sleepControl %llx\n", __FUNCTION__, mPowerManager.SleepControlRegAddr));+ ASSERT (mPowerManager.SleepControlRegAddr);+ Status = SetMemoryAttributesRunTime (mPowerManager.SleepControlRegAddr);+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));+ return ;+ }++ DEBUG ((DEBUG_INFO, "%a: sleepStatus %llx\n", __FUNCTION__, mPowerManager.SleepStatusRegAddr));+ ASSERT (mPowerManager.SleepStatusRegAddr);+ Status = SetMemoryAttributesRunTime (mPowerManager.SleepStatusRegAddr);+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));+ return ;+ }++ DEBUG ((DEBUG_INFO, "%a: ResetReg %llx\n", __FUNCTION__, mPowerManager.ResetRegAddr));+ ASSERT (mPowerManager.ResetRegAddr);+ Status = SetMemoryAttributesRunTime (mPowerManager.ResetRegAddr);+ if (EFI_ERROR (Status)) {+ DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));+ }+ return ;+}++/**+ The constructor function to Register ACPI Table change event and Address Change Event.++ @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.+**/+EFI_STATUS+EFIAPI+ResetSystemLibConstructor (+ IN EFI_HANDLE ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS Status;+ EFI_EVENT Event;+ EFI_EVENT ResetSystemVirtualNotifyEvent;++ Status = gBS->CreateEventEx (+ EVT_NOTIFY_SIGNAL,+ TPL_CALLBACK,+ AcpiNotificationEvent,+ NULL,+ &gEfiAcpiTableGuid,+ &Event+ );++ //+ // Register SetVirtualAddressMap () notify function+ //+ Status = gBS->CreateEvent (+ EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,+ TPL_NOTIFY,+ ResetSystemLibAddressChangeEvent,+ NULL,+ &ResetSystemVirtualNotifyEvent+ );+ ASSERT_EFI_ERROR (Status);+ return Status;+}diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.infnew file mode 100644index 0000000000..48c7ea2dc3--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf@@ -0,0 +1,41 @@+## @file+# DXE library instance for ResetSystem library class for loongarch.+#+# Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>+#+# SPDX-License-Identifier: BSD-2-Clause-Patent+#+##++[Defines]+ INF_VERSION = 1.29+ BASE_NAME = ResetSystemLib+ FILE_GUID = 3d6faf60-804a-4ca9-a36a-1a92416919d0+ MODULE_TYPE = DXE_RUNTIME_DRIVER+ VERSION_STRING = 1.0+ LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION+ CONSTRUCTOR = ResetSystemLibConstructor++#+# VALID_ARCHITECTURES = LOONGARCH64+#++[Sources]+ DxeResetSystemAcpiGed.c+ ResetSystemAcpiGed.c++[Packages]+ MdeModulePkg/MdeModulePkg.dec+ MdePkg/MdePkg.dec+ OvmfPkg/OvmfPkg.dec++[LibraryClasses]+ BaseLib+ DebugLib+ DxeServicesTableLib+ IoLib+ UefiLib++[Guids]+ gEfiAcpi10TableGuid ## PRODUCES ## SystemTable+ gEfiAcpiTableGuid ## PRODUCES ## SystemTablediff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.cnew file mode 100644index 0000000000..d15cc70b4b--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c@@ -0,0 +1,128 @@+/** @file+ ResetSystem library implementation.++ Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>++ SPDX-License-Identifier: BSD-2-Clause-Patent++**/++#include <Base.h>+#include <Uefi.h>+#include <PiPei.h>+#include <Library/BaseLib.h> // CpuDeadLoop()+#include <Library/DebugLib.h>+#include <Library/ResetSystemLib.h> // ResetCold()+#include <Library/IoLib.h>+#include "ResetSystemAcpiGed.h"++POWER_MANAGER mPowerManager;++/**+ 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.+**/+STATIC VOID+AcpiGedReset (+ VOID+ )+{+ MmioWrite8 (+ (UINTN)mPowerManager.ResetRegAddr,+ mPowerManager.ResetValue+ );++ CpuDeadLoop ();+}++/**+ This function causes the system to enter a power state equivalent+ to the ACPI S5 states.++ * */+STATIC VOID+AcpiGedShutdown (+ VOID+ )+{+ MmioWrite8 (+ (UINTN)mPowerManager.SleepControlRegAddr,+ (1 << 5) /* enable bit */ |+ (5 << 2) /* typ == S5 */+ );++ CpuDeadLoop ();+}++/**+ This function causes a system-wide reset (cold reset), in which+ all circuitry within the system returns to its initial state. This type of+ reset is asynchronous to system operation and operates without regard to+ cycle boundaries.++ If this function returns, it means that the system does not support cold+ reset.+**/+VOID EFIAPI+ResetCold (+ VOID+ )+{+ AcpiGedReset ();+}++/**+ This function causes a system-wide initialization (warm reset), in which all+ processors are set to their initial state. Pending cycles are not corrupted.++ If this function returns, it means that the system does not support warm+ reset.+**/+VOID EFIAPI+ResetWarm (+ VOID+ )+{+ AcpiGedReset ();+}++/**+ This function causes a systemwide reset. The exact type of the reset is+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData+ the platform must pick a supported reset type to perform.The platform may+ optionally log the parameters from any non-normal reset that occurs.++ @param[in] DataSize The size, in bytes, of ResetData.+ @param[in] ResetData The data buffer starts with a Null-terminated string,+ followed by the EFI_GUID.+**/+VOID+EFIAPI+ResetPlatformSpecific (+ IN UINTN DataSize,+ IN VOID *ResetData+ )+{+ AcpiGedReset ();+}++/**+ This function causes the system to enter a power state equivalent+ to the ACPI G2/S5 or G3 states.++ If this function returns, it means that the system does not support shut down+ reset.+**/+VOID EFIAPI+ResetShutdown (+ VOID+ )+{+ AcpiGedShutdown ();+}diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.hnew file mode 100644index 0000000000..e504e870f9--- /dev/null+++ b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h@@ -0,0 +1,23 @@+/** @file+ ResetSystem lib head file.++ Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>++ SPDX-License-Identifier: BSD-2-Clause-Patent++**/++#ifndef RESET_SYSTEM_ACPI_GED_H_+#define RESET_SYSTEM_ACPI_GED_H_++#include <Base.h>++typedef struct {+ UINT64 SleepControlRegAddr;+ UINT64 SleepStatusRegAddr;+ UINT64 ResetRegAddr;+ UINT8 ResetValue;+} POWER_MANAGER;++extern POWER_MANAGER mPowerManager;+#endif // RESET_SYSTEM_ACPI_GED_H_--2.31.1