| /* | |
| * Copyright 2019, Data61 | |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) | |
| * ABN 41 687 119 230. | |
| * | |
| * This software may be distributed and modified according to the terms of | |
| * the BSD 2-Clause license. Note that NO WARRANTY is provided. | |
| * See "LICENSE_BSD2.txt" for details. | |
| * | |
| * @TAG(DATA61_BSD) | |
| */ | |
| /* | |
| * The seL4 run-time interface. | |
| * | |
| * This provides an interface to the values managed by sel4runtime. | |
| */ | |
| #include <sel4runtime/stddef.h> | |
| #include <sel4runtime/stdint.h> | |
| #include <sel4/sel4.h> | |
| #include <sel4runtime/thread.h> | |
| #include <sel4runtime/auxv.h> | |
| #pragma once | |
| /* | |
| * Get the name of the process. | |
| * | |
| * Returns the basename of the first argument in argv. | |
| */ | |
| char const *sel4runtime_process_name(void); | |
| /* | |
| * Get the argument vector passed to main. | |
| */ | |
| char const *const *sel4runtime_argv(void); | |
| /* | |
| * Get the length of argument vector passed to main. | |
| */ | |
| int sel4runtime_argc(void); | |
| /* | |
| * Get the list of environment variables passed to main. | |
| */ | |
| char const *const *sel4runtime_envp(void); | |
| /* | |
| * Get the list of auxiliary vectors. | |
| */ | |
| auxv_t const *sel4runtime_auxv(void); | |
| /* | |
| * Get the address of the TLS base register. | |
| */ | |
| static inline sel4runtime_uintptr_t sel4runtime_get_tls_base(void); | |
| /* | |
| * Set the address of the TLS base register. | |
| */ | |
| static inline void sel4runtime_set_tls_base(sel4runtime_uintptr_t tls_base); | |
| /* | |
| * Get the bootinfo pointer if the process was provided a bootinfo | |
| * cspace descriptor. | |
| */ | |
| seL4_BootInfo *sel4runtime_bootinfo(void); | |
| /* | |
| * Get the size in bytes needed to store the thread's TLS. | |
| */ | |
| sel4runtime_size_t sel4runtime_get_tls_size(void); | |
| /* | |
| * Get the offset used to calculate the thread pointer from the | |
| * starting address of the thread area. | |
| */ | |
| sel4runtime_size_t sel4runtime_get_tp_offset(void); | |
| /* | |
| * Check if the TLS for the initial thread is enabled. | |
| * | |
| * If the TLS for the initial thread was too large to fit inside the | |
| * static region of the runtime, this will return false and | |
| * sel4runtime_move_initial_tls should be used to initialise it into a | |
| * new location. | |
| */ | |
| int sel4runtime_initial_tls_enabled(void); | |
| /* | |
| * Write the TLS image for a new thread into the provided memory image. | |
| * The TLS for the initial thread must be enabled before this is called. | |
| * | |
| * @returns the pointer to the TLS that should be used to call | |
| * seL4_TCB_SetTLSBase or NULL on error. | |
| */ | |
| sel4runtime_uintptr_t sel4runtime_write_tls_image(void *tls_memory); | |
| /* | |
| * Move the TLS for the current thread into a new memory location. | |
| * | |
| * Particularly useful for enabling TLS in the initial process where the | |
| * TLS image exeeded the size of the static TLS region in the runtime. | |
| * | |
| * WARNING: This will not prevent re-initialisation of the TLS for the | |
| * initial thread (even by other threads). This should only be used at | |
| * the start of a process only if `sel4utils_initial_tls_enabled` | |
| * returns false. | |
| * | |
| * @returns the pointer to the TLS that should be used to call | |
| * seL4_TCB_SetTLSBase. | |
| */ | |
| sel4runtime_uintptr_t sel4runtime_move_initial_tls(void *tls_memory); | |
| /* | |
| * Writes into a thread_local variable of another thread. | |
| * | |
| * This assumes that TLS has been initialised for the current thread. | |
| */ | |
| #define sel4runtime_set_tls_variable(thread_pointer, variable, value) ({\ | |
| _Static_assert(\ | |
| sizeof(variable) == sizeof(value), \ | |
| "Set value of same size" \ | |
| ); \ | |
| typeof (variable) typed_value = value; \ | |
| __sel4runtime_write_tls_variable( \ | |
| thread_pointer, \ | |
| (unsigned char *)&(variable), \ | |
| (unsigned char *)&(typed_value), \ | |
| sizeof(typed_value) \ | |
| ); \ | |
| }) | |
| /* | |
| * Copies data into the equivalent address in the TLS of another thread. | |
| * | |
| * This assumes that TLS has been initialised for the current thread. | |
| */ | |
| int __sel4runtime_write_tls_variable( | |
| sel4runtime_uintptr_t dest_tls_base, | |
| unsigned char *local_tls_dest, | |
| unsigned char *src, | |
| sel4runtime_size_t bytes | |
| ); | |
| /* | |
| * Callback function type that can be used to exit a process. | |
| */ | |
| typedef void sel4runtime_exit_cb(int code); | |
| /* | |
| * Set the callback used to exit a process. | |
| * | |
| * Returns the current exit function. | |
| */ | |
| sel4runtime_exit_cb *sel4runtime_set_exit(sel4runtime_exit_cb *cb); | |
| /* | |
| * Callback function type that can be used to exit a process. | |
| * | |
| * Should return the exit code to be generated. | |
| */ | |
| typedef int sel4runtime_pre_exit_cb(int code); | |
| /* | |
| * Set the callback called before destructors are run for a prcess exit.. | |
| * | |
| * Returns the current pre-exit function. | |
| */ | |
| sel4runtime_pre_exit_cb *sel4runtime_set_pre_exit(sel4runtime_pre_exit_cb *cb); | |
| /* | |
| * Exit the runtime. | |
| * | |
| * This will attempt to suspend the initial thread of the process. Any | |
| * threading libraries should register a destructor to trigger any | |
| * threads they create to be suspended. They should neve suspend the | |
| * current thread. | |
| */ | |
| void sel4runtime_exit(int code); |