Reviewed-by: Chao Li  <lichao@loongson.cn>


Thanks,
Chao
--------

On 11月 11 2022, at 5:12 δΈ‹εˆ, xianglai li <lixianglai@loongson.cn> wrote:
This library provides interfaces related to restart and shutdown.



REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054



Cc: 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.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.<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.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.<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

+ 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.<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.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.<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 ## 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.<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.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.<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