aboutsummaryrefslogtreecommitdiff
path: root/secure_fw/spm/cmsis_psa/tfm_thread.h
blob: 3841f942a002a8cbdce56dc9b7485cefe25029b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
 * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */
#ifndef __TFM_THREAD_H__
#define __TFM_THREAD_H__

#include <stdint.h>
#include <stddef.h>
#include "tfm_arch.h"
#include "cmsis_compiler.h"

/* State code */
#define THRD_STATE_CREATING       0
#define THRD_STATE_RUNNABLE       1
#define THRD_STATE_BLOCK          2
#define THRD_STATE_DETACH         3
#define THRD_STATE_INVALID        4

/* Security attribute - default as security */
#define THRD_ATTR_SECURE_OFFSET   16
#define THRD_ATTR_SECURE          (0)
#define THRD_ATTR_NON_SECURE      (1 << THRD_ATTR_SECURE_OFFSET)

/* Lower value has higher priority */
#define THRD_PRIOR_MASK           0xFF
#define THRD_PRIOR_HIGHEST        0x0
#define THRD_PRIOR_HIGH           0xF
#define THRD_PRIOR_MEDIUM         0x1F
#define THRD_PRIOR_LOW            0x7F
#define THRD_PRIOR_LOWEST         0xFF

/* Error code */
#define THRD_SUCCESS              0
#define THRD_ERR_INVALID_PARAM    1

/* Thread entry function type */
typedef void *(*tfm_core_thrd_entry_t)(void *);

/* Thread context */
struct tfm_core_thread_t {
    tfm_core_thrd_entry_t pfn;          /* entry function               */
    void            *param;             /* entry parameter              */
    uintptr_t       stk_btm;            /* stack bottom (lower address) */
    uintptr_t       stk_top;            /* stack top    (higher address)*/
    uint32_t        prior;              /* priority                     */
    uint32_t        state;              /* state                        */

    struct tfm_arch_ctx_t    arch_ctx;  /* State context                */
    struct tfm_core_thread_t *next;     /* next thread in list          */
};

/*
 * Initialize a thread context with the necessary info.
 *
 * Parameters :
 *  pth         -    pointer of caller provided thread context
 *  pfn         -    thread entry function
 *  param       -    thread entry function parameter
 *  stk_top     -    stack pointer top (higher address)
 *  stk_btm     -    stack pointer bottom (lower address)
 *
 * Notes :
 *  Thread contex rely on caller allocated memory; initialize members in
 *  context. This function does not insert thread into schedulable list.
 */
void tfm_core_thrd_init(struct tfm_core_thread_t *pth,
                        tfm_core_thrd_entry_t pfn, void *param,
                        uintptr_t stk_top, uintptr_t stk_btm);

/*
 * Set thread priority.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *  prior       -     priority value (0~255)
 *
 * Notes :
 *  Set thread priority. Priority is set to THRD_PRIOR_MEDIUM in
 *  tfm_core_thrd_init().
 */
void __STATIC_INLINE tfm_core_thrd_set_priority(struct tfm_core_thread_t *pth,
                                                uint32_t prior)
{
    pth->prior &= ~THRD_PRIOR_MASK;
    pth->prior |= prior & THRD_PRIOR_MASK;
}

/*
 * Set thread security attribute.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *  attr_secure -     THRD_ATTR_SECURE or THRD_ATTR_NON_SECURE
 *
 * Notes
 *  Reuse prior of thread context to shift down non-secure thread priority.
 */
void __STATIC_INLINE tfm_core_thrd_set_secure(struct tfm_core_thread_t *pth,
                                              uint32_t attr_secure)
{
    pth->prior &= ~THRD_ATTR_NON_SECURE;
    pth->prior |= attr_secure;
}

/*
 * Set thread state.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *  new_state   -     new state of thread
 *
 * Return :
 *  None
 *
 * Notes :
 *  Thread state is not changed if invalid state value inputed.
 */
void tfm_core_thrd_set_state(struct tfm_core_thread_t *pth, uint32_t new_state);

/*
 * Get thread state.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *
 * Return :
 *  State of thread
 */
uint32_t __STATIC_INLINE tfm_core_thrd_get_state(struct tfm_core_thread_t *pth)
{
    return pth->state;
}

/*
 * Set thread state return value.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *  retval      -     return value to be set for thread state
 *
 * Notes :
 *  This API is useful for blocked syscall blocking thread. Syscall
 *  could set its return value to the caller before caller goes.
 */
void __STATIC_INLINE tfm_core_thrd_set_retval(struct tfm_core_thread_t *pth,
                                              uint32_t retval)
{
    TFM_STATE_RET_VAL(&pth->arch_ctx) = retval;
}

/*
 * Validate thread context and insert it into schedulable list.
 *
 * Parameters :
 *  pth         -     pointer of thread context
 *
 * Return :
 *  THRD_SUCCESS for success. Or an error is returned.
 *
 * Notes :
 *  This function validates thread info. It returns error if thread info
 *  is not correct. Thread is available after successful tfm_core_thrd_start().
 */
uint32_t tfm_core_thrd_start(struct tfm_core_thread_t *pth);

/*
 * Get current running thread.
 *
 * Return :
 *  Current running thread context pointer.
 */
struct tfm_core_thread_t *tfm_core_thrd_get_curr(void);

/*
 * Get next thread to run in list.
 *
 * Return :
 *  Pointer of next thread to run.
 */
struct tfm_core_thread_t *tfm_core_thrd_get_next(void);

/*
 * Start scheduler for existing threads
 *
 * Parameters:
 *  pth         -     pointer of the caller context collecting thread
 *
 * Notes :
 *  This function should be called only ONCE to start the scheduler.
 *  Caller needs to provide a thread object to collect current context.
 *  The usage of the collected context is caller defined.
 */
void tfm_core_thrd_start_scheduler(struct tfm_core_thread_t *pth);

/*
 * Activate a scheduling action after exception.
 *
 * Notes :
 *  This function could be called multiple times before scheduling.
 */
void tfm_core_thrd_activate_schedule(void);

/*
 * Save current architecture context into 'prev' thread and switch to 'next'.
 *
 * Parameters :
 *  p_actx      -     latest caller context
 *  prev        -     previous thread to be switched out
 *  next        -     thread to be run
 *
 * Notes :
 *  This function could be called multiple times before scheduling.
 */
void tfm_core_thrd_switch_context(struct tfm_arch_ctx_t *p_actx,
                                  struct tfm_core_thread_t *prev,
                                  struct tfm_core_thread_t *next);

#endif