diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index eb0a366d1..cae94b5d8 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -978,8 +978,8 @@ manipulation; and with ``flags`` indicating the security state of the caller. Th framework finally sets up the execution stack for the handler, and invokes the services ``handle()`` function. -On return from the handler the result registers are populated in X0-X3 before -restoring the stack and CPU state and returning from the original SMC. +On return from the handler the result registers are populated in X0-X7 as needed +before restoring the stack and CPU state and returning from the original SMC. Exception Handling Framework ---------------------------- diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst index 6a06025ef..5375b659d 100644 --- a/docs/getting_started/rt-svc-writers-guide.rst +++ b/docs/getting_started/rt-svc-writers-guide.rst @@ -244,17 +244,35 @@ The handler is responsible for: TF-A expects owning entities to follow this recommendation. -#. Returning the result to the caller. The `SMCCC`_ allows for up to 256 bits - of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The - framework provides a family of macros to set the multi-register return - value and complete the handler: +#. Returning the result to the caller. Based on `SMCCC`_ spec, results are + returned in W0-W7(X0-X7) registers for SMC32(SMC64) calls from AArch64 + state. Results are returned in R0-R7 registers for SMC32 calls from AArch32 + state. The framework provides a family of macros to set the multi-register + return value and complete the handler: .. code:: c + AArch64 state: + SMC_RET1(handle, x0); SMC_RET2(handle, x0, x1); SMC_RET3(handle, x0, x1, x2); SMC_RET4(handle, x0, x1, x2, x3); + SMC_RET5(handle, x0, x1, x2, x3, x4); + SMC_RET6(handle, x0, x1, x2, x3, x4, x5); + SMC_RET7(handle, x0, x1, x2, x3, x4, x5, x6); + SMC_RET8(handle, x0, x1, x2, x3, x4, x5, x6, x7); + + AArch32 state: + + SMC_RET1(handle, r0); + SMC_RET2(handle, r0, r1); + SMC_RET3(handle, r0, r1, r2); + SMC_RET4(handle, r0, r1, r2, r3); + SMC_RET5(handle, r0, r1, r2, r3, r4); + SMC_RET6(handle, r0, r1, r2, r3, r4, r5); + SMC_RET7(handle, r0, r1, r2, r3, r4, r5, r6); + SMC_RET8(handle, r0, r1, r2, r3, r4, r5, r6, r7); The ``cookie`` parameter to the handler is reserved for future use and can be ignored. The ``handle`` is returned by the SMC handler - completion of the diff --git a/include/arch/aarch32/smccc_helpers.h b/include/arch/aarch32/smccc_helpers.h index b2ee3cfe0..2ce7874ef 100644 --- a/include/arch/aarch32/smccc_helpers.h +++ b/include/arch/aarch32/smccc_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -130,6 +130,22 @@ CASSERT(SMC_CTX_SIZE == sizeof(smc_ctx_t), assert_smc_ctx_size_mismatch); ((smc_ctx_t *)(_h))->r3 = (_r3); \ SMC_RET3(_h, (_r0), (_r1), (_r2)); \ } +#define SMC_RET5(_h, _r0, _r1, _r2, _r3, _r4) { \ + ((smc_ctx_t *)(_h))->r4 = (_r4); \ + SMC_RET4(_h, (_r0), (_r1), (_r2), (_r3)); \ +} +#define SMC_RET6(_h, _r0, _r1, _r2, _r3, _r4, _r5) { \ + ((smc_ctx_t *)(_h))->r5 = (_r5); \ + SMC_RET5(_h, (_r0), (_r1), (_r2), (_r3), (_r4)); \ +} +#define SMC_RET7(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6) { \ + ((smc_ctx_t *)(_h))->r6 = (_r6); \ + SMC_RET6(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5)); \ +} +#define SMC_RET8(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) { \ + ((smc_ctx_t *)(_h))->r7 = (_r7); \ + SMC_RET7(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5), (_r6)); \ +} /* * Helper macro to retrieve the SMC parameters from smc_ctx_t. diff --git a/include/lib/smccc.h b/include/lib/smccc.h index 76e60231f..dd3c578dc 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -20,7 +20,7 @@ SMCCC_VERSION_MINOR_SHIFT)) #define SMCCC_MAJOR_VERSION U(1) -#define SMCCC_MINOR_VERSION U(1) +#define SMCCC_MINOR_VERSION U(2) /******************************************************************************* * Bit definitions inside the function id as per the SMC calling convention @@ -83,6 +83,12 @@ #define SMC_UNK -1 #define SMC_PREEMPTED -2 /* Not defined by the SMCCC */ +/* Return codes for Arm Architecture Service SMC calls */ +#define SMC_ARCH_CALL_SUCCESS 0 +#define SMC_ARCH_CALL_NOT_SUPPORTED -1 +#define SMC_ARCH_CALL_NOT_REQUIRED -2 +#define SMC_ARCH_CALL_INVAL_PARAM -3 + /* Various flags passed to SMC handlers */ #define SMC_FROM_SECURE (U(0) << 0) #define SMC_FROM_NON_SECURE (U(1) << 0)