1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8#include <autoconf.h> 9 10#include <sel4/functions.h> 11 12/** 13 * @defgroup SystemCalls System Calls 14 * @{ 15 * 16 */ 17 18#ifdef CONFIG_KERNEL_MCS 19#include "syscalls_mcs.h" 20#else 21#include "syscalls_master.h" 22#endif 23 24/** 25 * @defgroup DebuggingSystemCalls 26 * This section documents debugging system calls available when the kernel is 27 * build with the `DEBUG_BUILD` configuration. For any system calls that rely 28 * on a kernel serial driver, `PRINTING` must also be enabled. 29 * 30 * @{ 31 */ 32#ifdef CONFIG_PRINTING 33/** 34 * @xmlonly <manual name="Put Char" label="sel4_debugputchar"/> @endxmlonly 35 * @brief Output a single char through the kernel. 36 * 37 * Use the kernel serial driver to output a single character. This is useful for 38 * debugging when a user level serial driver is not available. 39 * 40 * @param c The character to output. 41 * 42 */ 43LIBSEL4_INLINE_FUNC void 44seL4_DebugPutChar(char c); 45 46/** 47 * @xmlonly <manual name="Dump scheduler" label="sel4_dumpscheduler"/> @endxmlonly 48 * @brief Output the contents of the kernel scheduler. 49 * 50 * Dump the state of the all TCB objects to kernel serial output. This system call 51 * will output a table containing: 52 * - Address: the address of the TCB object for that thread, 53 * - Name: the name of the thread (if set), 54 * - IP: the contents of the instruction pointer the thread is at, 55 * - Priority: the priority of that thread, 56 * - State : the state of the thread. 57 */ 58 59LIBSEL4_INLINE_FUNC void 60seL4_DebugDumpScheduler(void); 61#endif 62 63#if CONFIG_DEBUG_BUILD 64/** 65 * @xmlonly <manual name="Halt" label="sel4_debughalt"/> @endxmlonly 66 * @brief Halt the system. 67 * 68 * This debugging system call will cause the kernel immediately cease responding to 69 * system calls. The kernel will switch permanently to the idle thread with 70 * interrupts disabled. Depending on the platform, the kernel may switch 71 * the hardware into a low-power state. 72 * 73 */ 74LIBSEL4_INLINE_FUNC void 75seL4_DebugHalt(void); 76 77/** 78 * @xmlonly <manual name="Snapshot" label="sel4_debugsnapshot"/> @endxmlonly 79 * @brief Output a capDL dump of the current kernel state. 80 * 81 * This debugging system call will output all of the capabilities in the current 82 * kernel using capDL. 83 * 84 */ 85LIBSEL4_INLINE_FUNC void 86seL4_DebugSnapshot(void); 87 88/** 89 * @xmlonly <manual name="Cap Identify" label="sel4_debugcapidentify"/> @endxmlonly 90 * @brief Identify the type of a capability in the current cspace. 91 * 92 * This debugging system call returns the type of capability in a capability 93 * slot in the current cspace. The type returned is not a libsel4 type, but 94 * refers to an internal seL4 type. This can be looked up in a built kernel by 95 * looking for the (generated) `enum cap_tag`, type `cap_tag_t`. 96 * 97 * @param cap A capability slot in the current cspace. 98 * @return The type of capability passed in. 99 * 100 */ 101LIBSEL4_INLINE_FUNC seL4_Uint32 102seL4_DebugCapIdentify(seL4_CPtr cap); 103 104/** 105 * @xmlonly <manual name="Name Thread" label="sel4_debugnamethread"/> @endxmlonly 106 * @brief Name a thread. 107 * 108 * Name a thread. This name will then be output by the kernel in all debugging output. 109 * Note that the max name length that can be passed to this function is limited by the 110 * number of chars that will fit in an IPC message (`seL4_MsgMaxLength` multiplied by the 111 * amount of chars that fit in a word). However the name is also truncated in order to fit into a TCB object. 112 * For some platforms you may need to increase `seL4_TCBBits` by 1 in a debug build in order to 113 * fit a long enough name. 114 * 115 * @param tcb A capability to the tcb object for the thread to name. 116 * @param name The name for the thread. 117 * 118 */ 119LIBSEL4_INLINE_FUNC void 120seL4_DebugNameThread(seL4_CPtr tcb, const char *name); 121#if CONFIG_MAX_NUM_NODES > 1 && defined CONFIG_ARCH_ARM 122/** 123 * @xmlonly <manual name="Send SGI 0-15" label="sel4_debugsendipi"/> @endxmlonly 124 * @brief Sends arbitrary SGI. 125 * 126 * Send an arbitrary SGI (core-specific interrupt 0-15) to the specified target core. 127 * 128 * @param target The target core ID. 129 * @param irq The SGI number (0-15). 130 * 131 */ 132LIBSEL4_INLINE_FUNC void 133seL4_DebugSendIPI(seL4_Uint8 target, unsigned irq); 134#endif 135#endif 136 137#ifdef CONFIG_DANGEROUS_CODE_INJECTION 138/** 139 * @xmlonly <manual name="Run" label="sel4_debugrun"/> @endxmlonly 140 * @brief Run a user level function in kernel mode. 141 * 142 * This extremely dangerous function is for running benchmarking and debugging code that 143 * needs to be executed in kernel mode from userlevel. It should never be used in a release kernel. 144 * This works because the kernel can access all user mappings of device memory, and does not switch page directories 145 * on kernel entry. 146 * 147 * Unlike the other system calls in this section, `seL4_DebugRun` does not 148 * depend on the `DEBUG_BUILD` configuration option, but its own config 149 * variable `DANGEROUS_CODE_INJECTION`. 150 * 151 * @param userfn The address in userspace of the function to run. 152 * @param userarg A single argument to pass to the function. 153 * 154 */ 155LIBSEL4_INLINE_FUNC void 156seL4_DebugRun(void (* userfn)(void *), void *userarg); 157#endif 158/** @} */ 159 160/** 161 * @defgroup BenchmarkingSystemCalls 162 * This section documents system calls available when the kernel is 163 * configured with benchmarking enabled. 164 * There are several different benchmarking modes which can be configured 165 * when building the kernel: 166 * 1. `BENCHMARK_TRACEPOINTS`: Enable using tracepoints in the kernel and timing code. 167 * 2. `BENCHMARK_TRACK_KERNEL_ENTRIES`: Keep track of information on kernel entries. 168 * 3. `BENCHMARK_TRACK_UTILISATION`: Allow users to get CPU timing info for the system, threads and/or idle thread. 169 * 170 * `BENCHMARK_TRACEPOINTS` and `BENCHMARK_TRACK_KERNEL_ENTRIES` use a log buffer that has to be allocated by the user and mapped 171 * to a fixed location in the kernel window. 172 * All of timing information is output in cycles. 173 * 174 * @{ 175 */ 176#ifdef CONFIG_ENABLE_BENCHMARKS 177/* 178 */ 179 180/** 181 * @xmlonly <manual name="Reset Log" label="sel4_benchmarkresetlog"/> @endxmlonly 182 * @brief Reset benchmark logging. 183 * 184 * The behaviour of this system call depends on benchmarking mode in action while invoking 185 * this system call: 186 * 1. `BENCHMARK_TRACEPOINTS`: resets the log index to 0, 187 * 2. `BENCHMARK_TRACK_KERNEL_ENTRIES`: as above, 188 * 3. `BENCHMARK_TRACK_UTILISATION`: resets benchmark and current thread 189 * start time (to the time of invoking this syscall), resets idle 190 * thread utilisation to 0, and starts tracking utilisation. 191 * 192 * @return A `seL4_Error` error if the user-level log buffer has not been set by the user 193 * (`BENCHMARK_TRACEPOINTS`/`BENCHMARK_TRACK_KERNEL_ENTRIES`). 194 */ 195LIBSEL4_INLINE_FUNC seL4_Error 196seL4_BenchmarkResetLog(void); 197 198/** 199 * @xmlonly <manual name="Finalize Log" label="sel4_benchmarkfinalizelog"/> @endxmlonly 200 * @brief Stop benchmark logging. 201 * 202 * The behaviour of this system call depends on benchmarking mode in action while invoking this system call: 203 * 1. `BENCHMARK_TRACEPOINTS`: Sets the final log buffer index to the current index, 204 * 2. `BENCHMARK_TRACK_KERNEL_ENTRIES`: as above, 205 * 3. `BENCHMARK_TRACK_UTILISATION`: sets benchmark end time to current time, stops tracking utilisation. 206 * 207 * @return The index of the final entry in the log buffer (if `BENCHMARK_TRACEPOINTS`/`BENCHMARK_TRACK_KERNEL_ENTRIES` are enabled). 208 * 209 */ 210LIBSEL4_INLINE_FUNC seL4_Word 211seL4_BenchmarkFinalizeLog(void); 212 213/** 214 * @xmlonly <manual name="Set Log Buffer" label="sel4_benchmarksetlogbuffer"/> @endxmlonly 215 * @brief Set log buffer. 216 * 217 * Provide a large frame object for the kernel to use as a log-buffer. 218 * The object must not be device memory, and must be seL4_LargePageBits in size. 219 * 220 * @param[in] frame_cptr A capability pointer to a user allocated frame of seL4_LargePage size. 221 * @return A `seL4_IllegalOperation` error if `frame_cptr` is not valid and couldn't set the buffer. 222 * 223 */ 224LIBSEL4_INLINE_FUNC seL4_Error 225seL4_BenchmarkSetLogBuffer(seL4_Word frame_cptr); 226 227/** 228 * @xmlonly <manual name="Null Syscall" label="sel4_benchmarknullsyscall"/> @endxmlonly 229 * @brief Null system call that enters and exits the kernel immediately, for timing kernel traps in microbenchmarks. 230 * 231 * Used to time kernel traps (in and out). 232 * 233 */ 234LIBSEL4_INLINE_FUNC void 235seL4_BenchmarkNullSyscall(void); 236 237/** 238 * @xmlonly <manual name="Flush Caches" label="sel4_benchmarkflushcaches"/> @endxmlonly 239 * @brief Flush hardware caches. 240 * 241 * Flush all possible hardware caches for this platform. 242 */ 243LIBSEL4_INLINE_FUNC void 244seL4_BenchmarkFlushCaches(void); 245 246#ifdef CONFIG_ARCH_ARM 247/** 248 * @xmlonly <manual name="Flush L1 Caches" label="sel4_benchmarkflushl1caches"/> @endxmlonly 249 * @brief Flush L1 caches. 250 * 251 * Flush L1 caches for this platform (currently only support for ARM). Allow to specify the cache type 252 * to be flushed (i.e. instruction cache only, data cache only and both instruction cache and data cache). 253 * 254 * @param[in] cache_type L1 Cache Type to be flushed 255 */ 256LIBSEL4_INLINE_FUNC void 257seL4_BenchmarkFlushL1Caches(seL4_Word cache_type); 258#endif 259 260#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION 261/** 262 * @xmlonly <manual name="Get Thread Utilisation" label="sel4_benchmarkgetthreadutilisation"/> @endxmlonly 263 * @brief Get utilisation timing information. 264 * 265 * Get timing information for the system, requested thread and idle thread. Such information is written 266 * into the caller's IPC buffer; see the definition of `benchmark_track_util_ipc_index` enum for more 267 * details on the data/format returned on the IPC buffer. 268 * 269 * @param[in] tcb_cptr TCB cap pointer to a thread to get CPU utilisation for. 270 */ 271LIBSEL4_INLINE_FUNC void 272seL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr); 273 274/** 275 * @xmlonly <manual name="Reset Thread Utilisation" label="sel4_benchmarkresetthreadutilisation"/> @endxmlonly 276 * @brief Reset utilisation timing for a specific thread. 277 * 278 * Reset the kernel's timing information data (start time and utilisation) for a specific thread. 279 * 280 * @param[in] tcb_cptr TCB cap pointer to a thread to get CPU utilisation for. 281 * 282 */ 283LIBSEL4_INLINE_FUNC void 284seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr); 285 286#ifdef CONFIG_DEBUG_BUILD 287/** 288 * @xmlonly <manual name="Dump All Threads Utilisation" label="sel4_benchmarkdumpallthreadsutilisation"/> @endxmlonly 289 * @brief Print the current accumulated cycle count for every thread on the current node. 290 * 291 * Uses kernel's printf to print number of cycles on each line in the following format: thread_name,thread_cycles 292 * 293 */ 294LIBSEL4_INLINE_FUNC void 295seL4_BenchmarkDumpAllThreadsUtilisation(void); 296 297/** 298 * @xmlonly <manual name="Reset All Threads Utilisation" label="sel4_benchmarkresetallthreadsutilisation"/> @endxmlonly 299 * @brief Reset the accumulated cycle count for every thread on the current node. 300 * 301 * Reset the cycle count for each thread to 0. 302 * 303 */ 304LIBSEL4_INLINE_FUNC void 305seL4_BenchmarkResetAllThreadsUtilisation(void); 306 307#endif 308#endif 309#endif 310/** @} */ 311 312#ifdef CONFIG_ARCH_X86 313/** 314 * @defgroup X86SystemCalls X86 System Calls 315 * @{ 316 */ 317 318#ifdef CONFIG_VTX 319/** 320 * @xmlonly <manual name="VMEnter" label="sel4_vmenter"/> @endxmlonly 321 * @brief Change current thread to execute from its bound VCPU 322 * 323 * Changes the execution mode of the current thread from normal TCB execution, to 324 * guest execution using its bound VCPU. 325 * @xmlonly 326 * <docref>For details on VCPUs and execution modes see <autoref label="sec:virt"/>.</docref> 327 * @endxmlonly 328 * 329 * Invoking `seL4_VMEnter` is similar to replying to a fault in that updates to the registers 330 * can be given in the message, but unlike a fault no message info 331 * @xmlonly 332 * <docref>(see <autoref label="sec:messageinfo"/>)</docref> 333 * @endxmlonly 334 * is sent as the registers are not optional and the number that must be sent is fixed. 335 * The mapping of hardware register to message register is 336 * - `SEL4_VMENTER_CALL_EIP_MR` Address to start executing instructions at in the guest mode 337 * - `SEL4_VMENTER_CALL_CONTROL_PPC_MR` New value for the Primary Processor Based VM Execution Controls 338 * - `SEL4_VMENTER_CALL_CONTROL_ENTRY_MR` New value for the VM Entry Controls 339 * 340 * On return these same three message registers will be filled with the values at the point 341 * that the privlidged mode ceased executing. If this function returns with `SEL4_VMENTER_RESULT_FAULT` 342 * then the following additional message registers will be filled out 343 * - `SEL4_VMENTER_FAULT_REASON_MR` 344 * - `SEL4_VMENTER_FAULT_QUALIFICATION_MR` 345 * - `SEL4_VMENTER_FAULT_INSTRUCTION_LEN_MR` 346 * - `SEL4_VMENTER_FAULT_GUEST_PHYSICAL_MR` 347 * - `SEL4_VMENTER_FAULT_RFLAGS_MR` 348 * - `SEL4_VMENTER_FAULT_GUEST_INT_MR` 349 * - `SEL4_VMENTER_FAULT_CR3_MR` 350 * - `SEL4_VMENTER_FAULT_EAX` 351 * - `SEL4_VMENTER_FAULT_EBX` 352 * - `SEL4_VMENTER_FAULT_ECX` 353 * - `SEL4_VMENTER_FAULT_EDX` 354 * - `SEL4_VMENTER_FAULT_ESI` 355 * - `SEL4_VMENTER_FAULT_EDI` 356 * - `SEL4_VMENTER_FAULT_EBP` 357 * 358 * @param[out] sender The address to write sender information to. 359 * If the syscall returns due to receiving a notification 360 * on the bound notification then the sender information 361 * is the badge of the notification capability that was invoked. 362 * This parameter is ignored if `NULL`. 363 * @return `SEL4_VMENTER_RESULT_NOTIF` if a notification was received or `SEL4_VMENTER_RESULT_FAULT` 364 * if the guest mode execution faulted for any reason 365 */ 366LIBSEL4_INLINE_FUNC seL4_Word 367seL4_VMEnter(seL4_Word *sender); 368#endif 369 370/** @} */ 371#endif 372 373/** @} */ 374 375#ifdef CONFIG_SET_TLS_BASE_SELF 376/** 377 * @xmlonly <manual name="SetTLSBase" label="sel4_settlsbase"/> @endxmlonly 378 * @brief Set the TLS base address and register of the currently executing thread. 379 * 380 * This stores the base address of the TLS region in the register 381 * reserved for that purpose on the given platform. 382 * 383 * Each platform has a specific register reserved for tracking the 384 * base address of the TLS region (as sepcified in the ELF standard) in 385 * a manner compatible with the TLS method used with that architecture. 386 * 387 * @param tls_base The new base address to store in the register. 388 */ 389LIBSEL4_INLINE_FUNC void 390seL4_SetTLSBase(seL4_Word tls_base); 391#endif 392 393