mirror of https://github.com/acidanthera/audk.git
152 lines
4.5 KiB
C
152 lines
4.5 KiB
C
/** @file
|
|
Base ResetSystem library implementation.
|
|
|
|
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/QemuFwCfgLib.h>
|
|
#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;
|
|
}
|