1/* 2 * Copyright 2019, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 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 * 10 * @TAG(DATA61_BSD) 11 */ 12/* 13 * The seL4 run-time interface. 14 * 15 * This provides an interface to the values managed by sel4runtime. 16 */ 17#include <sel4runtime/stddef.h> 18#include <sel4runtime/stdint.h> 19#include <sel4/sel4.h> 20#include <sel4runtime/thread.h> 21#include <sel4runtime/auxv.h> 22 23#pragma once 24 25/* 26 * Get the name of the process. 27 * 28 * Returns the basename of the first argument in argv. 29 */ 30char const *sel4runtime_process_name(void); 31 32/* 33 * Get the argument vector passed to main. 34 */ 35char const *const *sel4runtime_argv(void); 36 37/* 38 * Get the length of argument vector passed to main. 39 */ 40int sel4runtime_argc(void); 41 42/* 43 * Get the list of environment variables passed to main. 44 */ 45char const *const *sel4runtime_envp(void); 46 47/* 48 * Get the list of auxiliary vectors. 49 */ 50auxv_t const *sel4runtime_auxv(void); 51 52/* 53 * Get the address of the TLS base register. 54 */ 55static inline sel4runtime_uintptr_t sel4runtime_get_tls_base(void); 56 57/* 58 * Set the address of the TLS base register. 59 */ 60static inline void sel4runtime_set_tls_base(sel4runtime_uintptr_t tls_base); 61 62/* 63 * Get the bootinfo pointer if the process was provided a bootinfo 64 * cspace descriptor. 65 */ 66seL4_BootInfo *sel4runtime_bootinfo(void); 67 68/* 69 * Get the size in bytes needed to store the thread's TLS. 70 */ 71sel4runtime_size_t sel4runtime_get_tls_size(void); 72 73/* 74 * Get the offset used to calculate the thread pointer from the 75 * starting address of the thread area. 76 */ 77sel4runtime_size_t sel4runtime_get_tp_offset(void); 78 79/* 80 * Check if the TLS for the initial thread is enabled. 81 * 82 * If the TLS for the initial thread was too large to fit inside the 83 * static region of the runtime, this will return false and 84 * sel4runtime_move_initial_tls should be used to initialise it into a 85 * new location. 86 */ 87int sel4runtime_initial_tls_enabled(void); 88 89/* 90 * Write the TLS image for a new thread into the provided memory image. 91 * The TLS for the initial thread must be enabled before this is called. 92 * 93 * @returns the pointer to the TLS that should be used to call 94 * seL4_TCB_SetTLSBase or NULL on error. 95 */ 96sel4runtime_uintptr_t sel4runtime_write_tls_image(void *tls_memory); 97 98/* 99 * Move the TLS for the current thread into a new memory location. 100 * 101 * Particularly useful for enabling TLS in the initial process where the 102 * TLS image exeeded the size of the static TLS region in the runtime. 103 * 104 * WARNING: This will not prevent re-initialisation of the TLS for the 105 * initial thread (even by other threads). This should only be used at 106 * the start of a process only if `sel4utils_initial_tls_enabled` 107 * returns false. 108 * 109 * @returns the pointer to the TLS that should be used to call 110 * seL4_TCB_SetTLSBase. 111 */ 112sel4runtime_uintptr_t sel4runtime_move_initial_tls(void *tls_memory); 113 114/* 115 * Writes into a thread_local variable of another thread. 116 * 117 * This assumes that TLS has been initialised for the current thread. 118 */ 119#define sel4runtime_set_tls_variable(thread_pointer, variable, value) ({\ 120 _Static_assert(\ 121 sizeof(variable) == sizeof(value), \ 122 "Set value of same size" \ 123 ); \ 124 typeof (variable) typed_value = value; \ 125 __sel4runtime_write_tls_variable( \ 126 thread_pointer, \ 127 (unsigned char *)&(variable), \ 128 (unsigned char *)&(typed_value), \ 129 sizeof(typed_value) \ 130 ); \ 131}) 132 133/* 134 * Copies data into the equivalent address in the TLS of another thread. 135 * 136 * This assumes that TLS has been initialised for the current thread. 137 */ 138int __sel4runtime_write_tls_variable( 139 sel4runtime_uintptr_t dest_tls_base, 140 unsigned char *local_tls_dest, 141 unsigned char *src, 142 sel4runtime_size_t bytes 143); 144 145/* 146 * Callback function type that can be used to exit a process. 147 */ 148typedef void sel4runtime_exit_cb(int code); 149 150/* 151 * Set the callback used to exit a process. 152 * 153 * Returns the current exit function. 154 */ 155sel4runtime_exit_cb *sel4runtime_set_exit(sel4runtime_exit_cb *cb); 156 157/* 158 * Callback function type that can be used to exit a process. 159 * 160 * Should return the exit code to be generated. 161 */ 162typedef int sel4runtime_pre_exit_cb(int code); 163 164/* 165 * Set the callback called before destructors are run for a prcess exit.. 166 * 167 * Returns the current pre-exit function. 168 */ 169sel4runtime_pre_exit_cb *sel4runtime_set_pre_exit(sel4runtime_pre_exit_cb *cb); 170 171/* 172 * Exit the runtime. 173 * 174 * This will attempt to suspend the initial thread of the process. Any 175 * threading libraries should register a destructor to trigger any 176 * threads they create to be suspended. They should neve suspend the 177 * current thread. 178 */ 179void sel4runtime_exit(int code); 180