/** @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 "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. **/ STATIC 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 EFI_SUCCESS Successfully find out all the required information. @retval EFI_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 EFI_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 EFI_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 EFI_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 EFI_SUCCESS; } /** The constructor function to initialize mPowerManager. @retval EFI_SUCCESS Initialize mPowerManager success. @retval EFI_NOT_FOUND Failed to initialize mPowerManager. **/ EFI_STATUS EFI_API 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; }