Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 1 | /* |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 2 | * Copyright (c) 2018-2021, Arm Limited. All rights reserved. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | * |
| 6 | */ |
| 7 | #ifndef __TFM_THREAD_H__ |
| 8 | #define __TFM_THREAD_H__ |
| 9 | |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 10 | #include <stdint.h> |
| 11 | #include <stddef.h> |
David Hu | 50711e3 | 2019-06-12 18:32:30 +0800 | [diff] [blame] | 12 | #include "tfm_arch.h" |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 13 | #include "cmsis_compiler.h" |
| 14 | |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 15 | /* State code */ |
| 16 | #define THRD_STATE_CREATING 0 |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 17 | #define THRD_STATE_RUNNABLE 1 |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 18 | #define THRD_STATE_BLOCK 2 |
| 19 | #define THRD_STATE_DETACH 3 |
| 20 | #define THRD_STATE_INVALID 4 |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 21 | |
| 22 | /* Security attribute - default as security */ |
| 23 | #define THRD_ATTR_SECURE_OFFSET 16 |
| 24 | #define THRD_ATTR_SECURE (0) |
| 25 | #define THRD_ATTR_NON_SECURE (1 << THRD_ATTR_SECURE_OFFSET) |
| 26 | |
| 27 | /* Lower value has higher priority */ |
| 28 | #define THRD_PRIOR_MASK 0xFF |
| 29 | #define THRD_PRIOR_HIGHEST 0x0 |
Mingyang Sun | 00df235 | 2021-04-15 15:46:08 +0800 | [diff] [blame] | 30 | #define THRD_PRIOR_HIGH 0xF |
| 31 | #define THRD_PRIOR_MEDIUM 0x1F |
| 32 | #define THRD_PRIOR_LOW 0x7F |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 33 | #define THRD_PRIOR_LOWEST 0xFF |
| 34 | |
| 35 | /* Error code */ |
| 36 | #define THRD_SUCCESS 0 |
| 37 | #define THRD_ERR_INVALID_PARAM 1 |
| 38 | |
| 39 | /* Thread entry function type */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 40 | typedef void *(*tfm_core_thrd_entry_t)(void *); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 41 | |
| 42 | /* Thread context */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 43 | struct tfm_core_thread_t { |
| 44 | tfm_core_thrd_entry_t pfn; /* entry function */ |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 45 | void *param; /* entry parameter */ |
Summer Qin | cb19087 | 2020-01-06 16:08:26 +0800 | [diff] [blame] | 46 | uintptr_t stk_btm; /* stack bottom (lower address) */ |
| 47 | uintptr_t stk_top; /* stack top (higher address)*/ |
Kevin Peng | eca45b9 | 2021-02-09 14:46:50 +0800 | [diff] [blame] | 48 | uintptr_t flih_ctx; /* FLIH context pointer */ |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 49 | uint32_t prior; /* priority */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 50 | uint32_t state; /* state */ |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 51 | |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 52 | struct tfm_arch_ctx_t arch_ctx; /* State context */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 53 | struct tfm_core_thread_t *next; /* next thread in list */ |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 54 | }; |
| 55 | |
| 56 | /* |
| 57 | * Initialize a thread context with the necessary info. |
| 58 | * |
| 59 | * Parameters : |
| 60 | * pth - pointer of caller provided thread context |
| 61 | * pfn - thread entry function |
| 62 | * param - thread entry function parameter |
Summer Qin | cb19087 | 2020-01-06 16:08:26 +0800 | [diff] [blame] | 63 | * stk_top - stack pointer top (higher address) |
| 64 | * stk_btm - stack pointer bottom (lower address) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 65 | * |
| 66 | * Notes : |
| 67 | * Thread contex rely on caller allocated memory; initialize members in |
| 68 | * context. This function does not insert thread into schedulable list. |
| 69 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 70 | void tfm_core_thrd_init(struct tfm_core_thread_t *pth, |
| 71 | tfm_core_thrd_entry_t pfn, void *param, |
Summer Qin | cb19087 | 2020-01-06 16:08:26 +0800 | [diff] [blame] | 72 | uintptr_t stk_top, uintptr_t stk_btm); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 73 | |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 74 | /* |
| 75 | * Set thread priority. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 76 | * |
| 77 | * Parameters : |
| 78 | * pth - pointer of thread context |
| 79 | * prior - priority value (0~255) |
| 80 | * |
| 81 | * Notes : |
| 82 | * Set thread priority. Priority is set to THRD_PRIOR_MEDIUM in |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 83 | * tfm_core_thrd_init(). |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 84 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 85 | void __STATIC_INLINE tfm_core_thrd_set_priority(struct tfm_core_thread_t *pth, |
| 86 | uint32_t prior) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 87 | { |
| 88 | pth->prior &= ~THRD_PRIOR_MASK; |
| 89 | pth->prior |= prior & THRD_PRIOR_MASK; |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | * Set thread security attribute. |
| 94 | * |
| 95 | * Parameters : |
| 96 | * pth - pointer of thread context |
| 97 | * attr_secure - THRD_ATTR_SECURE or THRD_ATTR_NON_SECURE |
| 98 | * |
| 99 | * Notes |
| 100 | * Reuse prior of thread context to shift down non-secure thread priority. |
| 101 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 102 | void __STATIC_INLINE tfm_core_thrd_set_secure(struct tfm_core_thread_t *pth, |
| 103 | uint32_t attr_secure) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 104 | { |
| 105 | pth->prior &= ~THRD_ATTR_NON_SECURE; |
| 106 | pth->prior |= attr_secure; |
| 107 | } |
| 108 | |
| 109 | /* |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 110 | * Set thread state. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 111 | * |
| 112 | * Parameters : |
| 113 | * pth - pointer of thread context |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 114 | * new_state - new state of thread |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 115 | * |
| 116 | * Return : |
| 117 | * None |
| 118 | * |
| 119 | * Notes : |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 120 | * Thread state is not changed if invalid state value inputed. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 121 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 122 | void tfm_core_thrd_set_state(struct tfm_core_thread_t *pth, uint32_t new_state); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 123 | |
| 124 | /* |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 125 | * Get thread state. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 126 | * |
| 127 | * Parameters : |
| 128 | * pth - pointer of thread context |
| 129 | * |
| 130 | * Return : |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 131 | * State of thread |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 132 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 133 | uint32_t __STATIC_INLINE tfm_core_thrd_get_state(struct tfm_core_thread_t *pth) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 134 | { |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 135 | return pth->state; |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | /* |
| 139 | * Set thread state return value. |
| 140 | * |
| 141 | * Parameters : |
| 142 | * pth - pointer of thread context |
| 143 | * retval - return value to be set for thread state |
| 144 | * |
| 145 | * Notes : |
| 146 | * This API is useful for blocked syscall blocking thread. Syscall |
| 147 | * could set its return value to the caller before caller goes. |
| 148 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 149 | void __STATIC_INLINE tfm_core_thrd_set_retval(struct tfm_core_thread_t *pth, |
| 150 | uint32_t retval) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 151 | { |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 152 | TFM_STATE_RET_VAL(&pth->arch_ctx) = retval; |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | /* |
| 156 | * Validate thread context and insert it into schedulable list. |
| 157 | * |
| 158 | * Parameters : |
| 159 | * pth - pointer of thread context |
| 160 | * |
| 161 | * Return : |
| 162 | * THRD_SUCCESS for success. Or an error is returned. |
| 163 | * |
| 164 | * Notes : |
| 165 | * This function validates thread info. It returns error if thread info |
Xinyu Zhang | 3a45324 | 2021-04-16 17:57:09 +0800 | [diff] [blame] | 166 | * is not correct. Thread is available after successful tfm_core_thrd_start(). |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 167 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 168 | uint32_t tfm_core_thrd_start(struct tfm_core_thread_t *pth); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 169 | |
| 170 | /* |
| 171 | * Get current running thread. |
| 172 | * |
| 173 | * Return : |
| 174 | * Current running thread context pointer. |
| 175 | */ |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 176 | struct tfm_core_thread_t *tfm_core_thrd_get_curr(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 177 | |
| 178 | /* |
Kevin Peng | eca45b9 | 2021-02-09 14:46:50 +0800 | [diff] [blame] | 179 | * Set the current running thread |
| 180 | * Note: |
| 181 | * This API is intended to update the current thread in FLIH handling. |
| 182 | * So that in nested FLIH interrupts, the handler knows which isolation |
| 183 | * boundary was preempted. |
| 184 | * Although the CURR_THRD is updated, it does not mean the running Partition |
| 185 | * thread is changed. It could also be the FLIH function which runs with the |
| 186 | * same isolation boundary of the CURR_THRD. |
| 187 | */ |
| 188 | void tfm_core_thrd_set_curr(struct tfm_core_thread_t *pth); |
| 189 | |
| 190 | /* |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 191 | * Get next thread to run in list. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 192 | * |
| 193 | * Return : |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 194 | * Pointer of next thread to run. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 195 | */ |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 196 | struct tfm_core_thread_t *tfm_core_thrd_get_next(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 197 | |
| 198 | /* |
Ken Liu | 483f5da | 2019-04-24 10:45:21 +0800 | [diff] [blame] | 199 | * Start scheduler for existing threads |
| 200 | * |
| 201 | * Parameters: |
| 202 | * pth - pointer of the caller context collecting thread |
| 203 | * |
| 204 | * Notes : |
| 205 | * This function should be called only ONCE to start the scheduler. |
| 206 | * Caller needs to provide a thread object to collect current context. |
| 207 | * The usage of the collected context is caller defined. |
| 208 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 209 | void tfm_core_thrd_start_scheduler(struct tfm_core_thread_t *pth); |
Ken Liu | 483f5da | 2019-04-24 10:45:21 +0800 | [diff] [blame] | 210 | |
| 211 | /* |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 212 | * Activate a scheduling action after exception. |
| 213 | * |
| 214 | * Notes : |
| 215 | * This function could be called multiple times before scheduling. |
| 216 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 217 | void tfm_core_thrd_activate_schedule(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 218 | |
| 219 | /* |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 220 | * Save current architecture context into 'prev' thread and switch to 'next'. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 221 | * |
| 222 | * Parameters : |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 223 | * p_actx - latest caller context |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 224 | * prev - previous thread to be switched out |
| 225 | * next - thread to be run |
| 226 | * |
| 227 | * Notes : |
| 228 | * This function could be called multiple times before scheduling. |
| 229 | */ |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 230 | void tfm_core_thrd_switch_context(struct tfm_arch_ctx_t *p_actx, |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 231 | struct tfm_core_thread_t *prev, |
| 232 | struct tfm_core_thread_t *next); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 233 | |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 234 | #endif |