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


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr>   Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/96299">View/Reply Online (#96299)</a> |    |  <a target="_blank" href="https://groups.io/mt/94955180/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>