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)*/ |
Ken Liu | 5a2b905 | 2019-08-15 19:03:29 +0800 | [diff] [blame] | 48 | uint32_t prior; /* priority */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 49 | uint32_t state; /* state */ |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 50 | |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 51 | struct tfm_arch_ctx_t arch_ctx; /* State context */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 52 | struct tfm_core_thread_t *next; /* next thread in list */ |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 53 | }; |
| 54 | |
| 55 | /* |
| 56 | * Initialize a thread context with the necessary info. |
| 57 | * |
| 58 | * Parameters : |
| 59 | * pth - pointer of caller provided thread context |
| 60 | * pfn - thread entry function |
| 61 | * param - thread entry function parameter |
Summer Qin | cb19087 | 2020-01-06 16:08:26 +0800 | [diff] [blame] | 62 | * stk_top - stack pointer top (higher address) |
| 63 | * stk_btm - stack pointer bottom (lower address) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 64 | * |
| 65 | * Notes : |
| 66 | * Thread contex rely on caller allocated memory; initialize members in |
| 67 | * context. This function does not insert thread into schedulable list. |
| 68 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 69 | void tfm_core_thrd_init(struct tfm_core_thread_t *pth, |
| 70 | tfm_core_thrd_entry_t pfn, void *param, |
Summer Qin | cb19087 | 2020-01-06 16:08:26 +0800 | [diff] [blame] | 71 | uintptr_t stk_top, uintptr_t stk_btm); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 72 | |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 73 | /* |
| 74 | * Set thread priority. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 75 | * |
| 76 | * Parameters : |
| 77 | * pth - pointer of thread context |
| 78 | * prior - priority value (0~255) |
| 79 | * |
| 80 | * Notes : |
| 81 | * Set thread priority. Priority is set to THRD_PRIOR_MEDIUM in |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 82 | * tfm_core_thrd_init(). |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 83 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 84 | void __STATIC_INLINE tfm_core_thrd_set_priority(struct tfm_core_thread_t *pth, |
| 85 | uint32_t prior) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 86 | { |
| 87 | pth->prior &= ~THRD_PRIOR_MASK; |
| 88 | pth->prior |= prior & THRD_PRIOR_MASK; |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | * Set thread security attribute. |
| 93 | * |
| 94 | * Parameters : |
| 95 | * pth - pointer of thread context |
| 96 | * attr_secure - THRD_ATTR_SECURE or THRD_ATTR_NON_SECURE |
| 97 | * |
| 98 | * Notes |
| 99 | * Reuse prior of thread context to shift down non-secure thread priority. |
| 100 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 101 | void __STATIC_INLINE tfm_core_thrd_set_secure(struct tfm_core_thread_t *pth, |
| 102 | uint32_t attr_secure) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 103 | { |
| 104 | pth->prior &= ~THRD_ATTR_NON_SECURE; |
| 105 | pth->prior |= attr_secure; |
| 106 | } |
| 107 | |
| 108 | /* |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 109 | * Set thread state. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 110 | * |
| 111 | * Parameters : |
| 112 | * pth - pointer of thread context |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 113 | * new_state - new state of thread |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 114 | * |
| 115 | * Return : |
| 116 | * None |
| 117 | * |
| 118 | * Notes : |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 119 | * Thread state is not changed if invalid state value inputed. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 120 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 121 | 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] | 122 | |
| 123 | /* |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 124 | * Get thread state. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 125 | * |
| 126 | * Parameters : |
| 127 | * pth - pointer of thread context |
| 128 | * |
| 129 | * Return : |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 130 | * State of thread |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 131 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 132 | 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] | 133 | { |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 134 | return pth->state; |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | /* |
| 138 | * Set thread state return value. |
| 139 | * |
| 140 | * Parameters : |
| 141 | * pth - pointer of thread context |
| 142 | * retval - return value to be set for thread state |
| 143 | * |
| 144 | * Notes : |
| 145 | * This API is useful for blocked syscall blocking thread. Syscall |
| 146 | * could set its return value to the caller before caller goes. |
| 147 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 148 | void __STATIC_INLINE tfm_core_thrd_set_retval(struct tfm_core_thread_t *pth, |
| 149 | uint32_t retval) |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 150 | { |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 151 | TFM_STATE_RET_VAL(&pth->arch_ctx) = retval; |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | /* |
| 155 | * Validate thread context and insert it into schedulable list. |
| 156 | * |
| 157 | * Parameters : |
| 158 | * pth - pointer of thread context |
| 159 | * |
| 160 | * Return : |
| 161 | * THRD_SUCCESS for success. Or an error is returned. |
| 162 | * |
| 163 | * Notes : |
| 164 | * This function validates thread info. It returns error if thread info |
Xinyu Zhang | 3a45324 | 2021-04-16 17:57:09 +0800 | [diff] [blame^] | 165 | * is not correct. Thread is available after successful tfm_core_thrd_start(). |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 166 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 167 | uint32_t tfm_core_thrd_start(struct tfm_core_thread_t *pth); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 168 | |
| 169 | /* |
| 170 | * Get current running thread. |
| 171 | * |
| 172 | * Return : |
| 173 | * Current running thread context pointer. |
| 174 | */ |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 175 | struct tfm_core_thread_t *tfm_core_thrd_get_curr(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 176 | |
| 177 | /* |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 178 | * Get next thread to run in list. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 179 | * |
| 180 | * Return : |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 181 | * Pointer of next thread to run. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 182 | */ |
Kevin Peng | 82fbca5 | 2021-03-09 13:48:48 +0800 | [diff] [blame] | 183 | struct tfm_core_thread_t *tfm_core_thrd_get_next(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 184 | |
| 185 | /* |
Ken Liu | 483f5da | 2019-04-24 10:45:21 +0800 | [diff] [blame] | 186 | * Start scheduler for existing threads |
| 187 | * |
| 188 | * Parameters: |
| 189 | * pth - pointer of the caller context collecting thread |
| 190 | * |
| 191 | * Notes : |
| 192 | * This function should be called only ONCE to start the scheduler. |
| 193 | * Caller needs to provide a thread object to collect current context. |
| 194 | * The usage of the collected context is caller defined. |
| 195 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 196 | void tfm_core_thrd_start_scheduler(struct tfm_core_thread_t *pth); |
Ken Liu | 483f5da | 2019-04-24 10:45:21 +0800 | [diff] [blame] | 197 | |
| 198 | /* |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 199 | * Activate a scheduling action after exception. |
| 200 | * |
| 201 | * Notes : |
| 202 | * This function could be called multiple times before scheduling. |
| 203 | */ |
Summer Qin | 66f1e03 | 2020-01-06 15:40:03 +0800 | [diff] [blame] | 204 | void tfm_core_thrd_activate_schedule(void); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 205 | |
| 206 | /* |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 207 | * Save current architecture context into 'prev' thread and switch to 'next'. |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 208 | * |
| 209 | * Parameters : |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 210 | * p_actx - latest caller context |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 211 | * prev - previous thread to be switched out |
| 212 | * next - thread to be run |
| 213 | * |
| 214 | * Notes : |
| 215 | * This function could be called multiple times before scheduling. |
| 216 | */ |
Summer Qin | d2ad7e7 | 2020-01-06 18:16:35 +0800 | [diff] [blame] | 217 | 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] | 218 | struct tfm_core_thread_t *prev, |
| 219 | struct tfm_core_thread_t *next); |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 220 | |
Ken Liu | 91d44da | 2018-09-20 22:42:31 +0800 | [diff] [blame] | 221 | #endif |