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