\documentclass[11pt]{article}
\usepackage[margin=2cm]{geometry}
\geometry{a4paper}
\usepackage{graphicx}
\usepackage{amssymb}
\usepackage{epstopdf}
\usepackage{bytefield}
\usepackage[table,xcdraw]{xcolor}
\usepackage{amsmath}
\usepackage{hyperref}


% facilitates the creation of memory maps. Start address at the bottom, end address at the top.
% syntax: \memsection{end address}{start address}{height in lines}{text in box}
\newcommand{\memsection}[4]{
\bytefieldsetup{bitheight=#3\baselineskip}    % define the height of the memsection
\bitbox[]{10}{
\texttt{#1}     % print end address
\\ \vspace{#3\baselineskip} \vspace{-2\baselineskip} \vspace{-#3pt} % do some spacing
\texttt{#2} % print start address
}
\bitbox{32}{#4} % print box with caption
}


\DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `dirname #1`/`basename #1 .tif`.png}

\title{Syscalls}

\begin{document}

This document describes the syscalls exported by the kernel. Each syscall is identified by an integer number, that serves as its index in the kernel syscall table.

\tableofcontents
\newpage

%%%%%%%%%%%%%%%
\section{Calling Conventions}
Each architecture may define a different calling convention for syscalls. A commonality between all architectures, however, is the fact that system calls may receive up to six arguments. Not all arguments may be used for all system calls. Additionally, each system call can return an integer value, the width of which is at least equal to the machine's native width.

\subsection{x86 (32-bit)}
For kernel entry, the IA32 specific \texttt{SYSENTER} instruction should be used; specifically, the kernel syscall trampoline, mapped into all processes, should be used to perform the syscall. It performs some special handling to ensure the stack pointer can be restored as required (it copies the stack pointer to restore to the \texttt{\%esi} register, which the kernel will in turn restore that register to \texttt{\%ecx} before exiting from the syscall with \texttt{SYSEXIT}.

The syscall number is placed in \texttt{\%ax}; the high 16 bits of the \texttt{\%eax} register are unused and may be interpreted by the syscall as a 16-bit set of flags. Following the syscall number, a maximum of four 32-bit arguments may be passed in the \texttt{\%ebx}, \texttt{\%ecx}, \texttt{\%edx} and \texttt{\%edi} registers. The call's result is placed in \texttt{\%eax}.

The entire memory range of \texttt{0xBF5F0000} to \texttt{0xBF5FFFFF}, inclusive is reserved for syscall data in all processes. The division of its address space is roughly as follows:
\\ \\
\begin{bytefield}{1}	
	\memsection{bf5f ffff}{bf5f e000}{4}{System information} \\
	\memsection{bf5f dfff}{bf5f d000}{2}{Time-of-day (clock) information} \\
	\memsection{bf5f dfff}{bf5f 2000}{4}{-- reseved --} \\
	\memsection{bf5f 1fff}{bf5f 0000}{2}{System call \texttt{SYSENTER} stub}
\end{bytefield}

\subsection{\textsc{amd64} (x86 64-bit)}
The \texttt{SYSCALL} instruction should be used inline to make a kernel call. Up to six arguments may be passed to the system call, in registers \texttt{\%rdi, \%rsi, \%rdx, \%r10, \%r8, \%r9}, in that order. This is similar to the standard System V ABI that is used for function calls on the system -- with the exception that the fourth argument goes in \texttt{\%r10} rather than \texttt{\%rcx}, which is clobbered by \texttt{SYSCALL}) allowing for minimum overhead. The system call number should be placed in \texttt{\%rax}.

On return from the system call, \texttt{\%rax} contains the system call specific return value.

%%%%%%%%%%%%%%%
\section{Handles}
Handles are opaque userspace identifiers for kernel objects. They take the form of positive integers, and are globally valid across the system. Any time a userspace process wishes to interact with a kernel object, it does so by using handles.

Userspace processes \textit{should not} under any circumstances attempt to decode or otherwise reason about the contents of a handle; the only exception to this rule is to determine whether a syscall return value could be a handle, by checking its sign bit. Valid handles are always positive, non-zero values.

\subsection{32-bit Handles}
On 32-bit platforms, we're a little starved for space to encode all the information we need to:

\begin{bytefield}[bitheight=\widthof{~Sign~},bitwidth=1.3em]{32} \\
\bitheader[endianness=big]{0,19,20,26,27,30,31} \\
\bitbox{1}{\rotatebox{90}{Sign}}
\bitbox{4}{Type}
\bitbox{7}{Epoch}
\bitbox{20}{Object Table Index}
\end{bytefield}

Encoded in each handle is an "object type," which identifies in which table the actual object can be found, as well as what its type is. Valid object types are:

\begin{itemize}
\item \texttt{0x01}: Task
\item \texttt{0x02}: Thread
\item \texttt{0x03}: Port
\item \texttt{0x04}: Virtual memory region
\end{itemize}

The epoch value is a monotonically increasing value; it starts off at zero the first time a handle is assigned, and is decremented every time a given handle index (for that particular object type) is re-assigned. This allows the kernel to detect stale handles.

\subsection{64-bit Handles}
Type values are identical to the 32-bit counterparts. Fields are simply extended to take up the whole 64 bit width:

\begin{bytefield}[bitheight=\widthof{~Sign~},bitwidth=0.67em]{64} \\
\bitheader[endianness=big]{0,31,32,51,52,55,56,62,63} \\
\bitbox{1}{\rotatebox{90}{Sign}}
\bitbox{7}{Reserved}
\bitbox{4}{Type}
\bitbox{20}{Epoch}
\bitbox{32}{Object Table Index}
\end{bytefield}

It's guaranteed that the sign bit is always clear, and that at least one reserved bit continues to be zero so attempting to dereference a handle as a pointer will take a non-cannonical address fault on at least \textsc{amd64}.

%%%%%%%%%%%%%%%
\section{Syscalls}
This section lists all syscalls by their numerical identifier, as well as any arguments that they take. If arguments are specified, they should be assigned to successive parameter slots: i.e. a syscall with two arguments will use the first two registers identified by the calling convention.

%%%%%%%%%%
\subsection{Common Conventions}
All system calls return status information; this takes the form of a status code. A value of 0 indicates success, whereas negative values indicate some sort of system error; positive values are reserved for the system call. Some calls deviate from this specification; they are specifically marked as such.

Some calls may accept a timeout parameter; all timeouts to the kernel are specified in full, integer microseconds ($\mu s$,) while a value of 0 means no timeout (i.e. return immediately if not ready) while the maximum value of the parameter type ($2^{32}-1$ or $2^{64}-1$ for 32- and 64-bit two's complements platforms) indicates an infinite timeout (i.e. to block forever waiting for the call to complete.)

There are a few syscalls that may take more than the four arguments allowed to be passed quickly; in these cases, the syscall will take a single argument, which is the address of a syscall-specific information structure. In this document, these are shown as they would be on a 32-bit platform; for 64-bit, all fields are extended to 64-bit, unless stated otherwise.



%%%%%%%%%%
\subsection{IPC}
%%%%%
\subsubsection{{\tt 0x00}: Receive message}
\textbf{Arguments:} (4) Port handle, received message structure, receive struct length, timeout \\
\textbf{Flags:} None \\
\textbf{Returns:} Number of message bytes read, or a negative error code \\

Blocks the calling thread, and waits for a message to be received on the specified port. The message contents (and some additional metadata, such as its origin and actual length) are written into the specified structure by the kernel.

The parameter of receive struct length serves as an upper bound on the number of message bytes that may be written, after subtracting the space consumed by the fixed message struct header fields.

The received message struct has the following format:

\begin{bytefield}[bitwidth=1.3em]{32} \\
\bitheader[endianness=big]{0,15,16,31} \\
\bitbox{32}{Sender thread handle} \\
\bitbox{16}{Flags} & \bitbox{16}{Message length (bytes)} \\
\bitbox{32}{\it Reserved} \\
\bitbox{32}{\it Reserved} \\
\wordbox[lrt]{1}{Message payload} \\
\skippedwords
\end{bytefield}

Message structures should be aligned on a 16-byte boundary.

%%%%%
\subsubsection{{\tt 0x01}: Send message}
\textbf{Arguments:} (3) Port handle, message data, message length \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 on success, or a negative error code \\

Sends a message to the given port. The kernel automatically provides the receiver with information on the origin of the message (i.e. our thread/task handles.) Message data must be aligned to a 16-byte boundary.

The call returns immediately once the message has been queued into the port's message buffer. If the message buffer is full, this call will fail immediately.

%%%%%
\subsubsection{{\tt 0x02}: Set port parameters}
\textbf{Arguments:} (2) Port handle, queue depth \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 on success, or a negative error code \\

Sets the maximum number of messages that may be pending on a port at a given time, or its queue depth. The value \texttt{0} indicates that the caller desires no limit: the kernel may reject messages to ports with no limit if it cannot allocate memory for the message, for example.

If the queue is currently larger than the new limit, no messages are discarded, but attempts to send further messages will fail.

%%%%%
\subsubsection{{\tt 0x03}: Allocate Port}
\textbf{Arguments:} None \\
\textbf{Flags:} None \\
\textbf{Returns:} Port handle ($>0$) or error code ($\leq0$) \\

Creates a new port that an application can use to receive messages on.

%%%%%
\subsubsection{{\tt 0x04}: Deallocate Port}
\textbf{Arguments:} (1) Port handle \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 or error code \\

Deallocates all resources associated with a previously created port. The task making this call must have been the same task that originally created the port.

Any threads that are blocking waiting to send to the port will be woken up.

%%%%%
\subsubsection{{\tt 0x05}: Share VM region}
\textbf{Arguments:} (2) Destination task handle, VM object handle \\
\textbf{Flags:} See below \\
\textbf{Returns:} 0 on success, or a negative error code \\

Shares a virtual memory object with another task. The underlying memory is reference counted; it will be deallocated only when \textit{all} tasks that have it mapped have exited and their VM has been destroyed. However, you should always unshare VM regions if they're no longer needed. If this call fails, the caller retains ownership of the VM region.

This can be used to implement shared memory between tasks.

Flags are as follows:

\begin{itemize}
\item \texttt{1 << 0}: Map VM object temporarily. This will cause the object to be removed from the destination task's address space when the task that created the VM object is terminated; this in contrast to the default behavior described above. (In other words, the VM region's reference count is not incremented, nor decremented when the destination task exits.)
\item \texttt{1 << 1}: Map the object as "copy-on-write" in the destination task. When the task attempts to write to the memory region, its contents are copied to a new virtual memory region.
\item \texttt{1 << 2}: Allows the destination task to write directly to the virtual memory object. (This flag is mutually exclusive with the "copy-on-write" flag.)
\item \texttt{1 << 14}: Transfer ownership of the VM object to the receiving task. It will be unmapped from the caller during the system call. The protection features of the region will be maintained.
\item \texttt{1 << 15}: If ownership of the mapping is transferred, require that it's mapped into the recipient task at the same virtual address. If this cannot be satisfied, the call fails.
\end{itemize}

%%%%%
\subsubsection{{\tt 0x08}: Wait for notification}
\textbf{Arguments:} (2) Notification mask, timeout \\
\textbf{Flags:} None \\
\textbf{Returns:} Received notifications, or 0 in case of error \\

Blocks the calling thread, and waits for one or more of its notification bits to be set. The thread will unblock (and this call return) only if the bitwise \texttt{AND} of the thread's current notification value and the provided mask is non-zero; or the timeout value expires.

Upon return from this function in the non-timeout case, the thread's notification mask is returned, and all notification bits included in the specified mask are cleared. The returned notification value may have bits set that were not set in the provided mask; this is intended behavior, and should be dealt with gracefully by callers.

%%%%%
\subsubsection{{\tt 0x09}: Notify thread}
\textbf{Arguments:} (2) Thread handle, notification to send \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 on success, or negative error code \\

Sets the provided notification bits on the specified thread. The thread may be woken up if it is blocking on these notification bits. Bits that are cleared in the provided notification value are left as-is in the thread's notification value.



%%%%%%%%%%
\newpage
\subsection{Virtual Memory}
%%%%%
\subsubsection{{\tt 0x10}: Create VM region}
\textbf{Arguments:} (3) Physical base address, size, flags  \\
\textbf{Returns:} VM object handle ($>0$) or error code ($\leq0$) \\

Allocates a virtual memory region backed by physical memory, starting with the given address, and incrementing linearly for the requested allocation size. It is not yet mapped in any process address space.

This call will fail if the length and base address are not a multiple of the platform-specific minimum page size.

The VM object will be owned by the calling task. Ownership can be transferred when the object is mapped into another task.

\paragraph{Flags}
\begin{itemize}
\item \texttt{1 << 1}: Use large pages, if supported, to satisfy this virtual memory mapping. The kernel will attempt to map as much of the physical memory region as possible with large pages, and use regular pages to map the remainder.
\item \texttt{1 << 10}: Allow read access to the memory region.
\item \texttt{1 << 11}: Allow write access to the memory region.
\item \texttt{1 << 12}: Allow code execution from the memory region. (This flag may not be supported on all architectures; on those that do not support it, all virtual maps are executable, so you should pass this flag to ensure your code works correctly where the flag is considered.)
\item \texttt{1 << 13}: Maps the region as MMIO, i.e. disabling all forms of caching in the processor.
\item \texttt{1 << 14}: Enables write-through caching, if supported; this can be useful for things such as framebuffers. (This can be used to reduce the performance impact of the MMIO flag for writes, if strongly ordered writes are not required.)
\end{itemize}

%%%%%
\subsubsection{{\tt 0x11}: Create anonymous VM region}
\textbf{Arguments:} (2) Allocation size, flags  \\
\textbf{Returns:} VM object handle ($>0$) or error code ($\leq0$) \\

Allocates a virtual memory region backed by anonymous memory. Allocation size must be a multiple of the platform-specific minimum page size, or the call will fail; the platform is free to use pages larger than this, if supported, to satisfy the allocation.

The VM object will be owned by the calling task. Ownership can be transferred when the object is mapped into another task.

\paragraph{Flags}
\begin{itemize}
\item \texttt{1 << 0}: Force all memory to be allocated at the time the call returns; if the system has insufficient virtual memory space to satisfy the allocation, the call fails.
\item \texttt{1 << 10}: Allow read access to the memory region.
\item \texttt{1 << 11}: Allow write access to the memory region.
\item \texttt{1 << 12}: Allow code execution from the memory region. (This flag may not be supported on all architectures; on those that do not support it, all virtual maps are executable, so you should pass this flag to ensure your code works correctly where the flag is considered.)
\end{itemize}

%%%%%
\subsubsection{{\tt 0x12}: Deallocate VM region}
\textbf{Arguments:} (1) VM object handle  \\
\textbf{Returns:} Success ($0$) or error code ($\leq0$) \\

Deallocates a virtual memory region. The specified region will be removed from the calling task's virtual address space (if it's mapped,) and then removed from the task's list of owned VM regions, if it is the owner.

This means it's safe to make this call against a region that's shared with other tasks. Since each mapping of the region holds a reference to it, it will only be completely deallocated once all tasks have unmapped it, even if the owner invoked this method. (The region becomes orphaned at this point; but it will still be correctly deallocated later when it's completely unmapped.)

%%%%%
\subsubsection{{\tt 0x13}: Update VM region flags}
\textbf{Arguments:} (2) VM object handle, flags \\
\textbf{Returns:} 0 on success, or negative error code \\

Changes the access permissions and specifiers of the specified virtual memory region.

\textit{Note:} Only the task that created a VM object can change its permissions. (More concretely, this means you cannot adjust the permissions of a shared memory object you received from another task.)

\paragraph{Flags}
\begin{itemize}
\item \texttt{1 << 10}: Allow read access to the memory region.
\item \texttt{1 << 11}: Allow write access to the memory region.
\item \texttt{1 << 12}: Allow code execution from the memory region.
\item \texttt{1 << 13}: Maps the region as MMIO, i.e. disabling all forms of caching in the processor.
\item \texttt{1 << 14}: Enables write-through caching, if supported; this can be useful for things such as framebuffers. (This can be used to reduce the performance impact of the MMIO flag for writes, if strongly ordered writes are not required.)
\end{itemize}

%%%%%
\subsubsection{{\tt 0x14}: Resize VM region}
\textbf{Arguments:} (3) VM object handle, new size (in bytes), flags \\
\textbf{Returns:} 0 on success, or negative error code \\

Resizes a previously allocated virtual memory region. The new size may be larger or smaller than the current size, but it must be a multiple of the platform's page size. Only the task that created a VM object can resize it.

When a VM region is resized, none of the mappings in tasks are updated as a result. So, if the region shrank, accesses beyond its new ending address will cause a page fault. If it grows, tasks will not be able to access any additional pages beyond its old length until their map is updated.

\textit{Note:} The calling task must be the owner of the VM object.

\paragraph{Flags}
\begin{itemize}
\item \texttt{1 << 0}: If the object represents an anonymous mapping, and the resize operation requires the allocation of additional physical memory, force that memory to be allocated eagerly. This call will fail if the system has insufficient physical memory available to satisfy the request.
\end{itemize}

%%%%%
\subsubsection{{\tt 0x15}: Map VM region at fixed address}
\textbf{Arguments:} (5) VM object handle, destination task handle, virtual base address, mapping length, flags \\
\textbf{Returns:} 0 on success, or negative error code \\

Maps the specified virtual memory object into the address space of the specified task, reserving a particular length region of virtual address space for it, if possible. A page aligned base address for the view must be specified.

The mapping length \textit{does not} have to be the same as the size of the VM region, though it often is. This allows creating "views" into a region in virtual address space, allowing the region to grow or shrink as necessary. This is particularly useful for shared memory, as it allows the region to grow over time without needing to modify memory maps of other tasks.

Specify a task handle of \texttt{0} to use the currently running task.

\paragraph{Flags}
If any flags are specified at all, they are interpreted as a mask to be applied against the map's flags. For example, this can be used to map a page read-only into another task. The supported flags are:

\begin{itemize}
\item \texttt{1 << 10}: Allow read access to the memory region.
\item \texttt{1 << 11}: Allow write access to the memory region.
\item \texttt{1 << 12}: Allow code execution from the memory region.
\item \texttt{1 << 24}: Transfer ownership of the VM region to the destination task (allowed only if calling task is current owner)
\end{itemize}

%%%%%
\subsubsection{{\tt 0x16}: Map VM region (advanced)}
\textbf{Arguments:} (4) VM object handle, destination task handle, info structure, info structure size \\
\textbf{Returns:} 0 on success, or negative error code \\

Creates a view into a particular virtual memory region in a task's virtual address space. Specify a task handle of \texttt{0} to use the currently running task.

The info structure is of the following format:

\begin{bytefield}[bitwidth=0.65em]{64} \\
\bitheader[endianness=big]{0,63} \\
\bitbox{64}{Desired VM address range start} \\
\bitbox{64}{Desired VM address range end} \\
\bitbox{64}{Mapping length (bytes)} \\
\bitbox{64}{Flags} \\
\end{bytefield}

The kernel will attempt to find a free region of address space in the given bounds to create a view into the specified VM object. If the base address of the mapping should be fixed, specify it as the search range start, and set the search range ending address to \texttt{0}.

If the mapping is successful, the kernel writes into the first field the actual base address at which the VM object was mapped.

\paragraph{Flags}
If any flags are specified, they are interpreted as a mask to be applied against the map's flags. For example, this can be used to map a page read-only into another task. The supported flags are:

\begin{itemize}
\item \texttt{1 << 10}: Allow read access to the memory region.
\item \texttt{1 << 11}: Allow write access to the memory region.
\item \texttt{1 << 12}: Allow code execution from the memory region.
\item \texttt{1 << 24}: Transfer ownership of the VM region to the destination task (allowed only if calling task is current owner)
\end{itemize}

%%%%%
\subsubsection{{\tt 0x17}: Unmap VM region}
\textbf{Arguments:} (2) VM object handle, destination task handle \\
\textbf{Returns:} 0 on success, or negative error code \\

Unmaps a previously mapped VM region from the specified task. If this is the last task that had this object mapped, it will be destroyed automatically.

Specify a task handle of \texttt{0} to use the currently running task.

%%%%%
\subsubsection{{\tt 0x18}: Get VM region info}
\textbf{Arguments:} (4) VM object handle, task handle, info buffer, info buffer length \\
\textbf{Returns:} 0 on success, or negative error code \\

Gets information about the specified VM region. If the task handle is not \texttt{0}, the info is provided from the perspective of that task; otherwise, the running task is used. The information is then written into a buffer with the specified location. The buffer contains a structure with the following fields:

\begin{bytefield}[bitwidth=0.65em]{64} \\
\bitheader[endianness=big]{0,63} \\
\bitbox{64}{Virtual base address} \\
\bitbox{64}{Length (bytes)} \\
\bitbox{64}{Flags} \\
\end{bytefield}

%%%%%
\subsubsection{{\tt 0x19}: Get task VM info}
\textbf{Arguments:} (3) Task handle, info buffer, info buffer length \\
\textbf{Returns:} 0 on success, or negative error code \\

Retrieves information on a task's virtual memory environment. If the task handle is specified as \texttt{0}, the current task's information is returned.

Information is placed into an info buffer with the following structure:

\begin{bytefield}[bitwidth=0.65em]{64} \\
\bitheader[endianness=big]{0,063} \\
\bitbox{64}{Pages owned} \\
\bitbox{64}{Number of VM mappings} \\
\end{bytefield}

%%%%%
\subsubsection{{\tt 0x1A}: Get handle for address}
\textbf{Arguments:} (2) Task handle, virtual address \\
\textbf{Flags:} None \\
\textbf{Returns:} VM region handle ($>0$) or error code ($\leq0$) \\

Searches the given task's virtual address space to determine if there is a mapping that contains the specified address. In essence, all mappings are checked to see if they contain the byte at the given address. This does not trigger page faults on not present pages.

We'll return either the handle of the region, a value of \texttt{0} to indicate that there is no mapping at the given address, or a negative error code.

%%%%%
\subsubsection{{\tt 0x1B}: Translate virtual to physical}
\textbf{Arguments:} (4) Task handle, input virtual address array, output physical address array, number of addresses \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 on success, or error code ($\leq0$) \\

Translates one or more virtual addresses to physical addresses, based on the memory map of the task identified by the given handle, or \texttt{0} for the calling task. If an address cannot be translated, the corresponding output slot is \textit{not} written by the kernel. This implies that callers should fill this array with some value they can use to identify the translation failed.

Possible reasons for translation of a virtual address to fail are that it does not fall within a region in the task's virtual address space, the particular page in a region hasn't been faulted in yet, or because the region is not locked in memory (marked for hardware use.)

%%%%%
\subsubsection{{\tt 0x1C}: Query memory parameters}
\textbf{Arguments:} (3) Parameter to query, output value pointer, size of output value \\
\textbf{Flags:} None \\
\textbf{Returns:} 0 on success, or error code ($\leq0$) \\

Retrieves information about the virtual (or physical) memory allocation system and copies it to the user provided buffer.

Supported parameters are:

\begin{table}[h]
\begin{tabular}{|r|l|l|}
\hline
\rowcolor[HTML]{EFEFEF}
\textbf{Value} & \textbf{Definition} & \textbf{Output Size} \\ \hline
0x01 & Gets the total number of available pages of physical memory. & \texttt{uint64\_t} \\ \hline
0x02 & Gets the number of allocated pages of physical memory. & \texttt{uint64\_t} \\ \hline
0x03 & Gets the number of reserved pages of physical memory. & \texttt{uint64\_t} \\ \hline
\end{tabular}
\end{table}


%%%%%%%%%%
\newpage
\subsection{Scheduler}
%%%%%
\subsubsection{{\tt 0x20}: Get current thread handle}
\textbf{Arguments:} None \\
\textbf{Returns:} Thread handle ($>0$) or error code ($\leq0$) \\

Retrieves a kernel handle representing the currently executing thread.

%%%%%
\subsubsection{{\tt 0x21}: Yield remaining time quantum}
\textbf{Arguments:} None \\
\textbf{Returns:} 0 on success or negative error code \\

Gives up the remainder of the thread's time quantum. It will remain on the ready queue.

%%%%%
\subsubsection{{\tt 0x22}: Sleep}
\textbf{Arguments:} (1) Sleep duration (in $\mu s$) \\
\textbf{Returns:} 0 on success or negative error code \\

Blocks the thread for the specified amount of time. The kernel makes no guarantee that the thread will sleep for the precise amount specified; it should instead be considered a hint the kernel will make a \textit{best effort} to satisfy. This means this call may return immediately without blocking the thread, before the duration specified has elapsed, or even at some point significantly thereafter.

%%%%%
\subsubsection{{\tt 0x23}: Create thread}
\textbf{Arguments:} (4) Thread entry point; entry point argument; initial stack pointer, flags \\
\textbf{Returns:} Thread handle ($>0$) or error code ($\leq0$) \\

Creates a new thread and attaches it to the running task. The caller must have set up a region of memory for the thread's stack. After the associated kernel thread has been initialized, the thread will execute a return to user mode with the given stack and program counter value. It will be invoked as if it were a function declared as \texttt{void ThreadEntry(const uintptr\_t param)}.

It is undefined behavior to return from the user thread entry routine. (Doing so will probably just crash the task; however, runtime libraries may wish to wrap thread entry points such that returning from threads will terminate them, or do something else more desirable.)

\begin{itemize}
\item \texttt{1 << 15}: The thread begins suspended; you need to resume it later.
\end{itemize}

%%%%%
\subsubsection{{\tt 0x24}: Join with thread}
\textbf{Arguments:} (2) Thread handle, timeout (in $\mu s$) \\
\textbf{Returns:} 0 on success, 1 on timeout, or negative error code \\

Waits for the specified thread to terminate, for up to the given amount of time.

%%%%%
\subsubsection{{\tt 0x25}: Destroy thread}
\textbf{Arguments:} (1) Thread handle \\
\textbf{Returns:} 0 on success or negative error code \\

Cleans up all resources associated with a thread. This call returns as soon as the request has been received; if you need to wait for the thread to actually be terminated, you need to wait on it.

\textbf{Note:} This call will affect the specified thread the next time it enters kernel mode; at the latest, this is at the next scheduler invocation. You should not use this call for anything other than destroying threads when you are no longer using them; it is \textit{not} a suitable replacement for proper inter-thread communication to signal an orderly shutdown.

%%%%%
\subsubsection{{\tt 0x26}: Set thread state}
\textbf{Arguments:} (2) Thread handle, new thread state \\
\textbf{Returns:} 0 on success or negative error code \\

Sets the state of the given thread; the thread state can be one of the following: \texttt{0} = paused, \texttt{1} = running. A running thread will transition to the paused state the next time it calls into the kernel.

%%%%%
\subsubsection{{\tt 0x27}: Set thread priority}
\textbf{Arguments:} (2) Thread handle, new priority value \\
\textbf{Returns:} 0 on success, or negative error code \\

Updates the thread's base priority value. Valid priority values are in $[-100, 100]$, where a priority of $0$ indicates the standard (normal) priority level.

%%%%%
\subsubsection{{\tt 0x28}: Set thread notification mask}
\textbf{Arguments:} (2) Thread handle, new notification mask \\
\textbf{Returns:} 0 on success, or negative error code \\

Updates the thread's notification mask. Any bits that are cleared in the mask will be ignored when the thread is waiting on notifications.

\textbf{Note:} The result of using this call on a thread that is currently blocked waiting on notifications is \textit{undefined.}

%%%%%
\subsubsection{{\tt 0x29}: Set thread name}
\textbf{Arguments:} (3) Thread handle, address of new name, length of new name (in bytes) \\
\textbf{Returns:} 0 on success, or negative error code \\

Updates the thread's name with the contents of the specified string buffer; if the buffer is zero terminated, the terminator is not included in the byte count. The thread name is used purely for informational purposes. 

%%%%%
\subsubsection{{\tt 0x2A}: Resume thread}
\textbf{Arguments:} (1) Thread handle \\
\textbf{Returns:} 0 on success, or negative error code \\

Resumes a thread that's currently paused. This can only be called on threads that are in the suspended state, i.e. those created with the \texttt{THREAD\_SUSPENDED} flag.

%%%%%%%%%%
\newpage
\subsection{Tasks}
%%%%%
\subsubsection{{\tt 0x30}: Get current task handle}
\textbf{Arguments:} None \\
\textbf{Returns:} Task handle ($>0$) or error code ($\leq0$) \\

Retrieves a kernel handle representing the currently executing task.

%%%%%
\subsubsection{{\tt 0x31}: Create task}
\textbf{Arguments:} (1) Parent task handle \\
\textbf{Returns:} Task handle ($>0$) or error code ($\leq0$) \\

Creates a new task with a single thread. The task's parent is set to either the task specified, or the current task if the task handle is zero. You should use the "initialize task" call to kick this main thread into user space once you have finished setting up the memory map of the task.

This creates the kernel structures for the task and all required virtual memory structures. The task's main thread (and corresponding kernel stack) are allocated as well, and perform the required kernel structure initialization, and will then block. To continue the thread, you should invoke the "initialize task" system call.

At this point, the task will have no memory mapped in userspace (with the exception of any read-only data mapped by the architecture/platform code.) It's the responsibility of the caller to build up the task's virtual memory space, load executable code, set up stacks, and so forth. This process is typically encapsulated by a runtime library.

%%%%%
\subsubsection{{\tt 0x32}: Terminate task}
\textbf{Arguments:} (2) Task handle, exit code \\
\textbf{Returns:} 0 on success, negative error code otherwise. \\

Terminates the task (and all threads within it) as identified by the given task handle. If the task handle is not specified (i.e. it is zero) the currently executing task will be terminated; the call will not return control back to the caller before the task is destroyed.

%%%%%
\subsubsection{{\tt 0x33}: Initialize task}
\textbf{Arguments:} (3) Task handle, entry point address, stack address \\
\textbf{Returns:} 0 on success, negative error code otherwise. \\

Sets up the task's main thread to return to userspace with the specified stack at the specified address. The addresses are virtual addresses in the task's memory map, not the caller's.

You can only make this call on a freshly created task handle. Attempts to execute it against already initialized tasks will fail.

%%%%%
\subsubsection{{\tt 0x34}: Set task name}
\textbf{Arguments:} (3) Task handle, address of new name, length of new name (in bytes) \\
\textbf{Returns:} 0 on success, or negative error code \\

Updates the task's name with the contents of the specified string buffer; if the buffer is zero terminated, the terminator is not included in the byte count. The task name is used purely for informational purposes.

%%%%%
\subsubsection{{\tt 0x35}: Wait on task}
\textbf{Arguments:} (2) Task handle, timeout \\
\textbf{Returns:} Task exit code ($\geq0$) or error code ($<0$) \\

Waits for the specified task to exit, up to the specified the timeout, then returns its exit code.



%%%%%%%%%%%%%%%
\newpage
\subsection{Interrupt Handling}

%%%%%
\subsubsection{{\tt 0x38}: Register IRQ handler}
\textbf{Arguments:} (3) IRQ number, thread handle, notification bits \\
\textbf{Returns:} Handle on success ($> 0$) or error code ($\leq0$) \\

Installs an interrupt handler for the given platform-specific interrupt. When the interrupt fires, the specified thread will have the requested notification bit(s) set. The interrupt is unmasked and enabled in any associated interrupt controllers when the first registration is added for it.

%%%%%
\subsubsection{{\tt 0x39}: Unregister IRQ handler}
\textbf{Arguments:} (1) IRQ handler token \\
\textbf{Returns:} 0 on success or error code ($\leq0$) \\

Removes a previously registered interrupt handler. If there are no other handlers for the interrupt this handler belongs to, it is masked and disabled in all relevant interrupt controllers. 

%%%%%
\subsubsection{{\tt 0x3A}: Update IRQ handler}
\textbf{Arguments:} (3) IRQ handler token, thread handle, notification bits \\
\textbf{Returns:} 0 on success or error code ($\leq0$) \\

Changes the thread that is notified, and the bits that are set, when the interrupt fires.

%%%%%
\subsubsection{{\tt 0x3B}: Get IRQ handler information}
\textbf{Arguments:} (2) IRQ handler token, information value \\
\textbf{Returns:} Info value ($\geq 0$) or error code ($< 0$) \\

Returns information about the interrupt handler, based on the second input argument. The following values of this argument are currently supported and will produce the defined output:

\begin{table}[h]
\begin{tabular}{|r|l|}
\hline
\rowcolor[HTML]{EFEFEF} 
\cellcolor[HTML]{EFEFEF}\textbf{Value} & \textbf{Definition} \\ \hline
0x01 & Gets the processor local interrupt vector number. \\ \hline
\end{tabular}
\end{table}

%%%%%
\subsubsection{{\tt 0x3C}: Allocate Processor Local IRQ handler}
\textbf{Arguments:} (2) Thread handle, notification bits \\
\textbf{Returns:} Handle on success ($> 0$) or error code ($\leq0$) \\

Creates an interrupt handler for a processor local interrupt. An implementation defined vector number is allocated to the interrupt, which may be used by the caller to program hardware. The specified thread will be locked to the processor core from which it was called as a result.

Use the \hyperlink{section.3.6.4}{get IRQ Handler information} call to retrieve the allocated vector number.



%%%%%%%%%%%%%%%
\newpage
\subsection{Miscellaneous}

%%%%%
\subsubsection{{\tt 0x40}: Get kernel entropy}
\textbf{Arguments:} (2) Output buffer pointer, number of bytes to get \\
\textbf{Returns:} Total number of bytes of entropy copied on success, or error code ($\leq0$) \\

Copies up to the requested number of bytes out of the kernel's randomness buffer. The kernel is not required to satisfy the complete request; this could happen if the random pool is exhausted, for example. Therefore, the call returns the actual number of bytes copied into the output buffer.



%%%%%%%%%%%%%%%
\newpage
\section{Architecture Specific Calls}
Architecture code may expose its own system calls to userspace applications, for tasks such as interrupt routing or other per-task configuration. Note that the kernel does not do any permissions checks; you are responsible for doing these.

%%%%%%%%%%
\subsection{x86}
%%%%%
\subsubsection{{\tt 0x48}: Set IO permission bitmap}
\textbf{Arguments:} (3) Task handle, IO bitmap buffer, IO bitmap offset/length \\
\textbf{Returns:} 0 on success, or a negative error code \\

Configures the IO permission bitmap for the given task (or current task if \texttt{0} is specified,) filling it such that all ports whose bits are \textit{set} in the map can be accessed by the task.

The offset/length field is formatted as follows:

\begin{bytefield}[bitwidth=1.3em]{32} \\
\bitheader[endianness=big]{0,15,16,31} \\
\bitbox{16}{Length} & \bitbox{16}{Offset} \\
\end{bytefield}

Its length is specified as a number of ports (i.e. bits) but it will always be read in full byte increments. Offset is likewise specified in bits.

If the task does not already have a TSS associated with it, this will allocate one. This TSS has the full 8K (plus one byte) allocated to map all 64K IO ports on the platform. This is a little wasteful, but avoids several common bugs resulting from partial TSS IO permission bitmaps.

%%%%%
\subsubsection{{\tt 0x49}: Set thread-local base}
\textbf{Arguments:} (2) Thread handle, Thread-local base address \\
\textbf{Returns:} 0 on success, or a negative error code \\

Sets the thread-local base to the given address. This updates the value of \texttt{\%gs} that's updated every time the thread is switched in. The initial value of the register is 0.

%%%%%%%%%%
\subsection{amd64}

%%%%%
\subsubsection{{\tt 0x48}: Set thread-local base}
\textbf{Arguments:} (3) Thread handle, Base register index, Thread-local base address \\
\textbf{Returns:} 0 on success, or a negative error code \\

Sets the thread-local base to the given address. This updates the value of \texttt{\%gs} or \texttt{\%fs} that's updated every time the thread is switched in. The initial value of both registers is 0.

An index of $1$ writes to \texttt{\%gs}, and $0$ to \texttt{\%fs}.

%%%%%
\subsubsection{{\tt 0x49}: Get bootloader info struct}
\textbf{Arguments:} (2) Output buffer address, output buffer size \\
\textbf{Returns:} Positive number of bytes copied on success, or a negative error code \\

Copies the information structure provided by the bootloader (if any) into the provided userspace buffer. On all current amd64 implementations, this is the \href{https://gitlab.com/bztsrc/bootboot/}{BOOTBOOT} loader.

%%%%%
\subsubsection{{\tt 0x4A}: Update port access list}
\textbf{Arguments:} (4) Task handle, bitmap pointer, number of bits, port offset \\
\textbf{Returns:} 0, or a negative error code \\

Updates the task's IO permission bitmap to allow access to the ports referenced by the given bitmap; each bit represents one port. The provided offset is added to each bit's index in the bitmap to produce the final bit number.

%%%%%
\subsubsection{{\tt 0x4B}: Lock port access list}
\textbf{Arguments:} (1) Task handle \\
\textbf{Returns:} 0, or a negative error code \\

Locks the IO permission bitmap of the specified task (0 meaning the calling task,) ensuring no further changes can be made to it.

%%%%%
\subsubsection{{\tt 0x4C}: Perform IO port read}
\textbf{Arguments:} (3) IO port number, flags, output pointer \\
\textbf{Returns:} 0, or a negative error code \\

Performs an IO port read from the given port. The result is placed in the provided buffer, which is assumed to be at least of size \texttt{uint32\_t}, which is the maximum IO size.

The flags field is used to specify the size of the IO operation. The following values are supported:
\begin{itemize}
\item \texttt{0x01}: Byte access
\item \texttt{0x02}: Word access
\item \texttt{0x03}: DWord access
\end{itemize}

%%%%%
\subsubsection{{\tt 0x4D}: Perform IO port write}
\textbf{Arguments:} (3) IO port number, flags, value to write \\
\textbf{Returns:} 0, or a negative error code \\

Performs an IO port write to the given port. The flags field is used to specify the size of the IO operation, using the same meaning as for IO port reads.

%%%%%
\subsubsection{{\tt 0x4E}: Set kernel graphical console state}
\textbf{Arguments:} (1) Enable state of kernel console \\
\textbf{Returns:} 0, or a negative error code \\

Enables or disables the kernel's built in graphical framebuffer console, if it's supported. This should be used when graphics drivers are being initialized to prevent access conflicts between the kernel and the userspace drivers.

\end{document}  