1/* 2 * Copyright 2017, 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#pragma once 13 14#include <autoconf.h> 15#include <sel4utils/gen_config.h> 16 17#include <vka/vka.h> 18#include <vspace/vspace.h> 19 20#include <sel4utils/thread.h> 21#include <sel4utils/process_config.h> 22#include <sel4utils/vspace.h> 23#include <sel4utils/elf.h> 24#include <sel4platsupport/timer.h> 25 26#define WORD_STRING_SIZE ((CONFIG_WORD_SIZE / 3) + 1) 27 28typedef struct object_node object_node_t; 29 30struct object_node { 31 vka_object_t object; 32 object_node_t *next; 33}; 34 35typedef struct { 36 vka_object_t pd; 37 vspace_t vspace; 38 sel4utils_alloc_data_t data; 39 vka_object_t cspace; 40 uint32_t cspace_size; 41 uint32_t cspace_next_free; 42 sel4utils_thread_t thread; 43 vka_object_t fault_endpoint; 44 void *entry_point; 45 uintptr_t sysinfo; 46 /* cptr (with respect to the process cnode) of the tcb of the first thread (0 means not supplied) */ 47 seL4_CPtr dest_tcb_cptr; 48 seL4_Word pagesz; 49 object_node_t *allocated_object_list_head; 50 /* ELF headers that describe the sections of the loaded image (at least as they 51 * existed at load time). Is different to the elf_regions, which have reservations, 52 * these are the original headers from the elf and include nonloaded information regions */ 53 int num_elf_phdrs; 54 Elf_Phdr *elf_phdrs; 55 /* if the elf wasn't loaded into the address space, this describes the regions. 56 * this permits lazy loading / copy on write / page sharing / whatever crazy thing 57 * you want to implement */ 58 int num_elf_regions; 59 sel4utils_elf_region_t *elf_regions; 60 bool own_vspace; 61 bool own_cspace; 62 bool own_ep; 63} sel4utils_process_t; 64 65/* sel4utils processes start with some caps in their cspace. 66 * These are the caps 67 */ 68enum sel4utils_cspace_layout { 69 /* no cap in NULL */ 70 SEL4UTILS_NULL_SLOT = 0, 71 /* 72 * The root cnode (with appropriate guard) 73 */ 74 SEL4UTILS_CNODE_SLOT = 1, 75 /* The slot on the cspace that fault_endpoint is put if 76 * sel4utils_configure_process is used. 77 */ 78 SEL4UTILS_ENDPOINT_SLOT = 2, 79 80 /* The page directory slot */ 81 SEL4UTILS_PD_SLOT = 3, 82 83 /* the slot for the asid pool that this thread is in and can create threads 84 * in. 0 if this kernel does not support asid pools */ 85 SEL4UTILS_ASID_POOL_SLOT = 4, 86 87 /* the slot for this processes tcb */ 88 SEL4UTILS_TCB_SLOT = 5, 89 90 /* the slot for this processes sc */ 91 SEL4UTILS_SCHED_CONTEXT_SLOT = 6, 92 93 /* The slot for this processes reply object */ 94 SEL4UTILS_REPLY_SLOT = 7, 95 96 /* First free slot in the cspace configured by sel4utils */ 97 SEL4UTILS_FIRST_FREE = 8 98}; 99 100/** 101 * Start a process, and copy arguments into the processes address space. 102 * 103 * This is intended to use when loading applications of the format: 104 * 105 * int main(int argc, char **argv) { }; 106 * 107 * The third argument (in r2 for arm, on stack for ia32) will be the address of the ipc buffer. 108 * This is intended to be loaded by the crt into the data word of the ipc buffer, 109 * or you can just add it to your function prototype. 110 * 111 * Add the following to your crt to use it this way: 112 * 113 * arm: str r2, [r2, #484] 114 * ia32: popl %ebp 115 * movl %ebp, 484(%ebp) 116 * 117 * @param process initialised sel4utils process struct. 118 * @param vka vka interface to use for allocation of frames. 119 * @param vspace the current vspace. 120 * @param argc the number of arguments. 121 * @param argv a pointer to an array of strings in the current vspace. 122 * @param resume 1 to start the process, 0 to leave suspended. 123 * 124 * @return -1 on error, 0 on success. 125 * 126 */ 127int sel4utils_spawn_process(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, 128 int argc, char *argv[], int resume); 129 130/** 131 * Start a process, and copy arguments into the processes address space. 132 * 133 * This is intended for use when loading applications that have a System V ABI compliant 134 * entry point. This means that the entry point should *not* be a 'main' that is expecting 135 * argc and argv in the form as passed here, but should be an _start routine that will 136 * take a stack frame with the arguments on it and construct an appropriate invocation 137 * to a main function. The stack frame passed to the entry point will have an auxv, envp 138 * and argv 139 * 140 * @param process initialised sel4utils process struct. 141 * @param vka vka interface to use for allocation of frames. 142 * @param vspace the current vspace. 143 * @param argc the number of arguments. 144 * @param argv a pointer to an array of strings in the current vspace. 145 * @param resume 1 to start the process, 0 to leave suspended. 146 * 147 * @return -1 on error, 0 on success. 148 * 149 */ 150int sel4utils_spawn_process_v(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, 151 int argc, char *argv[], int resume); 152 153/** 154 * This is the function to use if you just want to set up a process as fast as possible. 155 * It creates a simple cspace and vspace for you, allocates a fault endpoint and puts 156 * it into the new cspace. The process will start at priority 0. 157 * 158 * If CONFIG_RT is enabled, it will not have a scheduling context. 159 * 160 * It loads the elf file into the new vspace, parses the elf file and stores the entry point 161 * into process->entry_point. 162 * 163 * It uses the same vka for both allocations - the new process will not have an allocator. 164 * 165 * The process will have just one thread. 166 * 167 * Otherwise, use it as a model for loading processes and use the elf_load. 168 * 169 * WARNING: when launching processes on ia32 please ensure your calling convention 170 * matches that documented in sel4utils_start_thread. Otherwise your arguments 171 * won't come through correctly. 172 * 173 * @param process uninitialised process struct. 174 * @param vka allocator to use to allocate objects. 175 * @param vspace vspace allocator for the current vspace. 176 * @param image_name name of the elf image to load from the cpio archive. 177 * 178 * @return 0 on success, -1 on error. 179 */ 180int sel4utils_configure_process(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, 181 const char *image_name); 182 183/** 184 * Configure a process with more customisations (Create your own vspace, customise cspace size). 185 * 186 * @param process uninitialised process struct 187 * @param vka allocator to use to allocate objects. 188 * @param spawner_vspace vspace to use to allocate virtual memory in the current address space. 189 * @param config process config. 190 * 191 * @return 0 on success, -1 on error. 192 */ 193int sel4utils_configure_process_custom(sel4utils_process_t *process, vka_t *target_vka, 194 vspace_t *spawner_vspace, sel4utils_process_config_t config); 195 196/** 197 * Copy a cap into a process' cspace. 198 * 199 * This will only work if you configured the process using one of the above functions, or 200 * have mimicked their functionality. 201 * 202 * @param process process to copy the cap to 203 * @param src path in the current cspace to copy the cap from 204 * 205 * @return 0 on failure, otherwise the slot in the processes cspace. 206 */ 207seL4_CPtr sel4utils_copy_path_to_process(sel4utils_process_t *process, cspacepath_t src); 208 209/** 210 * Copy a cap into a process' cspace. 211 * 212 * This will only work if you configured the process using one of the above functions, or 213 * have mimicked their functionality. 214 * 215 * @param process process to copy the cap to 216 * @param vka vka that can translate the cap into a cspacepath_t. 217 * @param cap cap location in your own cspace. 218 * 219 * @return 0 on failure, otherwise the slot in the processes cspace. 220 */ 221seL4_CPtr sel4utils_copy_cap_to_process(sel4utils_process_t *process, vka_t *vka, seL4_CPtr cap); 222 223/** 224 * Move a cap into a process' cspace. 225 * 226 * This will only work if you configured the process using one of the above functions, or 227 * have mimicked their functionality. Additionally the VKA that is passed in to have the 228 * slot freed can only do this if it is tracking that slot. IE when moving one of the initial 229 * caps provided by bootinfo such as the IRQ Control Cap the VKA may not be able to free the slot. 230 * Passing in NULL for the VKA will result in no slot being freed. 231 * 232 * @param process process to move the cap to 233 * @param src path in the current cspace to move the cap from 234 * @param vka the allocator that owns the cslot the cap is currently in, so it may be freed after the move. 235 * if NULL, then the original slot will not be freed. 236 * 237 * @return 0 on failure, otherwise the slot in the processes cspace. 238 */ 239seL4_CPtr sel4utils_move_cap_to_process(sel4utils_process_t *process, cspacepath_t src, vka_t *from_vka); 240 241/** 242 * 243 * Mint a cap into a process' cspace. 244 * 245 * As above, except mint the cap with rights and data. 246 * 247 * @return 0 on failure, otherwise the slot in the cspace where the new cap is. 248 */ 249seL4_CPtr sel4utils_mint_cap_to_process(sel4utils_process_t *process, cspacepath_t src, seL4_CapRights_t rights, 250 seL4_Word data); 251 252/** 253 * Destroy a process. 254 * 255 * This will free everything possible associated with a process and teardown the vspace. 256 * 257 * @param process process to destroy 258 * @param vka allocator used to allocate objects for this process 259 */ 260void sel4utils_destroy_process(sel4utils_process_t *process, vka_t *vka); 261 262/* 263 * sel4utils default allocated object function for vspaces. 264 * 265 * Stores a list of allocated objects in the process struct and frees them 266 * when sel4utils_destroy_process is called. 267 */ 268void sel4utils_allocated_object(void *cookie, vka_object_t object); 269 270/* 271 * Create c-formatted argument list to pass to a process from arbitrarily long amount of words. 272 * 273 * @param strings empty 2d array of chars to populate with word strings. 274 * @param argv empty 1d array of char pointers which will be set up with pointers to 275 * strings in strings. 276 * @param argc number of words 277 * @param ... list of words to create arguments from. 278 * 279 */ 280void sel4utils_create_word_args(char strings[][WORD_STRING_SIZE], char *argv[], int argc, ...); 281 282/* 283 * Get the initial cap equivalent for a sel4utils created process. 284 * This will only work if sel4utils created the processes cspace. 285 * 286 * @param cap initial cap index from sel4/bootinfo_types.h 287 * @return the corresponding cap in a sel4utils launched process. 288 */ 289seL4_CPtr sel4utils_process_init_cap(void *data, seL4_CPtr cap); 290 291/* 292 * Helper function for copying timer IRQs and Device untyped caps into another process. 293 * 294 * @param to struct to store new cap info 295 * @param from struct containing current cap info 296 * @param vka vka to create cnodes 297 * @param process target process to copy caps too 298 * 299 * @return 0 on success. 300 */ 301int sel4utils_copy_timer_caps_to_process(timer_objects_t *to, timer_objects_t *from, vka_t *vka, 302 sel4utils_process_t *process); 303