blob: 94a2e4fb54a96193bbc9f413952e80762773013f [file] [log] [blame]
David Hu50711e32019-06-12 18:32:30 +08001/*
Ronald Cron312be682019-09-23 09:27:33 +02002 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
David Hu50711e32019-06-12 18:32:30 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7#ifndef __TFM_ARCH_V8M_H__
8#define __TFM_ARCH_V8M_H__
9
10#include <stdint.h>
11#include <stdbool.h>
12
13#include "cmsis_compiler.h"
14
Summer Qind2ad7e72020-01-06 18:16:35 +080015#define EXC_RETURN_INDICATOR (0xFF << 24)
16#define EXC_RETURN_RES1 (0x1FFFF << 7)
David Hu50711e32019-06-12 18:32:30 +080017#define EXC_RETURN_SECURE_STACK (1 << 6)
Summer Qind2ad7e72020-01-06 18:16:35 +080018#define EXC_RETURN_STACK_RULE (1 << 5)
David Hu50711e32019-06-12 18:32:30 +080019#define EXC_RETURN_FPU_FRAME_BASIC (1 << 4)
20#define EXC_RETURN_MODE_THREAD (1 << 3)
21#define EXC_RETURN_STACK_PROCESS (1 << 2)
Summer Qind2ad7e72020-01-06 18:16:35 +080022#define EXC_RETURN_RES0 (0 << 1)
David Hu50711e32019-06-12 18:32:30 +080023#define EXC_RETURN_EXC_SECURE (1)
24
25/* Initial EXC_RETURN value in LR when a thread is loaded at the first time */
Summer Qind2ad7e72020-01-06 18:16:35 +080026#define EXC_RETURN_THREAD_S_PSP \
27 EXC_RETURN_INDICATOR | EXC_RETURN_RES1 | \
28 EXC_RETURN_SECURE_STACK | EXC_RETURN_STACK_RULE | \
29 EXC_RETURN_FPU_FRAME_BASIC | EXC_RETURN_MODE_THREAD | \
30 EXC_RETURN_STACK_PROCESS | EXC_RETURN_RES0 | \
31 EXC_RETURN_EXC_SECURE
David Hu50711e32019-06-12 18:32:30 +080032
Ronald Cron312be682019-09-23 09:27:33 +020033#if defined(__ARM_ARCH_8_1M_MAIN__) || defined(__ARM_ARCH_8M_MAIN__)
Summer Qind2ad7e72020-01-06 18:16:35 +080034struct tfm_arch_ctx_t {
David Hu50711e32019-06-12 18:32:30 +080035 uint32_t r4;
36 uint32_t r5;
37 uint32_t r6;
38 uint32_t r7;
39 uint32_t r8;
40 uint32_t r9;
41 uint32_t r10;
42 uint32_t r11;
43 uint32_t sp;
44 uint32_t sp_limit;
45 uint32_t dummy;
46 uint32_t lr;
47};
48#elif defined(__ARM_ARCH_8M_BASE__)
Summer Qind2ad7e72020-01-06 18:16:35 +080049struct tfm_arch_ctx_t {
David Hu50711e32019-06-12 18:32:30 +080050 uint32_t r8;
51 uint32_t r9;
52 uint32_t r10;
53 uint32_t r11;
54 uint32_t r4;
55 uint32_t r5;
56 uint32_t r6;
57 uint32_t r7;
58 uint32_t sp;
59 uint32_t sp_limit;
60 uint32_t dummy;
61 uint32_t lr;
62};
63#endif
64
65/* Disable NS exceptions by setting NS PRIMASK to 1 */
66#define TFM_NS_EXC_DISABLE() __TZ_set_PRIMASK_NS(1)
67/* Enable NS exceptions by setting NS PRIMASK to 0 */
68#define TFM_NS_EXC_ENABLE() __TZ_set_PRIMASK_NS(0)
69
David Hu141fe8d2019-06-24 13:24:00 +080070/**
71 * \brief Check whether Secure or Non-secure stack is used to restore stack
72 * frame on exception return.
73 *
74 * \param[in] lr LR register containing the EXC_RETURN value.
75 *
76 * \retval true Secure stack is used to restore stack frame on
77 * exception return.
78 * \retval false Non-secure stack is used to restore stack frame on
79 * exception return.
80 */
81__STATIC_INLINE bool is_return_secure_stack(uint32_t lr)
82{
83 return (lr & EXC_RETURN_SECURE_STACK);
84}
85
David Hue05b6a62019-06-12 18:45:28 +080086/**
David Hub8dada52019-07-02 18:08:23 +080087 * \brief Check whether the stack frame for this exception has space allocated
88 * for Floating Point(FP) state information.
89 *
90 * \param[in] lr LR register containing the EXC_RETURN value.
91 *
92 * \retval true The stack allocates space for FP information
93 * \retval false The stack doesn't allocate space for FP information
94 */
95__STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr)
96{
97 return (lr & EXC_RETURN_FPU_FRAME_BASIC) ? false : true;
98}
99
100/**
David Hue05b6a62019-06-12 18:45:28 +0800101 * \brief Set PSPLIM register.
102 *
103 * \param[in] psplim Register value to be written into PSPLIM.
104 */
105__STATIC_INLINE void tfm_arch_set_psplim(uint32_t psplim)
106{
David Huf363fe92019-07-02 13:03:30 +0800107 __set_PSPLIM(psplim);
108}
109
110/**
Summer Qind2ad7e72020-01-06 18:16:35 +0800111 * \brief Update architecture context value into hardware
Ken Liu490281d2019-12-30 15:55:26 +0800112 *
Summer Qind2ad7e72020-01-06 18:16:35 +0800113 * \param[in] p_actx Pointer of context data
Ken Liu490281d2019-12-30 15:55:26 +0800114 */
Summer Qind2ad7e72020-01-06 18:16:35 +0800115__STATIC_INLINE void tfm_arch_update_ctx(struct tfm_arch_ctx_t *p_actx)
Ken Liu490281d2019-12-30 15:55:26 +0800116{
Summer Qind2ad7e72020-01-06 18:16:35 +0800117 __set_PSP(p_actx->sp);
118 __set_PSPLIM(p_actx->sp_limit);
Ken Liu490281d2019-12-30 15:55:26 +0800119}
120
121/**
David Huf363fe92019-07-02 13:03:30 +0800122 * \brief Set MSPLIM register.
123 *
124 * \param[in] msplim Register value to be written into MSPLIM.
125 */
126__STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim)
127{
128 __set_MSPLIM(msplim);
David Hue05b6a62019-06-12 18:45:28 +0800129}
130
David Hu50711e32019-06-12 18:32:30 +0800131#endif