Reviewed-by: Chao Li Thanks, Chao -------- On 11月 11 2022, at 5:12 δΈ‹εˆ, xianglai li wrote: > This library provides interfaces related to restart and shutdown. > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054 > > > Cc: Bibo Mao > Cc: Chao Li > Cc: Leif Lindholm > Cc: Liming Gao > Cc: Michael D Kinney > Signed-off-by: xianglai li > --- > .../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.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c > create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h > > > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c > new file mode 100644 > index 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include "ResetSystemAcpiGed.h" > +#include > + > +/** > + 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.inf > new file mode 100644 > index 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.
> +# > +# 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 > + IoLib > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c > new file mode 100644 > index 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include // EfiConvertPointer() > +#include > +#include > +#include "ResetSystemAcpiGed.h" > +#include > + > +/** > + 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.inf > new file mode 100644 > index 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.
> +# > +# 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 ## SystemTable > diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c b/Platform/Loongson/LoongArchQemuPkg/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c > new file mode 100644 > index 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include // CpuDeadLoop() > +#include > +#include // ResetCold() > +#include > +#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.h > new file mode 100644 > index 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef RESET_SYSTEM_ACPI_GED_H_ > +#define RESET_SYSTEM_ACPI_GED_H_ > + > +#include > + > +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