/** @file | |
Install Acpi tables for Cloud Hypervisor | |
Copyright (c) 2021, Arm Limited. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Library/BaseLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <IndustryStandard/Acpi63.h> | |
#include <Protocol/AcpiTable.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Library/UefiDriverEntryPoint.h> | |
#include <Library/DebugLib.h> | |
/** | |
Find Acpi table Protocol and return it | |
@return AcpiTable Protocol, which is used to handle Acpi Table, on SUCCESS or NULL on FAILURE. | |
**/ | |
STATIC | |
EFI_ACPI_TABLE_PROTOCOL * | |
FindAcpiTableProtocol ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_ACPI_TABLE_PROTOCOL *AcpiTable; | |
Status = gBS->LocateProtocol ( | |
&gEfiAcpiTableProtocolGuid, | |
NULL, | |
(VOID **)&AcpiTable | |
); | |
ASSERT_EFI_ERROR (Status); | |
return AcpiTable; | |
} | |
/** Install Acpi tables for Cloud Hypervisor | |
@param [in] AcpiProtocol Acpi Protocol which is used to install Acpi tables | |
@return EFI_SUCCESS The table was successfully inserted. | |
@return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL | |
and the size field embedded in the ACPI table pointed | |
by AcpiTablePtr or DsdtPtr are not in sync. | |
@return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request. | |
@return EFI_NOT_FOUND DSDT table not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
InstallCloudHvAcpiTables ( | |
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol | |
) | |
{ | |
UINTN InstalledKey; | |
UINTN TableSize; | |
UINTN AcpiTableLength; | |
UINT64 RsdpPtr; | |
UINT64 XsdtPtr; | |
UINT64 TableOffset; | |
UINT64 AcpiTablePtr; | |
UINT64 *DsdtPtr; | |
EFI_STATUS Status; | |
if (AcpiProtocol == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
RsdpPtr = PcdGet64 (PcdCloudHvAcpiRsdpBaseAddress); | |
XsdtPtr = ((EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER *)RsdpPtr)->XsdtAddress; | |
AcpiTableLength = ((EFI_ACPI_COMMON_HEADER *)XsdtPtr)->Length; | |
TableOffset = sizeof (EFI_ACPI_DESCRIPTION_HEADER); | |
DsdtPtr = NULL; | |
while (TableOffset < AcpiTableLength) { | |
AcpiTablePtr = *(UINT64 *)(XsdtPtr + TableOffset); | |
TableSize = ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Length; | |
// | |
// Install ACPI tables from XSDT | |
// | |
Status = AcpiProtocol->InstallAcpiTable ( | |
AcpiProtocol, | |
(VOID *)AcpiTablePtr, | |
TableSize, | |
&InstalledKey | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Get DSDT from FADT | |
// | |
if ((DsdtPtr == NULL) && | |
(EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE == | |
((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Signature)) | |
{ | |
DsdtPtr = (UINT64 *)((EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *)AcpiTablePtr)->XDsdt; | |
} | |
TableOffset += sizeof (UINT64); | |
} // while | |
if (DsdtPtr == NULL) { | |
DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__)); | |
return EFI_NOT_FOUND; | |
} | |
// | |
// Install DSDT table | |
// | |
TableSize = ((EFI_ACPI_COMMON_HEADER *)DsdtPtr)->Length; | |
Status = AcpiProtocol->InstallAcpiTable ( | |
AcpiProtocol, | |
DsdtPtr, | |
TableSize, | |
&InstalledKey | |
); | |
return Status; | |
} | |
/** Entry point for Cloud Hypervisor Platform Dxe | |
@param [in] ImageHandle Handle for this image. | |
@param [in] SystemTable Pointer to the EFI system table. | |
@return EFI_SUCCESS The table was successfully inserted. | |
@return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL | |
and the size field embedded in the ACPI table pointed to | |
by AcpiTablePtr or DsdtPtr are not in sync. | |
@return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request. | |
@return EFI_NOT_FOUND DSDT table not found | |
**/ | |
EFI_STATUS | |
EFIAPI | |
CloudHvAcpiPlatformEntryPoint ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
Status = InstallCloudHvAcpiTables (FindAcpiTableProtocol ()); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"%a: Fail to install Acpi table: %r\n", | |
__func__, | |
Status | |
)); | |
CpuDeadLoop (); | |
} | |
return EFI_SUCCESS; | |
} |