mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-11-30 21:30:25 +00:00
Merge pull request #1314 from antonio-nino-diaz-arm/an/smccc-header
Rename 'smcc' to 'smccc'
This commit is contained in:
commit
6d8db46bec
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -10,7 +10,7 @@
|
||||
#include <context_mgmt.h>
|
||||
#include <debug.h>
|
||||
#include <platform.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include "../bl1_private.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
|
||||
*/
|
||||
@ -9,8 +9,8 @@
|
||||
#include <bl_common.h>
|
||||
#include <context.h>
|
||||
#include <el3_common_macros.S>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smcc_macros.S>
|
||||
#include <smccc_helpers.h>
|
||||
#include <smccc_macros.S>
|
||||
|
||||
.globl bl1_vector_table
|
||||
.globl bl1_entrypoint
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -9,8 +9,8 @@
|
||||
#include <bl1.h>
|
||||
#include <bl_common.h>
|
||||
#include <context.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smcc_macros.S>
|
||||
#include <smccc_helpers.h>
|
||||
#include <smccc_macros.S>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
.globl bl1_aarch32_smc_handler
|
||||
@ -93,7 +93,7 @@ func smc_handler
|
||||
* Save the GP registers.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
smcc_save_gp_mode_regs
|
||||
smccc_save_gp_mode_regs
|
||||
|
||||
/*
|
||||
* `sp` still points to `smc_ctx_t`. Save it to a register
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -218,7 +218,7 @@ unexpected_sync_exception:
|
||||
smc_handler:
|
||||
/* -----------------------------------------------------
|
||||
* Save the GP registers x0-x29.
|
||||
* TODO: Revisit to store only SMCC specified registers.
|
||||
* TODO: Revisit to store only SMCCC specified registers.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
bl save_gp_registers
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <errno.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#include "bl1_private.h"
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <errata_report.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <utils.h>
|
||||
#include <uuid.h>
|
||||
#include "bl1_private.h"
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include <context.h>
|
||||
#include <el3_common_macros.S>
|
||||
#include <runtime_svc.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smcc_macros.S>
|
||||
#include <smccc_helpers.h>
|
||||
#include <smccc_macros.S>
|
||||
#include <xlat_tables_defs.h>
|
||||
|
||||
.globl sp_min_vector_table
|
||||
@ -164,7 +164,7 @@ func sp_min_handle_smc
|
||||
/* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
|
||||
str lr, [sp, #SMC_CTX_LR_MON]
|
||||
|
||||
smcc_save_gp_mode_regs
|
||||
smccc_save_gp_mode_regs
|
||||
|
||||
clrex_on_monitor_entry
|
||||
|
||||
@ -222,7 +222,7 @@ func sp_min_handle_fiq
|
||||
/* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
|
||||
str lr, [sp, #SMC_CTX_LR_MON]
|
||||
|
||||
smcc_save_gp_mode_regs
|
||||
smccc_save_gp_mode_regs
|
||||
|
||||
clrex_on_monitor_entry
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
@ -17,7 +17,7 @@
|
||||
#include <platform_sp_min.h>
|
||||
#include <psci.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -32,7 +32,7 @@ static void *sp_min_cpu_ctx_ptr[PLATFORM_CORE_COUNT];
|
||||
static smc_ctx_t sp_min_smc_context[PLATFORM_CORE_COUNT];
|
||||
|
||||
/******************************************************************************
|
||||
* Define the smcc helper library API's
|
||||
* Define the smccc helper library API's
|
||||
*****************************************************************************/
|
||||
void *smc_get_ctx(unsigned int security_state)
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th
|
||||
arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4
|
||||
(in AArch64) when the SMC is received. These are the arguments to PSCI API as
|
||||
described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter
|
||||
and is detailed in 'smcc.h' header. It includes whether the call is from the
|
||||
and is detailed in 'smccc.h' header. It includes whether the call is from the
|
||||
secure or non-secure world. The ``cookie`` (6th argument) and the ``handle``
|
||||
(7th argument) are not used and are reserved for future use.
|
||||
|
||||
|
@ -108,7 +108,7 @@ initialization and call handler functions.
|
||||
is also used for diagnostic purposes
|
||||
|
||||
- ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in
|
||||
`smcc.h`_
|
||||
`smccc.h`_
|
||||
|
||||
- ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
|
||||
|
||||
@ -311,5 +311,5 @@ provide this information....
|
||||
.. _services: ../services
|
||||
.. _lib/psci: ../lib/psci
|
||||
.. _runtime\_svc.h: ../include/common/runtime_svc.h
|
||||
.. _smcc.h: ../include/lib/smcc.h
|
||||
.. _smccc.h: ../include/lib/smccc.h
|
||||
.. _std\_svc\_setup.c: ../services/std_svc/std_svc_setup.c
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define __RUNTIME_SVC_H__
|
||||
|
||||
#include <bl_common.h> /* to include exception types */
|
||||
#include <smcc_helpers.h> /* to include SMCC definitions */
|
||||
#include <smccc_helpers.h> /* to include SMCCC definitions */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -7,159 +7,8 @@
|
||||
#ifndef __SMCC_HELPERS_H__
|
||||
#define __SMCC_HELPERS_H__
|
||||
|
||||
#include <smcc.h>
|
||||
#if !ERROR_DEPRECATED
|
||||
#include <smccc_helpers.h>
|
||||
#endif
|
||||
|
||||
/* These are offsets to registers in smc_ctx_t */
|
||||
#define SMC_CTX_GPREG_R0 0x0
|
||||
#define SMC_CTX_GPREG_R1 0x4
|
||||
#define SMC_CTX_GPREG_R2 0x8
|
||||
#define SMC_CTX_GPREG_R3 0xC
|
||||
#define SMC_CTX_GPREG_R4 0x10
|
||||
#define SMC_CTX_GPREG_R5 0x14
|
||||
#define SMC_CTX_SP_USR 0x34
|
||||
#define SMC_CTX_SPSR_MON 0x78
|
||||
#define SMC_CTX_SP_MON 0x7C
|
||||
#define SMC_CTX_LR_MON 0x80
|
||||
#define SMC_CTX_SCR 0x84
|
||||
#define SMC_CTX_PMCR 0x88
|
||||
#define SMC_CTX_SIZE 0x90
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <cassert.h>
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
* The generic structure to save arguments and callee saved registers during
|
||||
* an SMC. Also this structure is used to store the result return values after
|
||||
* the completion of SMC service.
|
||||
*/
|
||||
typedef struct smc_ctx {
|
||||
u_register_t r0;
|
||||
u_register_t r1;
|
||||
u_register_t r2;
|
||||
u_register_t r3;
|
||||
u_register_t r4;
|
||||
u_register_t r5;
|
||||
u_register_t r6;
|
||||
u_register_t r7;
|
||||
u_register_t r8;
|
||||
u_register_t r9;
|
||||
u_register_t r10;
|
||||
u_register_t r11;
|
||||
u_register_t r12;
|
||||
/* spsr_usr doesn't exist */
|
||||
u_register_t sp_usr;
|
||||
u_register_t lr_usr;
|
||||
u_register_t spsr_irq;
|
||||
u_register_t sp_irq;
|
||||
u_register_t lr_irq;
|
||||
u_register_t spsr_fiq;
|
||||
u_register_t sp_fiq;
|
||||
u_register_t lr_fiq;
|
||||
u_register_t spsr_svc;
|
||||
u_register_t sp_svc;
|
||||
u_register_t lr_svc;
|
||||
u_register_t spsr_abt;
|
||||
u_register_t sp_abt;
|
||||
u_register_t lr_abt;
|
||||
u_register_t spsr_und;
|
||||
u_register_t sp_und;
|
||||
u_register_t lr_und;
|
||||
u_register_t spsr_mon;
|
||||
/*
|
||||
* `sp_mon` will point to the C runtime stack in monitor mode. But prior
|
||||
* to exit from SMC, this will point to the `smc_ctx_t` so that
|
||||
* on next entry due to SMC, the `smc_ctx_t` can be easily accessed.
|
||||
*/
|
||||
u_register_t sp_mon;
|
||||
u_register_t lr_mon;
|
||||
u_register_t scr;
|
||||
u_register_t pmcr;
|
||||
/*
|
||||
* The workaround for CVE-2017-5715 requires storing information in
|
||||
* the bottom 3 bits of the stack pointer. Add a padding field to
|
||||
* force the size of the struct to be a multiple of 8.
|
||||
*/
|
||||
u_register_t pad;
|
||||
} smc_ctx_t __aligned(8);
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'smc_context' structure to
|
||||
* ensure that the assembler and the compiler view of the offsets of
|
||||
* the structure members is the same.
|
||||
*/
|
||||
CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0), \
|
||||
assert_smc_ctx_greg_r0_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1), \
|
||||
assert_smc_ctx_greg_r1_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2), \
|
||||
assert_smc_ctx_greg_r2_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3), \
|
||||
assert_smc_ctx_greg_r3_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4), \
|
||||
assert_smc_ctx_greg_r4_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr), \
|
||||
assert_smc_ctx_sp_usr_offset_mismatch);
|
||||
CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon), \
|
||||
assert_smc_ctx_lr_mon_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon), \
|
||||
assert_smc_ctx_spsr_mon_offset_mismatch);
|
||||
|
||||
CASSERT((sizeof(smc_ctx_t) & 0x7) == 0, assert_smc_ctx_not_aligned);
|
||||
CASSERT(SMC_CTX_SIZE == sizeof(smc_ctx_t), assert_smc_ctx_size_mismatch);
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uintptr_t)(_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _r0) { \
|
||||
((smc_ctx_t *)(_h))->r0 = (_r0); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _r0, _r1) { \
|
||||
((smc_ctx_t *)(_h))->r1 = (_r1); \
|
||||
SMC_RET1(_h, (_r0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _r0, _r1, _r2) { \
|
||||
((smc_ctx_t *)(_h))->r2 = (_r2); \
|
||||
SMC_RET2(_h, (_r0), (_r1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _r0, _r1, _r2, _r3) { \
|
||||
((smc_ctx_t *)(_h))->r3 = (_r3); \
|
||||
SMC_RET3(_h, (_r0), (_r1), (_r2)); \
|
||||
}
|
||||
|
||||
/* Return a UUID in the SMC return registers */
|
||||
#define SMC_UUID_RET(_h, _uuid) \
|
||||
SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
|
||||
((const uint32_t *) &(_uuid))[1], \
|
||||
((const uint32_t *) &(_uuid))[2], \
|
||||
((const uint32_t *) &(_uuid))[3])
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from smc_ctx_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _r1, _r2, _r3, _r4) { \
|
||||
_r1 = ((smc_ctx_t *)_hdl)->r1; \
|
||||
_r2 = ((smc_ctx_t *)_hdl)->r2; \
|
||||
_r3 = ((smc_ctx_t *)_hdl)->r3; \
|
||||
_r4 = ((smc_ctx_t *)_hdl)->r4; \
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Helper APIs for setting and retrieving appropriate `smc_ctx_t`.
|
||||
* These functions need to implemented by the BL including this library.
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Get the pointer to `smc_ctx_t` corresponding to the security state. */
|
||||
void *smc_get_ctx(unsigned int security_state);
|
||||
|
||||
/* Set the next `smc_ctx_t` corresponding to the security state. */
|
||||
void smc_set_next_ctx(unsigned int security_state);
|
||||
|
||||
/* Get the pointer to next `smc_ctx_t` already set by `smc_set_next_ctx()`. */
|
||||
void *smc_get_next_ctx(void);
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
#endif /* __SMCC_HELPERS_H__ */
|
||||
|
@ -1,199 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#ifndef __SMCC_MACROS_S__
|
||||
#define __SMCC_MACROS_S__
|
||||
|
||||
#include <arch.h>
|
||||
#if !ERROR_DEPRECATED
|
||||
#include <smccc_macros.S>
|
||||
|
||||
/*
|
||||
* Macro to save the General purpose registers (r0 - r12), the banked
|
||||
* spsr, lr, sp registers and the `scr` register to the SMC context on entry
|
||||
* due a SMC call. The `lr` of the current mode (monitor) is expected to be
|
||||
* already saved. The `sp` must point to the `smc_ctx_t` to save to.
|
||||
* Additionally, also save the 'pmcr' register as this is updated whilst
|
||||
* executing in the secure world.
|
||||
*/
|
||||
.macro smcc_save_gp_mode_regs
|
||||
/* Save r0 - r12 in the SMC context */
|
||||
stm sp, {r0-r12}
|
||||
mov r0, sp
|
||||
add r0, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
stm r0!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_fiq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_svc
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_abt
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_und
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
/* lr_mon is already saved by caller */
|
||||
cps #MODE32_mon
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2}
|
||||
|
||||
stcopr r4, SCR
|
||||
isb
|
||||
#else
|
||||
/* Save the banked registers including the current SPSR and LR */
|
||||
mrs r4, sp_usr
|
||||
mrs r5, lr_usr
|
||||
mrs r6, spsr_irq
|
||||
mrs r7, sp_irq
|
||||
mrs r8, lr_irq
|
||||
mrs r9, spsr_fiq
|
||||
mrs r10, sp_fiq
|
||||
mrs r11, lr_fiq
|
||||
mrs r12, spsr_svc
|
||||
stm r0!, {r4-r12}
|
||||
|
||||
mrs r4, sp_svc
|
||||
mrs r5, lr_svc
|
||||
mrs r6, spsr_abt
|
||||
mrs r7, sp_abt
|
||||
mrs r8, lr_abt
|
||||
mrs r9, spsr_und
|
||||
mrs r10, sp_und
|
||||
mrs r11, lr_und
|
||||
mrs r12, spsr
|
||||
stm r0!, {r4-r12}
|
||||
/* lr_mon is already saved by caller */
|
||||
|
||||
ldcopr r4, SCR
|
||||
#define smcc_save_gp_mode_regs smccc_save_gp_mode_regs
|
||||
#endif
|
||||
str r4, [sp, #SMC_CTX_SCR]
|
||||
ldcopr r4, PMCR
|
||||
str r4, [sp, #SMC_CTX_PMCR]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to restore the `smc_ctx_t`, which includes the General purpose
|
||||
* registers and banked mode registers, and exit from the monitor mode.
|
||||
* r0 must point to the `smc_ctx_t` to restore from.
|
||||
*/
|
||||
.macro monitor_exit
|
||||
/*
|
||||
* Save the current sp and restore the smc context
|
||||
* pointer to sp which will be used for handling the
|
||||
* next SMC.
|
||||
*/
|
||||
str sp, [r0, #SMC_CTX_SP_MON]
|
||||
mov sp, r0
|
||||
|
||||
/*
|
||||
* Restore SCR first so that we access the right banked register
|
||||
* when the other mode registers are restored.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_SCR]
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Restore the PMCR register.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_PMCR]
|
||||
stcopr r1, PMCR
|
||||
|
||||
/* Restore the banked registers including the current SPSR */
|
||||
add r1, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
ldm r1!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_fiq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_svc
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_abt
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_und
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_mon
|
||||
ldm r1!, {r2}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
stcopr r4, SCR
|
||||
isb
|
||||
#else
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_usr, r4
|
||||
msr lr_usr, r5
|
||||
msr spsr_irq, r6
|
||||
msr sp_irq, r7
|
||||
msr lr_irq, r8
|
||||
msr spsr_fiq, r9
|
||||
msr sp_fiq, r10
|
||||
msr lr_fiq, r11
|
||||
msr spsr_svc, r12
|
||||
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_svc, r4
|
||||
msr lr_svc, r5
|
||||
msr spsr_abt, r6
|
||||
msr sp_abt, r7
|
||||
msr lr_abt, r8
|
||||
msr spsr_und, r9
|
||||
msr sp_und, r10
|
||||
msr lr_und, r11
|
||||
/*
|
||||
* Use the `_fsxc` suffix explicitly to instruct the assembler
|
||||
* to update all the 32 bits of SPSR. Else, by default, the
|
||||
* assembler assumes `_fc` suffix which only modifies
|
||||
* f->[31:24] and c->[7:0] bits of SPSR.
|
||||
*/
|
||||
msr spsr_fsxc, r12
|
||||
#endif
|
||||
|
||||
/* Restore the LR */
|
||||
ldr lr, [r0, #SMC_CTX_LR_MON]
|
||||
|
||||
/* Restore the rest of the general purpose registers */
|
||||
ldm r0, {r0-r12}
|
||||
eret
|
||||
.endm
|
||||
|
||||
#endif /* __SMCC_MACROS_S__ */
|
||||
|
166
include/lib/aarch32/smccc_helpers.h
Normal file
166
include/lib/aarch32/smccc_helpers.h
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __SMCCC_HELPERS_H__
|
||||
#define __SMCCC_HELPERS_H__
|
||||
|
||||
#include <smccc.h>
|
||||
|
||||
/* These are offsets to registers in smc_ctx_t */
|
||||
#define SMC_CTX_GPREG_R0 0x0
|
||||
#define SMC_CTX_GPREG_R1 0x4
|
||||
#define SMC_CTX_GPREG_R2 0x8
|
||||
#define SMC_CTX_GPREG_R3 0xC
|
||||
#define SMC_CTX_GPREG_R4 0x10
|
||||
#define SMC_CTX_GPREG_R5 0x14
|
||||
#define SMC_CTX_SP_USR 0x34
|
||||
#define SMC_CTX_SPSR_MON 0x78
|
||||
#define SMC_CTX_SP_MON 0x7C
|
||||
#define SMC_CTX_LR_MON 0x80
|
||||
#define SMC_CTX_SCR 0x84
|
||||
#define SMC_CTX_PMCR 0x88
|
||||
#define SMC_CTX_SIZE 0x90
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <cassert.h>
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
* The generic structure to save arguments and callee saved registers during
|
||||
* an SMC. Also this structure is used to store the result return values after
|
||||
* the completion of SMC service.
|
||||
*/
|
||||
typedef struct smc_ctx {
|
||||
u_register_t r0;
|
||||
u_register_t r1;
|
||||
u_register_t r2;
|
||||
u_register_t r3;
|
||||
u_register_t r4;
|
||||
u_register_t r5;
|
||||
u_register_t r6;
|
||||
u_register_t r7;
|
||||
u_register_t r8;
|
||||
u_register_t r9;
|
||||
u_register_t r10;
|
||||
u_register_t r11;
|
||||
u_register_t r12;
|
||||
/* spsr_usr doesn't exist */
|
||||
u_register_t sp_usr;
|
||||
u_register_t lr_usr;
|
||||
u_register_t spsr_irq;
|
||||
u_register_t sp_irq;
|
||||
u_register_t lr_irq;
|
||||
u_register_t spsr_fiq;
|
||||
u_register_t sp_fiq;
|
||||
u_register_t lr_fiq;
|
||||
u_register_t spsr_svc;
|
||||
u_register_t sp_svc;
|
||||
u_register_t lr_svc;
|
||||
u_register_t spsr_abt;
|
||||
u_register_t sp_abt;
|
||||
u_register_t lr_abt;
|
||||
u_register_t spsr_und;
|
||||
u_register_t sp_und;
|
||||
u_register_t lr_und;
|
||||
u_register_t spsr_mon;
|
||||
/*
|
||||
* `sp_mon` will point to the C runtime stack in monitor mode. But prior
|
||||
* to exit from SMC, this will point to the `smc_ctx_t` so that
|
||||
* on next entry due to SMC, the `smc_ctx_t` can be easily accessed.
|
||||
*/
|
||||
u_register_t sp_mon;
|
||||
u_register_t lr_mon;
|
||||
u_register_t scr;
|
||||
u_register_t pmcr;
|
||||
/*
|
||||
* The workaround for CVE-2017-5715 requires storing information in
|
||||
* the bottom 3 bits of the stack pointer. Add a padding field to
|
||||
* force the size of the struct to be a multiple of 8.
|
||||
*/
|
||||
u_register_t pad;
|
||||
} smc_ctx_t __aligned(8);
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'smc_context' structure to
|
||||
* ensure that the assembler and the compiler view of the offsets of
|
||||
* the structure members is the same.
|
||||
*/
|
||||
CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0), \
|
||||
assert_smc_ctx_greg_r0_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1), \
|
||||
assert_smc_ctx_greg_r1_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2), \
|
||||
assert_smc_ctx_greg_r2_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3), \
|
||||
assert_smc_ctx_greg_r3_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4), \
|
||||
assert_smc_ctx_greg_r4_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr), \
|
||||
assert_smc_ctx_sp_usr_offset_mismatch);
|
||||
CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon), \
|
||||
assert_smc_ctx_lr_mon_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon), \
|
||||
assert_smc_ctx_spsr_mon_offset_mismatch);
|
||||
|
||||
CASSERT((sizeof(smc_ctx_t) & 0x7) == 0, assert_smc_ctx_not_aligned);
|
||||
CASSERT(SMC_CTX_SIZE == sizeof(smc_ctx_t), assert_smc_ctx_size_mismatch);
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uintptr_t)(_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _r0) { \
|
||||
((smc_ctx_t *)(_h))->r0 = (_r0); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _r0, _r1) { \
|
||||
((smc_ctx_t *)(_h))->r1 = (_r1); \
|
||||
SMC_RET1(_h, (_r0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _r0, _r1, _r2) { \
|
||||
((smc_ctx_t *)(_h))->r2 = (_r2); \
|
||||
SMC_RET2(_h, (_r0), (_r1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _r0, _r1, _r2, _r3) { \
|
||||
((smc_ctx_t *)(_h))->r3 = (_r3); \
|
||||
SMC_RET3(_h, (_r0), (_r1), (_r2)); \
|
||||
}
|
||||
|
||||
/* Return a UUID in the SMC return registers */
|
||||
#define SMC_UUID_RET(_h, _uuid) \
|
||||
SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
|
||||
((const uint32_t *) &(_uuid))[1], \
|
||||
((const uint32_t *) &(_uuid))[2], \
|
||||
((const uint32_t *) &(_uuid))[3])
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from smc_ctx_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _r1, _r2, _r3, _r4) { \
|
||||
_r1 = ((smc_ctx_t *)_hdl)->r1; \
|
||||
_r2 = ((smc_ctx_t *)_hdl)->r2; \
|
||||
_r3 = ((smc_ctx_t *)_hdl)->r3; \
|
||||
_r4 = ((smc_ctx_t *)_hdl)->r4; \
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Helper APIs for setting and retrieving appropriate `smc_ctx_t`.
|
||||
* These functions need to implemented by the BL including this library.
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Get the pointer to `smc_ctx_t` corresponding to the security state. */
|
||||
void *smc_get_ctx(unsigned int security_state);
|
||||
|
||||
/* Set the next `smc_ctx_t` corresponding to the security state. */
|
||||
void smc_set_next_ctx(unsigned int security_state);
|
||||
|
||||
/* Get the pointer to next `smc_ctx_t` already set by `smc_set_next_ctx()`. */
|
||||
void *smc_get_next_ctx(void);
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
||||
#endif /* __SMCCC_HELPERS_H__ */
|
199
include/lib/aarch32/smccc_macros.S
Normal file
199
include/lib/aarch32/smccc_macros.S
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __SMCCC_MACROS_S__
|
||||
#define __SMCCC_MACROS_S__
|
||||
|
||||
#include <arch.h>
|
||||
|
||||
/*
|
||||
* Macro to save the General purpose registers (r0 - r12), the banked
|
||||
* spsr, lr, sp registers and the `scr` register to the SMC context on entry
|
||||
* due a SMC call. The `lr` of the current mode (monitor) is expected to be
|
||||
* already saved. The `sp` must point to the `smc_ctx_t` to save to.
|
||||
* Additionally, also save the 'pmcr' register as this is updated whilst
|
||||
* executing in the secure world.
|
||||
*/
|
||||
.macro smccc_save_gp_mode_regs
|
||||
/* Save r0 - r12 in the SMC context */
|
||||
stm sp, {r0-r12}
|
||||
mov r0, sp
|
||||
add r0, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
stm r0!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_fiq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_svc
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_abt
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_und
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
/* lr_mon is already saved by caller */
|
||||
cps #MODE32_mon
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2}
|
||||
|
||||
stcopr r4, SCR
|
||||
isb
|
||||
#else
|
||||
/* Save the banked registers including the current SPSR and LR */
|
||||
mrs r4, sp_usr
|
||||
mrs r5, lr_usr
|
||||
mrs r6, spsr_irq
|
||||
mrs r7, sp_irq
|
||||
mrs r8, lr_irq
|
||||
mrs r9, spsr_fiq
|
||||
mrs r10, sp_fiq
|
||||
mrs r11, lr_fiq
|
||||
mrs r12, spsr_svc
|
||||
stm r0!, {r4-r12}
|
||||
|
||||
mrs r4, sp_svc
|
||||
mrs r5, lr_svc
|
||||
mrs r6, spsr_abt
|
||||
mrs r7, sp_abt
|
||||
mrs r8, lr_abt
|
||||
mrs r9, spsr_und
|
||||
mrs r10, sp_und
|
||||
mrs r11, lr_und
|
||||
mrs r12, spsr
|
||||
stm r0!, {r4-r12}
|
||||
/* lr_mon is already saved by caller */
|
||||
|
||||
ldcopr r4, SCR
|
||||
#endif
|
||||
str r4, [sp, #SMC_CTX_SCR]
|
||||
ldcopr r4, PMCR
|
||||
str r4, [sp, #SMC_CTX_PMCR]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to restore the `smc_ctx_t`, which includes the General purpose
|
||||
* registers and banked mode registers, and exit from the monitor mode.
|
||||
* r0 must point to the `smc_ctx_t` to restore from.
|
||||
*/
|
||||
.macro monitor_exit
|
||||
/*
|
||||
* Save the current sp and restore the smc context
|
||||
* pointer to sp which will be used for handling the
|
||||
* next SMC.
|
||||
*/
|
||||
str sp, [r0, #SMC_CTX_SP_MON]
|
||||
mov sp, r0
|
||||
|
||||
/*
|
||||
* Restore SCR first so that we access the right banked register
|
||||
* when the other mode registers are restored.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_SCR]
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Restore the PMCR register.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_PMCR]
|
||||
stcopr r1, PMCR
|
||||
|
||||
/* Restore the banked registers including the current SPSR */
|
||||
add r1, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
ldm r1!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_fiq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_svc
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_abt
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_und
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_mon
|
||||
ldm r1!, {r2}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
stcopr r4, SCR
|
||||
isb
|
||||
#else
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_usr, r4
|
||||
msr lr_usr, r5
|
||||
msr spsr_irq, r6
|
||||
msr sp_irq, r7
|
||||
msr lr_irq, r8
|
||||
msr spsr_fiq, r9
|
||||
msr sp_fiq, r10
|
||||
msr lr_fiq, r11
|
||||
msr spsr_svc, r12
|
||||
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_svc, r4
|
||||
msr lr_svc, r5
|
||||
msr spsr_abt, r6
|
||||
msr sp_abt, r7
|
||||
msr lr_abt, r8
|
||||
msr spsr_und, r9
|
||||
msr sp_und, r10
|
||||
msr lr_und, r11
|
||||
/*
|
||||
* Use the `_fsxc` suffix explicitly to instruct the assembler
|
||||
* to update all the 32 bits of SPSR. Else, by default, the
|
||||
* assembler assumes `_fc` suffix which only modifies
|
||||
* f->[31:24] and c->[7:0] bits of SPSR.
|
||||
*/
|
||||
msr spsr_fsxc, r12
|
||||
#endif
|
||||
|
||||
/* Restore the LR */
|
||||
ldr lr, [r0, #SMC_CTX_LR_MON]
|
||||
|
||||
/* Restore the rest of the general purpose registers */
|
||||
ldm r0, {r0-r12}
|
||||
eret
|
||||
.endm
|
||||
|
||||
#endif /* __SMCCC_MACROS_S__ */
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -7,84 +7,8 @@
|
||||
#ifndef __SMCC_HELPERS_H__
|
||||
#define __SMCC_HELPERS_H__
|
||||
|
||||
#include <smcc.h>
|
||||
#if !ERROR_DEPRECATED
|
||||
#include <smccc_helpers.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <context.h>
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uint64_t) (_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _x0) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X0), (_x0)); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _x0, _x1) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X1), (_x1)); \
|
||||
SMC_RET1(_h, (_x0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _x0, _x1, _x2) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X2), (_x2)); \
|
||||
SMC_RET2(_h, (_x0), (_x1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X3), (_x3)); \
|
||||
SMC_RET3(_h, (_x0), (_x1), (_x2)); \
|
||||
}
|
||||
#define SMC_RET5(_h, _x0, _x1, _x2, _x3, _x4) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X4), (_x4)); \
|
||||
SMC_RET4(_h, (_x0), (_x1), (_x2), (_x3)); \
|
||||
}
|
||||
#define SMC_RET6(_h, _x0, _x1, _x2, _x3, _x4, _x5) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X5), (_x5)); \
|
||||
SMC_RET5(_h, (_x0), (_x1), (_x2), (_x3), (_x4)); \
|
||||
}
|
||||
#define SMC_RET7(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X6), (_x6)); \
|
||||
SMC_RET6(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5)); \
|
||||
}
|
||||
#define SMC_RET8(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X7), (_x7)); \
|
||||
SMC_RET7(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience macros to access general purpose registers using handle provided
|
||||
* to SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_GP(_h, _g) \
|
||||
read_ctx_reg((get_gpregs_ctx(_h)), (_g))
|
||||
#define SMC_SET_GP(_h, _g, _v) \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
|
||||
|
||||
/*
|
||||
* Convenience macros to access EL3 context registers using handle provided to
|
||||
* SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_EL3(_h, _e) \
|
||||
read_ctx_reg((get_el3state_ctx(_h)), (_e))
|
||||
#define SMC_SET_EL3(_h, _e, _v) \
|
||||
write_ctx_reg((get_el3state_ctx(_h)), (_e), (_v))
|
||||
|
||||
/* Return a UUID in the SMC return registers */
|
||||
#define SMC_UUID_RET(_h, _uuid) \
|
||||
SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
|
||||
((const uint32_t *) &(_uuid))[1], \
|
||||
((const uint32_t *) &(_uuid))[2], \
|
||||
((const uint32_t *) &(_uuid))[3])
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from cpu_context_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \
|
||||
do { \
|
||||
const gp_regs_t *regs = get_gpregs_ctx(_hdl); \
|
||||
_x1 = read_ctx_reg(regs, CTX_GPREG_X1); \
|
||||
_x2 = read_ctx_reg(regs, CTX_GPREG_X2); \
|
||||
_x3 = read_ctx_reg(regs, CTX_GPREG_X3); \
|
||||
_x4 = read_ctx_reg(regs, CTX_GPREG_X4); \
|
||||
} while (0)
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
#endif /* __SMCC_HELPERS_H__ */
|
||||
|
91
include/lib/aarch64/smccc_helpers.h
Normal file
91
include/lib/aarch64/smccc_helpers.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __SMCCC_HELPERS_H__
|
||||
#define __SMCCC_HELPERS_H__
|
||||
|
||||
#include <smccc.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <context.h>
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uint64_t) (_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _x0) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X0), (_x0)); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _x0, _x1) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X1), (_x1)); \
|
||||
SMC_RET1(_h, (_x0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _x0, _x1, _x2) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X2), (_x2)); \
|
||||
SMC_RET2(_h, (_x0), (_x1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X3), (_x3)); \
|
||||
SMC_RET3(_h, (_x0), (_x1), (_x2)); \
|
||||
}
|
||||
#define SMC_RET5(_h, _x0, _x1, _x2, _x3, _x4) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X4), (_x4)); \
|
||||
SMC_RET4(_h, (_x0), (_x1), (_x2), (_x3)); \
|
||||
}
|
||||
#define SMC_RET6(_h, _x0, _x1, _x2, _x3, _x4, _x5) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X5), (_x5)); \
|
||||
SMC_RET5(_h, (_x0), (_x1), (_x2), (_x3), (_x4)); \
|
||||
}
|
||||
#define SMC_RET7(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X6), (_x6)); \
|
||||
SMC_RET6(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5)); \
|
||||
}
|
||||
#define SMC_RET8(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X7), (_x7)); \
|
||||
SMC_RET7(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience macros to access general purpose registers using handle provided
|
||||
* to SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_GP(_h, _g) \
|
||||
read_ctx_reg((get_gpregs_ctx(_h)), (_g))
|
||||
#define SMC_SET_GP(_h, _g, _v) \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
|
||||
|
||||
/*
|
||||
* Convenience macros to access EL3 context registers using handle provided to
|
||||
* SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_EL3(_h, _e) \
|
||||
read_ctx_reg((get_el3state_ctx(_h)), (_e))
|
||||
#define SMC_SET_EL3(_h, _e, _v) \
|
||||
write_ctx_reg((get_el3state_ctx(_h)), (_e), (_v))
|
||||
|
||||
/* Return a UUID in the SMC return registers */
|
||||
#define SMC_UUID_RET(_h, _uuid) \
|
||||
SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
|
||||
((const uint32_t *) &(_uuid))[1], \
|
||||
((const uint32_t *) &(_uuid))[2], \
|
||||
((const uint32_t *) &(_uuid))[3])
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from cpu_context_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \
|
||||
do { \
|
||||
const gp_regs_t *regs = get_gpregs_ctx(_hdl); \
|
||||
_x1 = read_ctx_reg(regs, CTX_GPREG_X1); \
|
||||
_x2 = read_ctx_reg(regs, CTX_GPREG_X2); \
|
||||
_x3 = read_ctx_reg(regs, CTX_GPREG_X3); \
|
||||
_x4 = read_ctx_reg(regs, CTX_GPREG_X4); \
|
||||
} while (0)
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
||||
#endif /* __SMCCC_HELPERS_H__ */
|
@ -7,103 +7,8 @@
|
||||
#ifndef __SMCC_H__
|
||||
#define __SMCC_H__
|
||||
|
||||
#include <utils_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Bit definitions inside the function id as per the SMC calling convention
|
||||
******************************************************************************/
|
||||
#define FUNCID_TYPE_SHIFT U(31)
|
||||
#define FUNCID_CC_SHIFT U(30)
|
||||
#define FUNCID_OEN_SHIFT U(24)
|
||||
#define FUNCID_NUM_SHIFT U(0)
|
||||
|
||||
#define FUNCID_TYPE_MASK U(0x1)
|
||||
#define FUNCID_CC_MASK U(0x1)
|
||||
#define FUNCID_OEN_MASK U(0x3f)
|
||||
#define FUNCID_NUM_MASK U(0xffff)
|
||||
|
||||
#define FUNCID_TYPE_WIDTH U(1)
|
||||
#define FUNCID_CC_WIDTH U(1)
|
||||
#define FUNCID_OEN_WIDTH U(6)
|
||||
#define FUNCID_NUM_WIDTH U(16)
|
||||
|
||||
#define GET_SMC_CC(id) ((id >> FUNCID_CC_SHIFT) & \
|
||||
FUNCID_CC_MASK)
|
||||
#define GET_SMC_TYPE(id) ((id >> FUNCID_TYPE_SHIFT) & \
|
||||
FUNCID_TYPE_MASK)
|
||||
|
||||
#define SMC_64 U(1)
|
||||
#define SMC_32 U(0)
|
||||
#define SMC_OK U(0)
|
||||
#define SMC_UNK -1
|
||||
#define SMC_TYPE_FAST ULL(1)
|
||||
#if !ERROR_DEPRECATED
|
||||
#define SMC_TYPE_STD ULL(0)
|
||||
#include <smccc.h>
|
||||
#endif
|
||||
#define SMC_TYPE_YIELD U(0)
|
||||
#define SMC_PREEMPTED -2
|
||||
/*******************************************************************************
|
||||
* Owning entity number definitions inside the function id as per the SMC
|
||||
* calling convention
|
||||
******************************************************************************/
|
||||
#define OEN_ARM_START U(0)
|
||||
#define OEN_ARM_END U(0)
|
||||
#define OEN_CPU_START U(1)
|
||||
#define OEN_CPU_END U(1)
|
||||
#define OEN_SIP_START U(2)
|
||||
#define OEN_SIP_END U(2)
|
||||
#define OEN_OEM_START U(3)
|
||||
#define OEN_OEM_END U(3)
|
||||
#define OEN_STD_START U(4) /* Standard Service Calls */
|
||||
#define OEN_STD_END U(4)
|
||||
#define OEN_TAP_START U(48) /* Trusted Applications */
|
||||
#define OEN_TAP_END U(49)
|
||||
#define OEN_TOS_START U(50) /* Trusted OS */
|
||||
#define OEN_TOS_END U(63)
|
||||
#define OEN_LIMIT U(64)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <cassert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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)
|
||||
|
||||
#define is_caller_non_secure(_f) (!!(_f & SMC_FROM_NON_SECURE))
|
||||
#define is_caller_secure(_f) (!(is_caller_non_secure(_f)))
|
||||
|
||||
/* The macro below is used to identify a Standard Service SMC call */
|
||||
#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))
|
||||
|
||||
/*
|
||||
* Macro to define UUID for services. Apart from defining and initializing a
|
||||
* uuid_t structure, this macro verifies that the first word of the defined UUID
|
||||
* does not equal SMC_UNK. This is to ensure that the caller won't mistake the
|
||||
* returned UUID in x0 for an invalid SMC error return
|
||||
*/
|
||||
#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \
|
||||
_n0, _n1, _n2, _n3, _n4, _n5) \
|
||||
CASSERT((uint32_t)(_tl) != (uint32_t) SMC_UNK, invalid_svc_uuid);\
|
||||
static const uuid_t _name = { \
|
||||
_tl, _tm, _th, _cl, _ch, \
|
||||
{ _n0, _n1, _n2, _n3, _n4, _n5 } \
|
||||
}
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
#endif /* __SMCC_H__ */
|
||||
|
109
include/lib/smccc.h
Normal file
109
include/lib/smccc.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __SMCCC_H__
|
||||
#define __SMCCC_H__
|
||||
|
||||
#include <utils_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Bit definitions inside the function id as per the SMC calling convention
|
||||
******************************************************************************/
|
||||
#define FUNCID_TYPE_SHIFT U(31)
|
||||
#define FUNCID_CC_SHIFT U(30)
|
||||
#define FUNCID_OEN_SHIFT U(24)
|
||||
#define FUNCID_NUM_SHIFT U(0)
|
||||
|
||||
#define FUNCID_TYPE_MASK U(0x1)
|
||||
#define FUNCID_CC_MASK U(0x1)
|
||||
#define FUNCID_OEN_MASK U(0x3f)
|
||||
#define FUNCID_NUM_MASK U(0xffff)
|
||||
|
||||
#define FUNCID_TYPE_WIDTH U(1)
|
||||
#define FUNCID_CC_WIDTH U(1)
|
||||
#define FUNCID_OEN_WIDTH U(6)
|
||||
#define FUNCID_NUM_WIDTH U(16)
|
||||
|
||||
#define GET_SMC_CC(id) ((id >> FUNCID_CC_SHIFT) & \
|
||||
FUNCID_CC_MASK)
|
||||
#define GET_SMC_TYPE(id) ((id >> FUNCID_TYPE_SHIFT) & \
|
||||
FUNCID_TYPE_MASK)
|
||||
|
||||
#define SMC_64 U(1)
|
||||
#define SMC_32 U(0)
|
||||
#define SMC_OK U(0)
|
||||
#define SMC_UNK -1
|
||||
#define SMC_TYPE_FAST ULL(1)
|
||||
#if !ERROR_DEPRECATED
|
||||
#define SMC_TYPE_STD ULL(0)
|
||||
#endif
|
||||
#define SMC_TYPE_YIELD U(0)
|
||||
#define SMC_PREEMPTED -2
|
||||
/*******************************************************************************
|
||||
* Owning entity number definitions inside the function id as per the SMC
|
||||
* calling convention
|
||||
******************************************************************************/
|
||||
#define OEN_ARM_START U(0)
|
||||
#define OEN_ARM_END U(0)
|
||||
#define OEN_CPU_START U(1)
|
||||
#define OEN_CPU_END U(1)
|
||||
#define OEN_SIP_START U(2)
|
||||
#define OEN_SIP_END U(2)
|
||||
#define OEN_OEM_START U(3)
|
||||
#define OEN_OEM_END U(3)
|
||||
#define OEN_STD_START U(4) /* Standard Service Calls */
|
||||
#define OEN_STD_END U(4)
|
||||
#define OEN_TAP_START U(48) /* Trusted Applications */
|
||||
#define OEN_TAP_END U(49)
|
||||
#define OEN_TOS_START U(50) /* Trusted OS */
|
||||
#define OEN_TOS_END U(63)
|
||||
#define OEN_LIMIT U(64)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <cassert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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)
|
||||
|
||||
#define is_caller_non_secure(_f) (!!(_f & SMC_FROM_NON_SECURE))
|
||||
#define is_caller_secure(_f) (!(is_caller_non_secure(_f)))
|
||||
|
||||
/* The macro below is used to identify a Standard Service SMC call */
|
||||
#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))
|
||||
|
||||
/*
|
||||
* Macro to define UUID for services. Apart from defining and initializing a
|
||||
* uuid_t structure, this macro verifies that the first word of the defined UUID
|
||||
* does not equal SMC_UNK. This is to ensure that the caller won't mistake the
|
||||
* returned UUID in x0 for an invalid SMC error return
|
||||
*/
|
||||
#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \
|
||||
_n0, _n1, _n2, _n3, _n4, _n5) \
|
||||
CASSERT((uint32_t)(_tl) != (uint32_t) SMC_UNK, invalid_svc_uuid);\
|
||||
static const uuid_t _name = { \
|
||||
_tl, _tm, _th, _cl, _ch, \
|
||||
{ _n0, _n1, _n2, _n3, _n4, _n5 } \
|
||||
}
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
#endif /* __SMCCC_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
|
||||
*/
|
||||
@ -13,7 +13,7 @@
|
||||
#include <context_mgmt.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
@ -15,7 +15,7 @@
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <pubsub_events.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <spe.h>
|
||||
#include <string.h>
|
||||
#include <sve.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -7,7 +7,7 @@
|
||||
#include <debug.h>
|
||||
#include <platform.h>
|
||||
#include <pmf.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
|
||||
/*
|
||||
* This function is responsible for handling all PMF SMC calls.
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <platform.h>
|
||||
#include <pmf.h>
|
||||
#include <runtime_instr.h>
|
||||
#include <smcc.h>
|
||||
#include <smccc.h>
|
||||
#include <string.h>
|
||||
#include "psci_private.h"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@ -10,7 +10,7 @@
|
||||
#include <context_mgmt.h>
|
||||
#include <plat_arm.h>
|
||||
#include <psci.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <cdn_dp.h>
|
||||
#include <smcc.h>
|
||||
#include <smccc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <debug.h>
|
||||
#include <errata_report.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <smcc.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <workaround_cve_2017_5715.h>
|
||||
|
||||
static int32_t smccc_version(void)
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include <platform.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <secure_partition.h>
|
||||
#include <smcc.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <spinlock.h>
|
||||
#include <spm_svc.h>
|
||||
#include <utils.h>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <runtime_instr.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <sdei.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smccc_helpers.h>
|
||||
#include <spm_svc.h>
|
||||
#include <std_svc.h>
|
||||
#include <stdint.h>
|
||||
|
Loading…
Reference in New Issue
Block a user