1208625Sjkim/*
2208625Sjkim * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3208625Sjkim *
4208625Sjkim * SPDX-License-Identifier: BSD-2-Clause
5208625Sjkim */
6208625Sjkim
7217365Sjkim#pragma once
8306536Sjkim#include <autoconf.h>
9208625Sjkim
10208625Sjkim#include <sel4/functions.h>
11217365Sjkim
12217365Sjkim/**
13217365Sjkim * @defgroup SystemCalls System Calls
14217365Sjkim * @{
15217365Sjkim *
16217365Sjkim */
17217365Sjkim
18217365Sjkim#ifdef CONFIG_KERNEL_MCS
19217365Sjkim#include "syscalls_mcs.h"
20217365Sjkim#else
21217365Sjkim#include "syscalls_master.h"
22217365Sjkim#endif
23217365Sjkim
24217365Sjkim/**
25208625Sjkim * @defgroup DebuggingSystemCalls
26217365Sjkim * This section documents debugging system calls available when the kernel is
27217365Sjkim * build with the `DEBUG_BUILD` configuration. For any system calls that rely
28217365Sjkim * on a kernel serial driver, `PRINTING` must also be enabled.
29208625Sjkim *
30217365Sjkim * @{
31217365Sjkim */
32217365Sjkim#ifdef CONFIG_PRINTING
33217365Sjkim/**
34217365Sjkim * @xmlonly <manual name="Put Char" label="sel4_debugputchar"/> @endxmlonly
35217365Sjkim * @brief Output a single char through the kernel.
36217365Sjkim *
37217365Sjkim * Use the kernel serial driver to output a single character. This is useful for
38217365Sjkim * debugging when a user level serial driver is not available.
39217365Sjkim *
40217365Sjkim * @param c The character to output.
41217365Sjkim *
42217365Sjkim */
43208625SjkimLIBSEL4_INLINE_FUNC void
44209746SjkimseL4_DebugPutChar(char c);
45209746Sjkim
46209746Sjkim/**
47208625Sjkim * @xmlonly <manual name="Dump scheduler" label="sel4_dumpscheduler"/> @endxmlonly
48208625Sjkim * @brief Output the contents of the kernel scheduler.
49208625Sjkim *
50208625Sjkim * Dump the state of the all TCB objects to kernel serial output. This system call
51208625Sjkim * will output a table containing:
52208625Sjkim *    - Address: the address of the TCB object for that thread,
53208625Sjkim *    - Name:    the name of the thread (if set),
54208625Sjkim *    - IP:      the contents of the instruction pointer the thread is at,
55208625Sjkim *    - Priority: the priority of that thread,
56208625Sjkim *    - State   : the state of the thread.
57208625Sjkim */
58208625Sjkim
59208625SjkimLIBSEL4_INLINE_FUNC void
60208625SjkimseL4_DebugDumpScheduler(void);
61208625Sjkim#endif
62208625Sjkim
63208625Sjkim#if CONFIG_DEBUG_BUILD
64208625Sjkim/**
65208625Sjkim * @xmlonly <manual name="Halt" label="sel4_debughalt"/> @endxmlonly
66208625Sjkim * @brief Halt the system.
67208625Sjkim *
68208625Sjkim * This debugging system call will cause the kernel immediately cease responding to
69208625Sjkim * system calls. The kernel will switch permanently to the idle thread with
70208625Sjkim * interrupts disabled. Depending on the platform, the kernel may switch
71208625Sjkim * the hardware into a low-power state.
72208625Sjkim *
73208625Sjkim */
74208625SjkimLIBSEL4_INLINE_FUNC void
75208625SjkimseL4_DebugHalt(void);
76208625Sjkim
77208625Sjkim/**
78281075Sdim * @xmlonly <manual name="Snapshot" label="sel4_debugsnapshot"/> @endxmlonly
79208625Sjkim * @brief Output a capDL dump of the current kernel state.
80208625Sjkim *
81208625Sjkim * This debugging system call will output all of the capabilities in the current
82208625Sjkim * kernel using capDL.
83250838Sjkim *
84250838Sjkim */
85250838SjkimLIBSEL4_INLINE_FUNC void
86208625SjkimseL4_DebugSnapshot(void);
87250838Sjkim
88208625Sjkim/**
89208625Sjkim * @xmlonly <manual name="Cap Identify" label="sel4_debugcapidentify"/> @endxmlonly
90208625Sjkim * @brief Identify the type of a capability in the current cspace.
91208625Sjkim *
92208625Sjkim * This debugging system call returns the type of capability in a capability
93208625Sjkim * slot in the current cspace. The type returned is not a libsel4 type, but
94208625Sjkim * refers to an internal seL4 type. This can be looked up in a built kernel by
95208625Sjkim * looking for the (generated) `enum cap_tag`, type `cap_tag_t`.
96208625Sjkim *
97208625Sjkim * @param cap A capability slot in the current cspace.
98208625Sjkim * @return The type of capability passed in.
99208625Sjkim *
100208625Sjkim */
101208625SjkimLIBSEL4_INLINE_FUNC seL4_Uint32
102208625SjkimseL4_DebugCapIdentify(seL4_CPtr cap);
103208625Sjkim
104208625Sjkim/**
105208625Sjkim * @xmlonly <manual name="Name Thread" label="sel4_debugnamethread"/> @endxmlonly
106208625Sjkim * @brief Name a thread.
107208625Sjkim *
108208625Sjkim * Name a thread. This name will then be output by the kernel in all debugging output.
109208625Sjkim * Note that the max name length that can be passed to this function is limited by the
110208625Sjkim * number of chars that will fit in an IPC message (`seL4_MsgMaxLength` multiplied by the
111208625Sjkim * amount of chars that fit in a word). However the name is also truncated in order to fit into a TCB object.
112208625Sjkim * For some platforms you may need to increase `seL4_TCBBits` by 1 in a debug build in order to
113208625Sjkim * fit a long enough name.
114208625Sjkim *
115208625Sjkim * @param tcb A capability to the tcb object for the thread to name.
116208625Sjkim * @param name The name for the thread.
117208625Sjkim *
118208625Sjkim */
119208625SjkimLIBSEL4_INLINE_FUNC void
120208625SjkimseL4_DebugNameThread(seL4_CPtr tcb, const char *name);
121208625Sjkim#if CONFIG_MAX_NUM_NODES > 1 && defined CONFIG_ARCH_ARM
122208625Sjkim/**
123208625Sjkim * @xmlonly <manual name="Send SGI 0-15" label="sel4_debugsendipi"/> @endxmlonly
124208625Sjkim * @brief Sends arbitrary SGI.
125281075Sdim *
126208625Sjkim * Send an arbitrary SGI (core-specific interrupt 0-15) to the specified target core.
127208625Sjkim *
128208625Sjkim * @param target The target core ID.
129208625Sjkim * @param irq The SGI number (0-15).
130208625Sjkim *
131208625Sjkim */
132208625SjkimLIBSEL4_INLINE_FUNC void
133208625SjkimseL4_DebugSendIPI(seL4_Uint8 target, unsigned irq);
134250838Sjkim#endif
135208625Sjkim#endif
136208625Sjkim
137208625Sjkim#ifdef CONFIG_DANGEROUS_CODE_INJECTION
138208625Sjkim/**
139208625Sjkim * @xmlonly <manual name="Run" label="sel4_debugrun"/> @endxmlonly
140208625Sjkim * @brief Run a user level function in kernel mode.
141208625Sjkim *
142250838Sjkim * This extremely dangerous function is for running benchmarking and debugging code that
143208625Sjkim * needs to be executed in kernel mode from userlevel. It should never be used in a release kernel.
144208625Sjkim * This works because the kernel can access all user mappings of device memory, and does not switch page directories
145208625Sjkim * on kernel entry.
146208625Sjkim *
147208625Sjkim * Unlike the other system calls in this section, `seL4_DebugRun` does not
148208625Sjkim * depend on the `DEBUG_BUILD` configuration option, but its own config
149208625Sjkim * variable `DANGEROUS_CODE_INJECTION`.
150208625Sjkim *
151208625Sjkim * @param userfn The address in userspace of the function to run.
152208625Sjkim * @param userarg A single argument to pass to the function.
153208625Sjkim *
154208625Sjkim */
155208625SjkimLIBSEL4_INLINE_FUNC void
156208625SjkimseL4_DebugRun(void (* userfn)(void *), void *userarg);
157208625Sjkim#endif
158208625Sjkim/** @} */
159208625Sjkim
160208625Sjkim/**
161208625Sjkim * @defgroup BenchmarkingSystemCalls
162208625Sjkim * This section documents system calls available when the kernel is
163208625Sjkim * configured with benchmarking enabled.
164208625Sjkim * There are several different benchmarking modes which can be configured
165208625Sjkim * when building the kernel:
166208625Sjkim *     1. `BENCHMARK_TRACEPOINTS`: Enable using tracepoints in the kernel and timing code.
167208625Sjkim *     2. `BENCHMARK_TRACK_KERNEL_ENTRIES`: Keep track of information on kernel entries.
168208625Sjkim *     3. `BENCHMARK_TRACK_UTILISATION`: Allow users to get CPU timing info for the system, threads and/or idle thread.
169208625Sjkim *
170208625Sjkim * `BENCHMARK_TRACEPOINTS` and `BENCHMARK_TRACK_KERNEL_ENTRIES` use a log buffer that has to be allocated by the user and mapped
171208625Sjkim * to a fixed location in the kernel window.
172208625Sjkim * All of timing information is output in cycles.
173208625Sjkim *
174208625Sjkim * @{
175208625Sjkim */
176208625Sjkim#ifdef CONFIG_ENABLE_BENCHMARKS
177208625Sjkim/*
178281075Sdim  */
179208625Sjkim
180208625Sjkim/**
181208625Sjkim * @xmlonly <manual name="Reset Log" label="sel4_benchmarkresetlog"/> @endxmlonly
182208625Sjkim * @brief Reset benchmark logging.
183208625Sjkim *
184208625Sjkim * The behaviour of this system call depends on benchmarking mode in action while invoking
185220663Sjkim * this system call:
186220663Sjkim *    1. `BENCHMARK_TRACEPOINTS`: resets the log index to 0,
187220663Sjkim *    2. `BENCHMARK_TRACK_KERNEL_ENTRIES`:  as above,
188220663Sjkim *    3. `BENCHMARK_TRACK_UTILISATION`: resets benchmark and current thread
189220663Sjkim *        start time (to the time of invoking this syscall), resets idle
190220663Sjkim *        thread utilisation to 0, and starts tracking utilisation.
191220663Sjkim *
192208625Sjkim * @return A `seL4_Error` error if the user-level log buffer has not been set by the user
193208625Sjkim *                         (`BENCHMARK_TRACEPOINTS`/`BENCHMARK_TRACK_KERNEL_ENTRIES`).
194220663Sjkim */
195208625SjkimLIBSEL4_INLINE_FUNC seL4_Error
196208625SjkimseL4_BenchmarkResetLog(void);
197208625Sjkim
198208625Sjkim/**
199208625Sjkim * @xmlonly <manual name="Finalize Log" label="sel4_benchmarkfinalizelog"/> @endxmlonly
200208625Sjkim * @brief Stop benchmark logging.
201208625Sjkim *
202208625Sjkim * The behaviour of this system call depends on benchmarking mode in action while invoking this system call:
203208625Sjkim *    1. `BENCHMARK_TRACEPOINTS`: Sets the final log buffer index to the current index,
204208625Sjkim *    2. `BENCHMARK_TRACK_KERNEL_ENTRIES`:  as above,
205208625Sjkim *    3. `BENCHMARK_TRACK_UTILISATION`: sets benchmark end time to current time, stops tracking utilisation.
206208625Sjkim *
207208625Sjkim * @return The index of the final entry in the log buffer (if `BENCHMARK_TRACEPOINTS`/`BENCHMARK_TRACK_KERNEL_ENTRIES` are enabled).
208208625Sjkim *
209208625Sjkim */
210208625SjkimLIBSEL4_INLINE_FUNC seL4_Word
211208625SjkimseL4_BenchmarkFinalizeLog(void);
212208625Sjkim
213208625Sjkim/**
214208625Sjkim * @xmlonly <manual name="Set Log Buffer" label="sel4_benchmarksetlogbuffer"/> @endxmlonly
215208625Sjkim * @brief Set log buffer.
216208625Sjkim *
217208625Sjkim * Provide a large frame object for the kernel to use as a log-buffer.
218208625Sjkim * The object must not be device memory, and must be seL4_LargePageBits in size.
219208625Sjkim *
220208625Sjkim * @param[in] frame_cptr A capability pointer to a user allocated frame of seL4_LargePage size.
221208625Sjkim * @return A `seL4_IllegalOperation` error if `frame_cptr` is not valid and couldn't set the buffer.
222208625Sjkim *
223208625Sjkim */
224208625SjkimLIBSEL4_INLINE_FUNC seL4_Error
225208625SjkimseL4_BenchmarkSetLogBuffer(seL4_Word frame_cptr);
226208625Sjkim
227208625Sjkim/**
228208625Sjkim * @xmlonly <manual name="Null Syscall" label="sel4_benchmarknullsyscall"/> @endxmlonly
229208625Sjkim * @brief Null system call that enters and exits the kernel immediately, for timing kernel traps in microbenchmarks.
230208625Sjkim *
231208625Sjkim *  Used to time kernel traps (in and out).
232208625Sjkim *
233208625Sjkim */
234208625SjkimLIBSEL4_INLINE_FUNC void
235208625SjkimseL4_BenchmarkNullSyscall(void);
236208625Sjkim
237208625Sjkim/**
238208625Sjkim * @xmlonly <manual name="Flush Caches" label="sel4_benchmarkflushcaches"/> @endxmlonly
239208625Sjkim * @brief Flush hardware caches.
240208625Sjkim *
241208625Sjkim * Flush all possible hardware caches for this platform.
242208625Sjkim */
243208625SjkimLIBSEL4_INLINE_FUNC void
244306536SjkimseL4_BenchmarkFlushCaches(void);
245208625Sjkim
246208625Sjkim#ifdef CONFIG_ARCH_ARM
247208625Sjkim/**
248208625Sjkim * @xmlonly <manual name="Flush L1 Caches" label="sel4_benchmarkflushl1caches"/> @endxmlonly
249208625Sjkim * @brief Flush L1 caches.
250208625Sjkim *
251208625Sjkim * Flush L1 caches for this platform (currently only support for ARM). Allow to specify the cache type
252306536Sjkim * to be flushed (i.e. instruction cache only, data cache only and both instruction cache and data cache).
253306536Sjkim *
254208625Sjkim * @param[in] cache_type L1 Cache Type to be flushed
255208625Sjkim */
256208625SjkimLIBSEL4_INLINE_FUNC void
257208625SjkimseL4_BenchmarkFlushL1Caches(seL4_Word cache_type);
258208625Sjkim#endif
259208625Sjkim
260208625Sjkim#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
261208625Sjkim/**
262208625Sjkim * @xmlonly <manual name="Get Thread Utilisation" label="sel4_benchmarkgetthreadutilisation"/> @endxmlonly
263208625Sjkim * @brief Get utilisation timing information.
264208625Sjkim *
265208625Sjkim * Get timing information for the system, requested thread and idle thread. Such information is written
266208625Sjkim * into the caller's IPC buffer; see the definition of `benchmark_track_util_ipc_index` enum for more
267208625Sjkim * details on the data/format returned on the IPC buffer.
268208625Sjkim *
269208625Sjkim * @param[in] tcb_cptr TCB cap pointer to a thread to get CPU utilisation for.
270208625Sjkim */
271208625SjkimLIBSEL4_INLINE_FUNC void
272208625SjkimseL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr);
273208625Sjkim
274208625Sjkim/**
275208625Sjkim * @xmlonly <manual name="Reset Thread Utilisation" label="sel4_benchmarkresetthreadutilisation"/> @endxmlonly
276208625Sjkim * @brief Reset utilisation timing for a specific thread.
277208625Sjkim *
278208625Sjkim * Reset the kernel's timing information data (start time and utilisation) for a specific thread.
279208625Sjkim *
280208625Sjkim * @param[in] tcb_cptr TCB cap pointer to a thread to get CPU utilisation for.
281208625Sjkim *
282208625Sjkim */
283208625SjkimLIBSEL4_INLINE_FUNC void
284208625SjkimseL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr);
285208625Sjkim
286208625Sjkim#ifdef CONFIG_DEBUG_BUILD
287208625Sjkim/**
288208625Sjkim * @xmlonly <manual name="Dump All Threads Utilisation" label="sel4_benchmarkdumpallthreadsutilisation"/> @endxmlonly
289208625Sjkim * @brief Print the current accumulated cycle count for every thread on the current node.
290208625Sjkim *
291208625Sjkim *  Uses kernel's printf to print number of cycles on each line in the following format: thread_name,thread_cycles
292208625Sjkim *
293208625Sjkim */
294208625SjkimLIBSEL4_INLINE_FUNC void
295208625SjkimseL4_BenchmarkDumpAllThreadsUtilisation(void);
296208625Sjkim
297208625Sjkim/**
298208625Sjkim * @xmlonly <manual name="Reset All Threads Utilisation" label="sel4_benchmarkresetallthreadsutilisation"/> @endxmlonly
299220663Sjkim * @brief Reset the accumulated cycle count for every thread on the current node.
300208625Sjkim *
301220663Sjkim *  Reset the cycle count for each thread to 0.
302208625Sjkim *
303220663Sjkim */
304208625SjkimLIBSEL4_INLINE_FUNC void
305208625SjkimseL4_BenchmarkResetAllThreadsUtilisation(void);
306220663Sjkim
307208625Sjkim#endif
308208625Sjkim#endif
309208625Sjkim#endif
310208625Sjkim/** @} */
311208625Sjkim
312208625Sjkim#ifdef CONFIG_ARCH_X86
313208625Sjkim/**
314208625Sjkim * @defgroup X86SystemCalls X86 System Calls
315208625Sjkim * @{
316208625Sjkim */
317208625Sjkim
318208625Sjkim#ifdef CONFIG_VTX
319208625Sjkim/**
320208625Sjkim * @xmlonly <manual name="VMEnter" label="sel4_vmenter"/> @endxmlonly
321208625Sjkim * @brief Change current thread to execute from its bound VCPU
322208625Sjkim *
323208625Sjkim * Changes the execution mode of the current thread from normal TCB execution, to
324208625Sjkim * guest execution using its bound VCPU.
325208625Sjkim * @xmlonly
326208625Sjkim * <docref>For details on VCPUs and execution modes see <autoref label="sec:virt"/>.</docref>
327208625Sjkim * @endxmlonly
328208625Sjkim *
329208625Sjkim * Invoking `seL4_VMEnter` is similar to replying to a fault in that updates to the registers
330208625Sjkim * can be given in the message, but unlike a fault no message info
331208625Sjkim * @xmlonly
332208625Sjkim * <docref>(see <autoref label="sec:messageinfo"/>)</docref>
333208625Sjkim * @endxmlonly
334208625Sjkim * is sent as the registers are not optional and the number that must be sent is fixed.
335208625Sjkim * The mapping of hardware register to message register is
336208625Sjkim *      - `SEL4_VMENTER_CALL_EIP_MR` Address to start executing instructions at in the guest mode
337208625Sjkim *      - `SEL4_VMENTER_CALL_CONTROL_PPC_MR` New value for the Primary Processor Based VM Execution Controls
338208625Sjkim *      - `SEL4_VMENTER_CALL_CONTROL_ENTRY_MR` New value for the VM Entry Controls
339208625Sjkim *
340208625Sjkim * On return these same three message registers will be filled with the values at the point
341208625Sjkim * that the privlidged mode ceased executing. If this function returns with `SEL4_VMENTER_RESULT_FAULT`
342208625Sjkim * then the following additional message registers will be filled out
343208625Sjkim *      - `SEL4_VMENTER_FAULT_REASON_MR`
344208625Sjkim *      - `SEL4_VMENTER_FAULT_QUALIFICATION_MR`
345208625Sjkim *      - `SEL4_VMENTER_FAULT_INSTRUCTION_LEN_MR`
346208625Sjkim *      - `SEL4_VMENTER_FAULT_GUEST_PHYSICAL_MR`
347208625Sjkim *      - `SEL4_VMENTER_FAULT_RFLAGS_MR`
348208625Sjkim *      - `SEL4_VMENTER_FAULT_GUEST_INT_MR`
349208625Sjkim *      - `SEL4_VMENTER_FAULT_CR3_MR`
350228110Sjkim *      - `SEL4_VMENTER_FAULT_EAX`
351208625Sjkim *      - `SEL4_VMENTER_FAULT_EBX`
352228110Sjkim *      - `SEL4_VMENTER_FAULT_ECX`
353250838Sjkim *      - `SEL4_VMENTER_FAULT_EDX`
354208625Sjkim *      - `SEL4_VMENTER_FAULT_ESI`
355208625Sjkim *      - `SEL4_VMENTER_FAULT_EDI`
356208625Sjkim *      - `SEL4_VMENTER_FAULT_EBP`
357208625Sjkim *
358208625Sjkim * @param[out] sender The address to write sender information to.
359208625Sjkim *               If the syscall returns due to receiving a notification
360208625Sjkim *               on the bound notification then the sender information
361208625Sjkim *               is the badge of the notification capability that was invoked.
362250838Sjkim *               This parameter is ignored if `NULL`.
363208625Sjkim * @return `SEL4_VMENTER_RESULT_NOTIF` if a notification was received or `SEL4_VMENTER_RESULT_FAULT`
364208625Sjkim *  if the guest mode execution faulted for any reason
365208625Sjkim */
366208625SjkimLIBSEL4_INLINE_FUNC seL4_Word
367281687SjkimseL4_VMEnter(seL4_Word *sender);
368218590Sjkim#endif
369252279Sjkim
370208625Sjkim/** @} */
371219707Sjkim#endif
372209734Sjkim
373250838Sjkim/** @} */
374208625Sjkim
375208625Sjkim#ifdef CONFIG_SET_TLS_BASE_SELF
376208625Sjkim/**
377208625Sjkim * @xmlonly <manual name="SetTLSBase" label="sel4_settlsbase"/> @endxmlonly
378208625Sjkim * @brief Set the TLS base address and register of the currently executing thread.
379284460Sjkim *
380250838Sjkim * This stores the base address of the TLS region in the register
381208625Sjkim * reserved for that purpose on the given platform.
382208625Sjkim *
383208625Sjkim * Each platform has a specific register reserved for tracking the
384217365Sjkim * base address of the TLS region (as sepcified in the ELF standard) in
385250838Sjkim * a manner compatible with the TLS method used with that architecture.
386217365Sjkim *
387217365Sjkim * @param tls_base The new base address to store in the register.
388217365Sjkim */
389217365SjkimLIBSEL4_INLINE_FUNC void
390250838SjkimseL4_SetTLSBase(seL4_Word tls_base);
391217365Sjkim#endif
392217365Sjkim
393217365Sjkim