From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.6333.1668652806314502036 for ; Wed, 16 Nov 2022 18:40:07 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: loongson.cn, ip: 114.242.206.163, mailfrom: lixianglai@loongson.cn) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxXbYEn3VjMiQIAA--.11325S3; Thu, 17 Nov 2022 10:40:04 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxLeD5nnVjCpcVAA--.56818S15; Thu, 17 Nov 2022 10:40:03 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney Subject: [edk2-platforms][PATCH V6 13/16] Platform/Loongson: Add Reset System Lib. Date: Thu, 17 Nov 2022 10:39:39 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxLeD5nnVjCpcVAA--.56818S15 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvAXoWftr1fCw13ZF18ZrWxJFy7Wrg_yoW8tr4rto W2gan7t3y8Jrs5u397Wrn3GF4IqFsYq398ZF1rJFWDJrWDZr109FWkXa48JF9aqF15XF45 GayfJ3yrJrZagF4kn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UUqG1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64 kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY 1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aV CY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x2 6I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4 IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AG Y7Cv6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s 026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF 0xvE2Ix0cI8IcVAFwI0_Ar0_tr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42 IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2 jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Content-Transfer-Encoding: 8bit This library provides interfaces related to restart and shutdown. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4054 Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li Reviewed-by: Chao 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