\chapter{Supervisor Binary Interface (SBI)} This chapter is a placeholder to describe the form of the SBIs we're envisioning for the RISC-V supervisor. The SBI captures the instructions that can be executed together with a set of SBI calls out to the supervisor execution environment (SEE) on a given platform. Several features that might normally handled by the supervisor operating system (OS) directly are handled via SBI calls to the SEE in RISC-V, including: \begin{itemize} \item Reset is handled by the SEE and once the machine is set up, the OS kernel is mapped into virtual memory, and its entry point is called. \item Machine-check errors and other non-maskable interrupts are handled by the SEE before vectoring into the OS if recovery is possible. \item Some device drivers may be handled by the SEE, and managed via virtual device calls over the SBI. \item The presence and version of supported instruction-set extensions is obtained via an SBI call to return the configuration string rather than a machine register. This allows for an arbitrarily large definition of instruction set extensions, and simplifies virtualization where the returned machine configuration might be modified to emulate different architectures on a given hardware platform. \end{itemize} The SBI employs the same calling convention as the ABI specified in Volume I of this manual. SBI entry points are located in the uppermost \wunits{2}{KiB} of the virtual address space, so that they may be invoked with a single {\tt jalr} instruction with {\tt x0} as the base register. Table~\ref{sbicalls} gives a preliminary list of SBI calls. \begin{table*}[h!] \begin{center} \begin{tabular}{| >{\ttfamily\catcode`_=12}l|p{8cm}|} \hline const char* sbi_get_config(void); & \parbox{8cm}{Get pointer to configuration string.}\\ \hline size_t sbi_hart_id(void); & \parbox{8cm}{Get ID of current hart, in range \\ {\tt [0, number\_harts - 1 ]}.} \\ \hline int sbi_send_ipi(size_t hart_id); & Send an interprocessor interrupt; returns 0 on success or -1 if hart ID is invalid. \\ \hline bool sbi_clear_ipi(void); & Clear local interprocessor interrupt. Returns 1 if an IPI was pending, else 0. \\ \hline void sbi_shutdown(void); & Terminate this supervisor-mode process. \\ \hline int sbi_console_putchar(uint8_t ch); & Write byte to debug console (blocking); returns 0 on success, else -1. \\ \hline int sbi_console_getchar(void); & Read byte from debug console; returns the byte on success, or -1 for failure. \\ \hline & \multirow{4}{*}{\parbox{8cm}{Instruct other harts to execute SFENCE.VMA. {\tt harts} points to a bitmask of remote hart IDs; NULL indicates all harts. {\tt asid} holds the address-space ID; 0 indicates all address spaces.}} \\ void sbi_remote_sfence_vm( & \\ \ \ const uintptr_t* harts, size_t asid); & \\ & \\ \hline void sbi_remote_sfence_vm_range( & \multirow{3}{*}{\parbox{8cm}{Like {\tt sbi\_remote\_sfence\_vm}, but only orders updates to leaf page tables mapping the range {\tt [start, start+size-1]}.}} \\ \ \ const uintptr_t* harts, size_t asid, & \\ \ \ uintptr_t start, uintptr_t size); & \\ \hline void sbi_remote_fence_i( & \multirow{2}{*}{\parbox{8cm}{Instruct remote harts to execute FENCE.I. {\tt harts} is as with {\tt sbi\_remote\_sfence\_vm}.}} \\ \ \ const uintptr_t* harts); & \\ \hline int sbi_mask_interrupt(int which); & Disable a PLIC interrupt line. Returns 0 if previously disabled, 1 if previously enabled, or -1 if {\tt which} is invalid. \\ \hline int sbi_unmask_interrupt(int which); & Enable a PLIC interrupt line. Return value is as with {\tt sbi\_mask\_interrupt}. \\ \hline \end{tabular} \end{center} \caption{SBI calls.} \label{sbicalls} \end{table*}