arch/arm64: Support calling a trusted monitor
Implement support for generating an SMC to call a trusted monitor. Some functions are provided to read the SoC ID from the monitor, if supported. Change-Id: I158db0b971aba722b3995d52162146aa406d1644 Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/78284 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
committed by
Lean Sheng Tan
parent
c2ed5eaa12
commit
f27b22ab4e
@@ -30,6 +30,9 @@ bootblock-y += eabi_compat.c
|
||||
decompressor-$(CONFIG_ARM64_USE_ARCH_TIMER) += arch_timer.c
|
||||
bootblock-$(CONFIG_ARM64_USE_ARCH_TIMER) += arch_timer.c
|
||||
bootblock-y += transition.c transition_asm.S
|
||||
ifneq ($(CONFIG_ARM64_CURRENT_EL),3)
|
||||
bootblock-y += smc.c smc_asm.S
|
||||
endif
|
||||
|
||||
decompressor-y += memset.S
|
||||
bootblock-y += memset.S
|
||||
@@ -69,6 +72,9 @@ verstage-y += memcpy.S
|
||||
verstage-y += memmove.S
|
||||
|
||||
verstage-y += transition.c transition_asm.S
|
||||
ifneq ($(CONFIG_ARM64_CURRENT_EL),3)
|
||||
verstage-y += smc.c smc_asm.S
|
||||
endif
|
||||
|
||||
endif # CONFIG_ARCH_VERSTAGE_ARM64
|
||||
|
||||
@@ -88,6 +94,9 @@ romstage-y += memmove.S
|
||||
romstage-y += ramdetect.c
|
||||
romstage-y += romstage.c
|
||||
romstage-y += transition.c transition_asm.S
|
||||
ifneq ($(CONFIG_ARM64_CURRENT_EL),3)
|
||||
romstage-y += smc.c smc_asm.S
|
||||
endif
|
||||
|
||||
rmodules_arm64-y += memset.S
|
||||
rmodules_arm64-y += memcpy.S
|
||||
@@ -109,6 +118,7 @@ ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM64),y)
|
||||
ramstage-y += div0.c
|
||||
ramstage-y += eabi_compat.c
|
||||
ramstage-y += boot.c
|
||||
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
|
||||
ramstage-y += tables.c
|
||||
ramstage-y += ramdetect.c
|
||||
ramstage-$(CONFIG_ARM64_USE_ARCH_TIMER) += arch_timer.c
|
||||
@@ -117,6 +127,9 @@ ramstage-y += memcpy.S
|
||||
ramstage-y += memmove.S
|
||||
ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += bl31.c
|
||||
ramstage-y += transition.c transition_asm.S
|
||||
ifneq ($(CONFIG_ARM64_CURRENT_EL),3)
|
||||
ramstage-y += smc.c smc_asm.S
|
||||
endif
|
||||
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
|
||||
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
|
||||
ramstage-y += dma.c
|
||||
|
52
src/arch/arm64/include/armv8/arch/smc.h
Normal file
52
src/arch/arm64/include/armv8/arch/smc.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef ARM_ARM64_SMC_H
|
||||
#define ARM_ARM64_SMC_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
uint64_t smc(uint32_t function_id, uint64_t arg1, uint64_t arg2, uint64_t arg3,
|
||||
uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7);
|
||||
|
||||
#define smc_call0(function_id) smc(function_id, 0, 0, 0, 0, 0, 0, 0)
|
||||
#define smc_call1(function_id, a1) smc(function_id, a1, 0, 0, 0, 0, 0, 0)
|
||||
#define smc_call2(function_id, a1, a2) smc(function_id, a1, a2, 0, 0, 0, 0, 0)
|
||||
#define smc_call3(function_id, a1, a2, a3) smc(function_id, a1, a2, a3, 0, 0, 0, 0)
|
||||
|
||||
/* Documented in https://developer.arm.com/documentation/den0022/ */
|
||||
enum psci_return_values {
|
||||
PSCI_SUCCESS = 0,
|
||||
PSCI_NOT_SUPPORTED = -1,
|
||||
PSCI_INVALID_PARAMETERS = -2,
|
||||
PSCI_DENIED = -3,
|
||||
PSCI_ALREADY_ON = -4,
|
||||
PSCI_ON_PENDING = -5,
|
||||
PSCI_INTERNAL_FAILURE = -6,
|
||||
PSCI_NOT_PRESENT = -7,
|
||||
PSCI_DISABLED = -8,
|
||||
PSCI_INVALID_ADDRESS = -9,
|
||||
};
|
||||
|
||||
/* PSCI functions */
|
||||
#define PSCI_VERSION 0x84000000
|
||||
#define PSCI_FEATURES 0x8400000a
|
||||
|
||||
/* Documented in https://developer.arm.com/documentation/den0028/ */
|
||||
enum smccc_return_values {
|
||||
SMC_SUCCESS = 0,
|
||||
SMC_NOT_SUPPORTED = -1,
|
||||
SMC_NOT_REQUIRED = -2,
|
||||
SMC_INVALID_PARAMETER = -3,
|
||||
};
|
||||
|
||||
/* SMCCC functions */
|
||||
#define SMCCC_VERSION 0x80000000
|
||||
#define SMCCC_ARCH_FEATURES 0x80000001
|
||||
#define SMCCC_ARCH_SOC_ID 0x80000002
|
||||
#define SMCCC_GET_SOC_VERSION 0
|
||||
#define SMCCC_GET_SOC_REVISION 1
|
||||
|
||||
uint8_t smccc_supports_arch_soc_id(void);
|
||||
enum cb_err smccc_arch_soc_id(uint32_t *jep106code, uint32_t *soc_revision);
|
||||
|
||||
#endif /* ARM_ARM64_SMC_H */
|
66
src/arch/arm64/smc.c
Normal file
66
src/arch/arm64/smc.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/smc.h>
|
||||
#include <console/console.h>
|
||||
#include <types.h>
|
||||
|
||||
/* Assumes at least a PSCI implementation is present */
|
||||
uint8_t smccc_supports_arch_soc_id(void)
|
||||
{
|
||||
static uint8_t supported = 0xff;
|
||||
uint64_t smc_ret;
|
||||
|
||||
if (supported != 0xff)
|
||||
return supported;
|
||||
|
||||
// PSCI_FEATURES mandatory from PSCI 1.0
|
||||
smc_ret = smc_call0(PSCI_VERSION);
|
||||
if (smc_ret < 0x10000)
|
||||
goto fail;
|
||||
|
||||
smc_ret = smc_call1(PSCI_FEATURES, SMCCC_VERSION);
|
||||
if (smc_ret == PSCI_NOT_SUPPORTED)
|
||||
goto fail;
|
||||
|
||||
// SMCCC_ARCH_FEATURES supported from SMCCC 1.1
|
||||
smc_ret = smc_call0(SMCCC_VERSION);
|
||||
if (smc_ret < 0x10001)
|
||||
goto fail;
|
||||
|
||||
smc_ret = smc_call1(SMCCC_ARCH_FEATURES, SMCCC_ARCH_SOC_ID);
|
||||
if (smc_ret != SMC_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
supported = 1;
|
||||
return supported;
|
||||
|
||||
fail:
|
||||
supported = 0;
|
||||
return supported;
|
||||
}
|
||||
|
||||
enum cb_err smccc_arch_soc_id(uint32_t *jep106code, uint32_t *soc_revision)
|
||||
{
|
||||
uint64_t smc_ret;
|
||||
|
||||
if (jep106code == NULL || soc_revision == NULL)
|
||||
return CB_ERR_ARG;
|
||||
|
||||
smc_ret = smc_call1(SMCCC_ARCH_SOC_ID, SMCCC_GET_SOC_VERSION);
|
||||
if (smc_ret != SMC_INVALID_PARAMETER)
|
||||
*jep106code = smc_ret;
|
||||
else
|
||||
*jep106code = -1;
|
||||
|
||||
smc_ret = smc_call1(SMCCC_ARCH_SOC_ID, SMCCC_GET_SOC_REVISION);
|
||||
if (smc_ret != SMC_INVALID_PARAMETER)
|
||||
*soc_revision = smc_ret;
|
||||
else
|
||||
*soc_revision = -1;
|
||||
|
||||
if (*jep106code == -1 || *soc_revision == -1) {
|
||||
printk(BIOS_ERR, "SMCCC_ARCH_SOC_ID failed!\n");
|
||||
return CB_ERR;
|
||||
} else
|
||||
return CB_SUCCESS;
|
||||
}
|
9
src/arch/arm64/smc_asm.S
Normal file
9
src/arch/arm64/smc_asm.S
Normal file
@@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
ENTRY(smc)
|
||||
/* W0, X1-X7 passed as arguments. Function ID is always W0. */
|
||||
smc #0
|
||||
ret /* X0 passed back as return value */
|
||||
ENDPROC(smc)
|
Reference in New Issue
Block a user