blob: 1d745b2868aeb18600b5ed190443d8023e94d1a4 [file] [log] [blame]
TrustworthySystemsb85c30b2014-07-22 14:11:33 +10001/*
Anna Lyons92143412017-06-05 08:29:55 +10002 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +10005 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
Anna Lyons92143412017-06-05 08:29:55 +100010 * @TAG(DATA61_BSD)
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100011 */
12
13/**
14 *
15 * Provides basic thread configuration/starting/cleanup functions.
16 *
17 * Any other operations (start, stop, resume) should use the seL4 API directly on
18 * sel4utils_thread_t->tcb.cptr.
19 *
20 */
Anna Lyons135c6512017-09-28 12:16:03 +100021#pragma once
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100022
23#include <autoconf.h>
Yu Houe23dc542019-05-20 15:29:15 +100024#include <sel4utils/gen_config.h>
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100025
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100026#include <sel4/sel4.h>
Anna Lyons41ca0a62015-10-23 13:59:45 +110027#include <stdbool.h>
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100028#include <vka/vka.h>
29
30#include <vspace/vspace.h>
Anna Lyonse378dbc2017-07-10 16:07:09 +100031#include <sel4utils/thread_config.h>
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100032
Kofi Doku Atuahd67465c2016-09-26 01:27:35 +100033#ifdef CONFIG_DEBUG_BUILD
34#define NAME_THREAD(_tcbcap, _name) seL4_DebugNameThread(_tcbcap, _name);
35#else
36#define NAME_THREAD(_tcbcap, _name)
37#endif
38
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100039typedef struct sel4utils_thread {
40 vka_object_t tcb;
Anna Lyonse8088af2017-08-10 11:41:46 +100041 vka_object_t sched_context;
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100042 void *stack_top;
Alexander Wharton132a7a52016-09-21 14:24:44 +100043 void *initial_stack_pointer;
Anna Lyons8e73b442016-07-06 11:28:14 +100044 size_t stack_size;
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100045 seL4_CPtr ipc_buffer;
46 seL4_Word ipc_buffer_addr;
Anna Lyonse8088af2017-08-10 11:41:46 +100047 bool own_sc;
Anna Lyonsba1db812017-08-10 12:30:15 +100048 bool own_reply;
49 vka_object_t reply;
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100050} sel4utils_thread_t;
51
Anna Lyons41ca0a62015-10-23 13:59:45 +110052typedef struct sel4utils_checkpoint {
Anna Lyonsdbec9512018-08-28 13:32:41 +100053 /* checkpointed stack */
Anna Lyons41ca0a62015-10-23 13:59:45 +110054 void *stack;
55 seL4_UserContext regs;
56 sel4utils_thread_t *thread;
Anna Lyonse76b3592018-08-28 17:01:55 +100057 /* stack pointer this checkpoint preserves */
58 uintptr_t sp;
Anna Lyons41ca0a62015-10-23 13:59:45 +110059} sel4utils_checkpoint_t;
60
Stephen Sherratt857ffba2017-03-16 13:39:29 +110061typedef void (*sel4utils_thread_entry_fn)(void *arg0, void *arg1, void *ipc_buf);
62
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100063/**
Anna Lyonse378dbc2017-07-10 16:07:09 +100064 * Configure a thread, allocating any resources required. The thread will start at priority 0.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100065 *
Anna Lyonse8088af2017-08-10 11:41:46 +100066 * If CONFIG_RT is enabled, the thread will not have a scheduling context, so it will not be able to run.
67 *
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100068 * @param vka initialised vka to allocate objects with
Adrian Danisc5f81c12014-08-28 11:10:33 +100069 * @param parent vspace structure of the thread calling this function, used for temporary mappings
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100070 * @param alloc initialised vspace structure to allocate virtual memory with
71 * @param fault_endpoint endpoint to set as the threads fault endpoint. Can be 0.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100072 * @param cspace the root of the cspace to start the thread in
73 * @param cspace_root_data data for cspace access
74 * @param res an uninitialised sel4utils_thread_t data structure that will be initialised
75 * after this operation.
76 *
77 * @return 0 on success, -1 on failure. Use CONFIG_DEBUG to see error messages.
78 */
Adrian Danisc5f81c12014-08-28 11:10:33 +100079int sel4utils_configure_thread(vka_t *vka, vspace_t *parent, vspace_t *alloc, seL4_CPtr fault_endpoint,
Adrian Danis08f9b7c2017-10-05 15:48:18 +110080 seL4_CNode cspace, seL4_Word cspace_root_data,
Anna Lyons3ec60c82014-10-16 09:37:48 +110081 sel4utils_thread_t *res);
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100082
Anna Lyons3ec60c82014-10-16 09:37:48 +110083/**
Anna Lyons1b987fc2014-10-14 11:22:03 +110084 * As per sel4utils_configure_thread, but using a config struct.
85 */
86int sel4utils_configure_thread_config(vka_t *vka, vspace_t *parent, vspace_t *alloc,
87 sel4utils_thread_config_t config, sel4utils_thread_t *res);
88
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100089/**
90 * Start a thread, allocating any resources required.
91 * The third argument to the thread (in r2 for arm, on stack for ia32) will be the
92 * address of the ipc buffer.
93 *
94 * @param thread thread data structure that has been initialised with sel4utils_configure_thread
95 * @param entry_point the address that the thread will start at
Anna Lyons3ec60c82014-10-16 09:37:48 +110096 *
97 * NOTE: In order for the on-stack argument passing to work for ia32,
98 * entry points must be functions.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +100099 *
100 * ie. jumping to this start symbol will work:
101 *
102 * void _start(int argc, char **argv) {
103 * int ret = main(argc, argv);
104 * exit(ret);
105 * }
Anna Lyons3ec60c82014-10-16 09:37:48 +1100106 *
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000107 *
108 * However, jumping to a start symbol like this:
109 *
110 * _start:
111 * call main
112 *
113 * will NOT work, as call pushes an extra value (the return value)
114 * onto the stack. If you really require an assembler stub, it should
115 * decrement the stack value to account for this.
116 *
117 * ie.
118 *
119 * _start:
120 * popl %eax
121 * call main
122 *
123 * This does not apply for arm, as arguments are passed in registers.
124 *
125 *
126 * @param arg0 a pointer to the arguments for this thread. User decides the protocol.
127 * @param arg1 another pointer. User decides the protocol. Note that there are two args here
128 * to easily support C standard: int main(int argc, char **argv).
129 * @param resume 1 to start the thread immediately, 0 otherwise.
130 *
131 * @return 0 on success, -1 on failure.
132 */
Stephen Sherratt4aad8202017-03-16 13:44:09 +1100133int sel4utils_start_thread(sel4utils_thread_t *thread, sel4utils_thread_entry_fn entry_point,
134 void *arg0, void *arg1, int resume);
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000135
136/**
137 * Release any resources used by this thread. The thread data structure will not be usable
138 * until sel4utils_thread_configure is called again.
139 *
140 * @param vka the vka interface that this thread was initialised with
141 * @param alloc the allocation interface that this thread was initialised with
142 * @param thread the thread structure that was returned when the thread started
143 */
144void sel4utils_clean_up_thread(vka_t *vka, vspace_t *alloc, sel4utils_thread_t *thread);
145
146/**
Anna Lyons41ca0a62015-10-23 13:59:45 +1100147 * Checkpoint a thread at its current state, storing its current register set and stack.
148 *
149 * Note that the heap state is not saved, so threads intending to use this functionality
150 * should not mutate the heap or other state beyond the checkpoint, unless extra functionality
151 * is included to roll these back.
152 *
Anna Lyonse76b3592018-08-28 17:01:55 +1000153 * This should not be called on a currently running thread, and is designed to be called on
154 * threads which are known to be blocked on an seL4_Recv, for checkpointing passive threads on
155 * the mcs kernel (threads without scheduling contexts). The checkpoint is set up that such a
156 * thread can be restarted successfully at the instruction which enters the kernel, with
157 * register state set up specifically for that.
Anna Lyons41ca0a62015-10-23 13:59:45 +1100158 *
159 * @param thread the thread to checkpoint
160 * @param checkpoint pointer to uninitialised checkpoint struct
Anna Lyons0016dfc2017-07-14 09:40:34 +1000161 * @param suspend true if the thread should be suspended
162 *
Anna Lyons41ca0a62015-10-23 13:59:45 +1100163 * @return 0 on success.
164 */
165int sel4utils_checkpoint_thread(sel4utils_thread_t *thread, sel4utils_checkpoint_t *checkpoint, bool suspend);
166
167/**
Anna Lyons0016dfc2017-07-14 09:40:34 +1000168 * Rollback a thread to a previous checkpoint, restoring its register set and stack.
Anna Lyons41ca0a62015-10-23 13:59:45 +1100169 *
Anna Lyons0016dfc2017-07-14 09:40:34 +1000170 * This is not atomic and callers should make sure the target thread is stopped or that the
171 * caller is higher priority such that the target is not switched to by the kernel mid-restore.
Anna Lyons41ca0a62015-10-23 13:59:45 +1100172 *
173 * @param checkpoint the previously saved checkpoint to restore.
174 * @param free true if this checkpoint should free all memory allocated, i.e if the checkpoint
175 * will not be used again.
Anna Lyons0016dfc2017-07-14 09:40:34 +1000176 * @param resume true if the thread should be resumed immediately.
Anna Lyons41ca0a62015-10-23 13:59:45 +1100177 *
178 * @return 0 on success.
179 */
180int sel4utils_checkpoint_restore(sel4utils_checkpoint_t *checkpoint, bool free, bool resume);
181
182/**
183 * Clean up a previously allocated checkpoint.
184 */
185void sel4utils_free_checkpoint(sel4utils_checkpoint_t *checkpoint);
186
187/**
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000188 * Start a fault handling thread that will print the name of the thread that faulted
Anna Lyonse378dbc2017-07-10 16:07:09 +1000189 * as well as debugging information. The thread will start at priority 0.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000190 *
Anna Lyonse8088af2017-08-10 11:41:46 +1000191 * If CONFIG_RT it be passive (not have a scheulding context) and will run on the SC of the faulter.
192 *
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000193 * @param fault_endpoint the fault_endpoint to wait on
194 * @param vka allocator
195 * @param vspace vspace (this library must be mapped into that vspace).
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000196 * @param cspace the cspace that the fault_endpoint is in
197 * @param data the cspace_data for that cspace (with correct guard)
198 * @param name the name of the thread to print if it faults
199 * @param thread the thread data structure to populate
200 *
201 * @return 0 on success.
202 */
Anna Lyons3ec60c82014-10-16 09:37:48 +1100203int sel4utils_start_fault_handler(seL4_CPtr fault_endpoint, vka_t *vka, vspace_t *vspace,
Adrian Danis08f9b7c2017-10-05 15:48:18 +1100204 seL4_CPtr cspace, seL4_Word data, char *name, sel4utils_thread_t *res);
Anna Lyons3ec60c82014-10-16 09:37:48 +1100205
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000206/**
Matthew Fernandeza8cfaf52015-03-19 09:46:57 +1100207 * Pretty print a fault message.
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000208 *
209 * @param tag the message info tag delivered by the fault.
Anna Lyons3ec60c82014-10-16 09:37:48 +1100210 * @param name thread name
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000211 */
Adrian Danis889675f2015-01-13 11:36:17 +1100212void sel4utils_print_fault_message(seL4_MessageInfo_t tag, const char *name);
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000213
Anna Lyons8ba9fcd2017-12-20 12:20:05 +1100214/* Set the affinity of a thread, which will cause migration if the thread
215 * is running on a different core.
216 *
217 * On master, only use sched_params_set_core to set the core then call this function.
218 *
Kent McLeod38a475d2019-08-21 16:41:58 +1000219 * If CONFIG_KERNEL_MCS is set, the sched params must be fully populated or the scheduling
Anna Lyons8ba9fcd2017-12-20 12:20:05 +1100220 * context will be empty when it changes core as scheduling parameters of scheduling
221 * contexts are not maintained across migrations.
222 */
223int sel4utils_set_sched_affinity(sel4utils_thread_t *thread, sched_params_t params);
224
Yu Houe9a9ff42019-07-18 17:26:01 +1000225static inline seL4_TCB sel4utils_get_tcb(sel4utils_thread_t *thread)
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000226{
227 return thread->tcb.cptr;
228}
229
Yu Houe9a9ff42019-07-18 17:26:01 +1000230static inline int sel4utils_suspend_thread(sel4utils_thread_t *thread)
TrustworthySystemsb85c30b2014-07-22 14:11:33 +1000231{
232 return seL4_TCB_Suspend(thread->tcb.cptr);
233}
234