mirror of https://github.com/acidanthera/audk.git
ArmVirtPkg/ArmVirtQemu: Implement ArmMonitorLib for QEMU specifically
Whether SMCCC calls use HVC or SMC generally depends on the exception level that the firmware executes at, but also on whether or not EL2 is implemented. This is almost always known at build time, which is why the default ArmMonitorLib used to model this as a feature PCD. However, on QEMU, things are not that simple. However, SMCCC specifies that the conduit is the same as the one used for PSCI calls (which has been retrofitted into SMCCC when it was defined). Given that QEMU provides this information via the device tree, let's use it to select the conduit, using a special ArmMonitorLib implementation. This also removes the need to set the associated PCD at runtime, given that its updated value will no longer be used. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
5bea691233
commit
059676e4fa
|
@ -92,6 +92,8 @@
|
|||
TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf
|
||||
!endif
|
||||
|
||||
ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf
|
||||
|
||||
[LibraryClasses.AARCH64]
|
||||
ArmPlatformLib|ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf
|
||||
|
||||
|
|
|
@ -82,6 +82,8 @@
|
|||
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
||||
TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf
|
||||
|
||||
ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf
|
||||
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/** @file
|
||||
Arm Monitor Library that chooses the conduit based on the PSCI node in the
|
||||
device tree provided by QEMU
|
||||
|
||||
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2024, Google LLC. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/ArmHvcLib.h>
|
||||
#include <Library/ArmMonitorLib.h>
|
||||
#include <Library/ArmSmcLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <Protocol/FdtClient.h>
|
||||
|
||||
STATIC UINT32 mArmSmcccMethod;
|
||||
|
||||
/** Library constructor.
|
||||
|
||||
Assign the global variable mArmSmcccMethod based on the PSCI node in the
|
||||
device tree.
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
ArmVirtQemuMonitorLibConstructor (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FDT_CLIENT_PROTOCOL *FdtClient;
|
||||
CONST VOID *Prop;
|
||||
|
||||
Status = gBS->LocateProtocol (
|
||||
&gFdtClientProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&FdtClient
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtClient->FindCompatibleNodeProperty (
|
||||
FdtClient,
|
||||
"arm,psci-0.2",
|
||||
"method",
|
||||
&Prop,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
|
||||
mArmSmcccMethod = 1;
|
||||
} else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
|
||||
mArmSmcccMethod = 2;
|
||||
} else {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a: Unknown SMCCC method \"%a\"\n",
|
||||
__func__,
|
||||
Prop
|
||||
));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/** Monitor call.
|
||||
|
||||
An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
|
||||
depending on the default conduit.
|
||||
|
||||
@param [in,out] Args Arguments for the HVC/SMC.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmMonitorCall (
|
||||
IN OUT ARM_MONITOR_ARGS *Args
|
||||
)
|
||||
{
|
||||
if (mArmSmcccMethod == 1) {
|
||||
ArmCallHvc ((ARM_HVC_ARGS *)Args);
|
||||
} else if (mArmSmcccMethod == 2) {
|
||||
ArmCallSmc ((ARM_SMC_ARGS *)Args);
|
||||
} else {
|
||||
ASSERT ((mArmSmcccMethod == 1) || (mArmSmcccMethod == 2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
## @file
|
||||
# Arm Monitor Library that chooses the conduit based on the PSCI node in the
|
||||
# device tree provided by QEMU
|
||||
#
|
||||
# Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
|
||||
# Copyright (c) 2024, Google LLC. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 1.29
|
||||
BASE_NAME = ArmVirtQemuMonitorLib
|
||||
FILE_GUID = 09f50ee5-2aa2-42b9-a2a0-090faeefed2b
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = ArmMonitorLib|DXE_DRIVER DXE_RUNTIME_DRIVER
|
||||
CONSTRUCTOR = ArmVirtQemuMonitorLibConstructor
|
||||
|
||||
[Sources]
|
||||
ArmVirtQemuMonitorLib.c
|
||||
|
||||
[Packages]
|
||||
ArmPkg/ArmPkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
ArmHvcLib
|
||||
ArmSmcLib
|
||||
BaseLib
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Protocols]
|
||||
gFdtClientProtocolGuid ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gFdtClientProtocolGuid
|
|
@ -226,17 +226,5 @@ PlatformPeim (
|
|||
|
||||
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
|
||||
|
||||
#ifdef MDE_CPU_AARCH64
|
||||
//
|
||||
// Set the SMCCC conduit to SMC if executing at EL2, which is typically the
|
||||
// exception level that services HVCs rather than the one that invokes them.
|
||||
//
|
||||
if (ArmReadCurrentEL () == AARCH64_EL2) {
|
||||
Status = PcdSetBoolS (PcdMonitorConduitHvc, FALSE);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue