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