diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 2db4856..886d301 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,6 +23,7 @@ bl31/bl31_context_mgmt.c \ common/runtime_svc.c \ plat/common/aarch64/platform_mp_stack.S \ + services/arm_arch_svc/arm_arch_svc_setup.c \ services/std_svc/std_svc_setup.c \ ${PSCI_LIB_SOURCES} \ ${SPM_SOURCES} \ diff --git a/include/lib/smcc.h b/include/lib/smcc.h index 13b1e7a..a273b3a 100644 --- a/include/lib/smcc.h +++ b/include/lib/smcc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -67,6 +67,11 @@ #include #include +#define SMCCC_MAJOR_VERSION U(1) +#define SMCCC_MINOR_VERSION U(1) + +#define MAKE_SMCCC_VERSION(_major, _minor) (((_major) << 16) | (_minor)) + /* Various flags passed to SMC handlers */ #define SMC_FROM_SECURE (U(0) << 0) #define SMC_FROM_NON_SECURE (U(1) << 0) @@ -78,6 +83,10 @@ #define is_std_svc_call(_fid) ((((_fid) >> FUNCID_OEN_SHIFT) & \ FUNCID_OEN_MASK) == OEN_STD_START) +/* The macro below is used to identify a Arm Architectural Service SMC call */ +#define is_arm_arch_svc_call(_fid) ((((_fid) >> FUNCID_OEN_SHIFT) & \ + FUNCID_OEN_MASK) == OEN_ARM_START) + /* The macro below is used to identify a valid Fast SMC call */ #define is_valid_fast_smc(_fid) ((!(((_fid) >> 16) & U(0xff))) && \ (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)) diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h new file mode 100644 index 0000000..2961601 --- /dev/null +++ b/include/services/arm_arch_svc.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __ARM_ARCH_SVC_H__ +#define __ARM_ARCH_SVC_H__ + +#define SMCCC_VERSION U(0x80000000) +#define SMCCC_ARCH_FEATURES U(0x80000001) +#define SMCCC_ARCH_WORKAROUND_1 U(0x80008000) + +#endif /* __ARM_ARCH_SVC_H__ */ diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c new file mode 100644 index 0000000..eedac86 --- /dev/null +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static int32_t smccc_version(void) +{ + return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION); +} + +static int32_t smccc_arch_features(u_register_t arg) +{ + switch (arg) { + case SMCCC_VERSION: + case SMCCC_ARCH_FEATURES: + return SMC_OK; +#if WORKAROUND_CVE_2017_5715 + case SMCCC_ARCH_WORKAROUND_1: + return SMC_OK; +#endif + default: + return SMC_UNK; + } +} + +/* + * Top-level Arm Architectural Service SMC handler. + */ +uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + switch (smc_fid) { + case SMCCC_VERSION: + SMC_RET1(handle, smccc_version()); + case SMCCC_ARCH_FEATURES: + SMC_RET1(handle, smccc_arch_features(x1)); +#if WORKAROUND_CVE_2017_5715 + case SMCCC_ARCH_WORKAROUND_1: + /* + * The workaround has already been applied on affected PEs + * during entry to EL3. On unaffected PEs, this function + * has no effect. + */ + SMC_RET0(handle); +#endif + default: + WARN("Unimplemented Arm Architecture Service Call: 0x%x \n", + smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Register Standard Service Calls as runtime service */ +DECLARE_RT_SVC( + arm_arch_svc, + OEN_ARM_START, + OEN_ARM_END, + SMC_TYPE_FAST, + NULL, + arm_arch_svc_smc_handler +);