David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 1 | /* |
Ronald Cron | 312be68 | 2019-09-23 09:27:33 +0200 | [diff] [blame] | 2 | * Copyright (c) 2018-2020, Arm Limited. All rights reserved. |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | * |
| 6 | */ |
| 7 | #ifndef __TFM_ARCH_H__ |
| 8 | #define __TFM_ARCH_H__ |
| 9 | |
| 10 | /* This header file collects the architecture related operations. */ |
| 11 | |
Ken Liu | 1d96c13 | 2019-12-31 15:51:30 +0800 | [diff] [blame] | 12 | #include <stddef.h> |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 13 | #include <inttypes.h> |
Kevin Peng | bc5e5aa | 2019-10-16 10:55:17 +0800 | [diff] [blame] | 14 | #include "tfm_hal_device_header.h" |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 15 | #include "cmsis_compiler.h" |
| 16 | |
Ronald Cron | 312be68 | 2019-09-23 09:27:33 +0200 | [diff] [blame] | 17 | #if defined(__ARM_ARCH_8_1M_MAIN__) || \ |
| 18 | defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__) |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 19 | #include "tfm_arch_v8m.h" |
David Hu | 40455c9 | 2019-07-02 14:31:34 +0800 | [diff] [blame] | 20 | #elif defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7M__) || \ |
| 21 | defined(__ARM_ARCH_7EM__) |
| 22 | #include "tfm_arch_v6m_v7m.h" |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 23 | #else |
| 24 | #error "Unsupported ARM Architecture." |
| 25 | #endif |
| 26 | |
| 27 | #define XPSR_T32 0x01000000 |
| 28 | |
| 29 | /* General core state context */ |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 30 | struct tfm_state_context_t { |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 31 | uint32_t r0; |
| 32 | uint32_t r1; |
| 33 | uint32_t r2; |
| 34 | uint32_t r3; |
| 35 | uint32_t r12; |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 36 | uint32_t lr; |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 37 | uint32_t ra; |
| 38 | uint32_t xpsr; |
| 39 | }; |
| 40 | |
Summer Qin | f68f0de | 2020-01-14 11:31:50 +0800 | [diff] [blame] | 41 | #define TFM_STATE_RET_VAL(ctx) (((struct tfm_state_context_t *)((ctx)->sp))->r0) |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 42 | |
| 43 | __attribute__ ((always_inline)) |
| 44 | __STATIC_INLINE void tfm_arch_trigger_pendsv(void) |
| 45 | { |
| 46 | SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; |
| 47 | } |
| 48 | |
Summer Qin | 2b8ab7e | 2020-02-18 13:58:58 +0800 | [diff] [blame] | 49 | #ifdef TFM_MULTI_CORE_TOPOLOGY |
| 50 | __STATIC_INLINE void tfm_arch_set_pendsv_priority(void) |
| 51 | { |
| 52 | NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1); |
| 53 | } |
| 54 | #else |
| 55 | __STATIC_INLINE void tfm_arch_set_pendsv_priority(void) |
| 56 | { |
| 57 | /* |
| 58 | * Set secure PendSV priority to the lowest in SECURE state. |
| 59 | * |
| 60 | * IMPORTANT NOTE: |
| 61 | * |
| 62 | * Although the priority of the secure PendSV must be the lowest possible |
| 63 | * among other interrupts in the Secure state, it must be ensured that |
| 64 | * PendSV is not preempted nor masked by Non-Secure interrupts to ensure |
| 65 | * the integrity of the Secure operation. |
| 66 | * When AIRCR.PRIS is set, the Non-Secure execution can act on |
| 67 | * FAULTMASK_NS, PRIMASK_NS or BASEPRI_NS register to boost its priority |
| 68 | * number up to the value 0x80. |
| 69 | * For this reason, set the priority of the PendSV interrupt to the next |
| 70 | * priority level configurable on the platform, just below 0x80. |
| 71 | */ |
| 72 | NVIC_SetPriority(PendSV_IRQn, (1 << (__NVIC_PRIO_BITS - 1)) - 1); |
| 73 | } |
| 74 | #endif /* TFM_MULTI_CORE_TOPOLOGY */ |
| 75 | |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 76 | /** |
| 77 | * \brief Get Link Register |
| 78 | * \details Returns the value of the Link Register (LR) |
| 79 | * \return LR value |
| 80 | */ |
| 81 | __attribute__ ((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) |
| 82 | { |
| 83 | register uint32_t result; |
| 84 | |
| 85 | __ASM volatile ("MOV %0, LR\n" : "=r" (result)); |
| 86 | return result; |
| 87 | } |
| 88 | |
| 89 | __attribute__ ((always_inline)) |
| 90 | __STATIC_INLINE uint32_t __get_active_exc_num(void) |
| 91 | { |
| 92 | IPSR_Type IPSR; |
| 93 | |
| 94 | /* if non-zero, exception is active. NOT banked S/NS */ |
| 95 | IPSR.w = __get_IPSR(); |
| 96 | return IPSR.b.ISR; |
| 97 | } |
| 98 | |
| 99 | __attribute__ ((always_inline)) |
| 100 | __STATIC_INLINE void __set_CONTROL_SPSEL(uint32_t SPSEL) |
| 101 | { |
| 102 | CONTROL_Type ctrl; |
| 103 | |
| 104 | ctrl.w = __get_CONTROL(); |
| 105 | ctrl.b.SPSEL = SPSEL; |
| 106 | __set_CONTROL(ctrl.w); |
| 107 | __ISB(); |
| 108 | } |
| 109 | |
| 110 | /* |
| 111 | * Initialize CPU architecture specific thread context extension |
| 112 | */ |
Summer Qin | f68f0de | 2020-01-14 11:31:50 +0800 | [diff] [blame] | 113 | void tfm_arch_init_actx(struct tfm_arch_ctx_t *p_actx, |
| 114 | uint32_t sp, uint32_t sp_limit); |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 115 | |
David Hu | 4e16560 | 2019-06-12 18:38:31 +0800 | [diff] [blame] | 116 | /* |
| 117 | * Prioritize Secure exceptions |
| 118 | */ |
| 119 | void tfm_arch_prioritize_secure_exception(void); |
| 120 | |
Jamie Fox | 4558767 | 2020-08-17 18:31:14 +0100 | [diff] [blame] | 121 | /** |
| 122 | * \brief Configure coprocessors |
| 123 | */ |
| 124 | void tfm_arch_configure_coprocessors(void); |
| 125 | |
Ken Liu | ce2692d | 2020-02-11 12:39:36 +0800 | [diff] [blame] | 126 | /* |
| 127 | * Clear float point status. |
| 128 | */ |
| 129 | void tfm_arch_clear_fp_status(void); |
| 130 | |
Summer Qin | af3b9e1 | 2020-01-13 15:56:36 +0800 | [diff] [blame] | 131 | void tfm_arch_init_context(struct tfm_arch_ctx_t *p_actx, |
| 132 | void *param, uintptr_t pfn, |
| 133 | uintptr_t stk_btm, uintptr_t stk_top); |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 134 | #endif |