From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 1B4E77803CE for ; Mon, 11 Mar 2024 09:39:36 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=v592L1syp4T3R3D8ZeDUVZg/aAHjyR7aH7q+vKFse/c=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1710149975; v=1; b=OsMffFWYXpmkyILsN7tEupFjk95rULTzfm90b0HhWoMtcUKTb0PLWgXAbtACUIdUQdKaAa8j Zak78AUpAsfYNVu/viRS4W2A49lbAzDcZ2904Wm4h4pugaCgsz2v0eDjcc1GGIJTW/lDX+xWdo1 dVzWtqcIDhbsWzWxQs1L3ur2s0SpPvNpqCNuTvCzTvSd7xkLHffPkqh0bZtu7MuwffLZxrXqb8I BeyFOnnSSDxbFKlIbbFPZD6XOsAHVGX8/j4U3daIhUkIL8Mv7F7iKjjc26febDN5gcqskqgkaMy 89sWguUTCWnRWtMIZghDIcDI9ANo/hGhC+vr/9FLbIODQ== X-Received: by 127.0.0.2 with SMTP id GDoiYY7687511x8e52hdwZH1; Mon, 11 Mar 2024 02:39:35 -0700 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.58537.1710149974553160680 for ; Mon, 11 Mar 2024 02:39:35 -0700 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8Dx6uhT0e5lCxsXAA--.36850S3; Mon, 11 Mar 2024 17:39:31 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxVMxR0e5lHyVWAA--.33908S2; Mon, 11 Mar 2024 17:39:29 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Bibo Mao , Dongyan Qian , Xianglai Li Subject: [edk2-devel] [PATCH v1 22/26] OvmfPkg/LoongArchVirt: Add reset system library Date: Mon, 11 Mar 2024 02:39:35 -0700 Message-Id: <20240311093928.1254637-1-lichao@loongson.cn> In-Reply-To: <20240311093631.1251466-1-lichao@loongson.cn> References: <20240311093631.1251466-1-lichao@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxVMxR0e5lHyVWAA--.33908S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQANCGXuwOYA3wAhsX X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lichao@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: O9imqbt9RvhguHM2L3MQuO3vx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=OsMffFWY; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io This library provides interface related to restart and shudown the LoongArch64 virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao Reviewed-by: Bibo Mao --- .../BaseResetSystemAcpiGed.c | 148 ++++++++++ .../BaseResetSystemAcpiGedLib.inf | 36 +++ .../DxeResetSystemAcpiGed.c | 259 ++++++++++++++++++ .../DxeResetSystemAcpiGedLib.inf | 41 +++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.c | 125 +++++++++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.h | 23 ++ 6 files changed, 632 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c new file mode 100644 index 0000000000..0d94a62a38 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c @@ -0,0 +1,148 @@ +/** @file + Base ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include "ResetSystemAcpiGed.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", __func__, __LINE__)); + } + + ASSERT (mPowerManager.SleepControlRegAddr); + ASSERT (mPowerManager.SleepStatusRegAddr); + ASSERT (mPowerManager.ResetRegAddr); + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..e163b09284 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf @@ -0,0 +1,36 @@ +## @file +# Base library instance for ResetSystem library class for LoongArch +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLib + FILE_GUID = BA521997-9016-32B5-65DF-EA5F560A3837 + 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] + DebugLib + IoLib + MemoryAllocationLib + QemuFwCfgLib diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c new file mode 100644 index 0000000000..c3256ee4ec --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c @@ -0,0 +1,259 @@ +/** @file + Dxe ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include // EfiConvertPointer() +#include "ResetSystemAcpiGed.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", __func__)); + 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", __func__)); + return Status; + } + + Status = gDS->SetMemorySpaceAttributes ( + Address, + EFI_PAGE_SIZE, + EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __func__, __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", __func__, __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", __func__, mPowerManager.SleepControlRegAddr)); + ASSERT (mPowerManager.SleepControlRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.SleepControlRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + return; + } + + DEBUG ((DEBUG_INFO, "%a: sleepStatus %llx\n", __func__, mPowerManager.SleepStatusRegAddr)); + ASSERT (mPowerManager.SleepStatusRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.SleepStatusRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + return; + } + + DEBUG ((DEBUG_INFO, "%a: ResetReg %llx\n", __func__, mPowerManager.ResetRegAddr)); + ASSERT (mPowerManager.ResetRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.ResetRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __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/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..9815e2f6e7 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf @@ -0,0 +1,41 @@ +## @file +# DXE library instance for ResetSystem library class for LoongArch. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLib + FILE_GUID = F05197D5-5827-AA61-FB2D-BC69259F17A9 + 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] + DebugLib + DxeServicesTableLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeLib + +[Guids] + gEfiAcpi10TableGuid ## PRODUCES ## SystemTable + gEfiAcpiTableGuid ## PRODUCES ## SystemTable diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c new file mode 100644 index 0000000000..105382da35 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c @@ -0,0 +1,125 @@ +/** @file + ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include // CpuDeadLoop() +#include +#include +#include // ResetCold() +#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/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h new file mode 100644 index 0000000000..06e2572db0 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h @@ -0,0 +1,23 @@ +/** @file + ResetSystem lib head file. + + Copyright (c) 2024 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.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116605): https://edk2.groups.io/g/devel/message/116605 Mute This Topic: https://groups.io/mt/104859899/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-