Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
4 contributors

Users who have contributed to this file

@palmer-dabbelt @atishp04 @mickflemm @fintelia
353 lines (282 sloc) 12.3 KB

RISC-V Supervisor Binary Interface Specification

This RISC-V SBI specification is

© 2019 Palmer Dabbelt <palmer@sifive.com>
© 2019 Atish Patra <atish.patra@wdc.com>

It is licensed under the Creative Commons Attribution 4.0 International License (CC-BY 4.0). The full license text is available at https://creativecommons.org/licenses/by/4.0/.

Introduction

This specification describes the RISC-V Supervisor Binary Interface, known from here on as SBI. This interface allows supervisor-mode software to be written that is portable to all RISC-V implementations. The design of the SBI follows the general RISC-V philosophy of having a small core along with a set of optional modular extensions.

Versioning and History

This document describes a draft of version 0.2 of the RISC-V SBI specification.

Changes Since Version 0.1

  • The entire v0.1 SBI has been moved to the legacy extension, which is now an optional extension. This is technically a backwards-incompatible change because the legacy extension is optional and v0.1 of the SBI doesn’t allow probing, but it’s as good as we can do.

Binary Encoding

All SBI functions share a single binary encoding, which facilitates the mixing of SBI extensions. This binary encoding matches the standard RISC-V UNIX syscall ABI, which itself is based on the calling convention defined in the RISC-V ELF psABI. In other words, SBI calls are exactly the same as standard RISC-V function calls except that:

  • An ecall is used as the control transfer instruction instead of a call instruction.

  • a7 (or t0 on RV32E-based systems) encodes the SBI extension ID, which matches how the system call ID is encoded in the standard UNIX system call ABI.

Many SBI extensions also chose to encode an additional function ID in a6, a scheme similar to the ioctl() system call on many UNIX operating systems. This allows SBI extensions to encode multiple functions within the space of a single extension.

In the name of compatibility, SBI extension IDs and SBI function IDs are encoded as signed 32-bit integers. When passed in registers these follow the standard RISC-V calling convention rules.

SBI functions must return a pair of values in a0 and a1, with a0 returning an error code. This is analogous to returning the C structure

    struct sbiret {
        long error;
        long value;
    };

Standard SBI error codes are listed below

Error Type Value

SBI_SUCCESS

0

SBI_ERR_FAILED

-1

SBI_ERR_NOT_SUPPORTED

-2

SBI_ERR_INVALID_PARAM

-3

SBI_ERR_DENIED

-4

SBI_ERR_INVALID_ADDRESS

-5

SBI_ERR_ALREADY_AVAILABLE

-6

SBI Base Functionality, Extension ID 0x10

The base of the supervisor binary interface is designed to be as small as possible. As such, it only contains functionality for probing which SBI extensions are available and for querying the version of the SBI. All functions in the base must be supported by all SBI implementations, so there are no error returns defined.

struct sbiret sbi_get_spec_version(void);

Returns the current SBI specification version. This function must always succeed. The minor number of the SBI specification is encoded in the low 24 bits, with the major number encoded in the next 7 bits. Bit 32 must be 0 and is reserved for future expansion.

struct sbiret sbi_get_impl_id(void);

Returns the current SBI implementation ID, which is different for every SBI implementation. It is intended that this implementation ID allows software to probe for SBI implementation quirks.

struct sbiret sbi_get_impl_version(void);

Returns the current SBI implementation version. The encoding of this version number is specific to the SBI implementation.

struct sbiret sbi_probe_extension(long extension_id);

Returns 0 if the given extension ID is not available, or an extension-specific non-zero value if it is available.

struct sbiret sbi_get_mvendorid(void);
struct sbiret sbi_get_marchid(void);
struct sbiret sbi_get_mimpid(void);

Return a value that is legal for the corresponding CSR. 0 is always a legal value for any of these CSRs.

Function Listing

Function Name Function ID Extension ID

sbi_get_sbi_spec_version

0

0x10

sbi_get_sbi_impl_id

1

0x10

sbi_get_sbi_impl_version

2

0x10

sbi_probe_extension

3

0x10

sbi_get_mvendorid

4

0x10

sbi_get_marchid

5

0x10

sbi_get_mimpid

6

0x10

SBI Implementation IDs

Implementation ID Name

0

Berkeley Boot Loader (BBL)

1

OpenSBI

Legacy SBI Extension, Extension IDs 0x00 through 0x0F

The legacy SBI ignores the function ID field, instead being encoded as multiple extension IDs. Each of these extension IDs must be probed for directly. This extension is deprecated in favor of the following extensions:

void sbi_set_timer(uint64_t stime_value)

Programs the clock for next event after stime_value time. This function also clears the pending timer interrupt bit.

If the supervisor wishes to clear the timer interrupt without scheduling the next timer event, it can either request a timer interrupt infinitely far into the future (i.e., (uint64_t)-1), or it can instead mask the timer interrupt by clearing sie.STIE.

void sbi_send_ipi(const unsigned long *hart_mask)

Send an inter-processor interrupt to all the harts defined in hart_mask. Interprocessor interrupts manifest at the receiving harts as Supervisor Software Interrupts.

hart_mask is a virtual address that points to a bit-vector of harts. The bit vector is represented as a sequence of unsigned longs whose length equals the number of harts in the system divided by the number of bits in an unsigned long, rounded up to the next integer.

void sbi_clear_ipi(void)

Clears the pending IPIs if any. The IPI is cleared only in the hart for which this SBI call is invoked.

void sbi_remote_fence_i(const unsigned long *hart_mask)

Instructs remote harts to execute FENCE.I instruction. N.B. hart_mask is as described in sbi_send_ipi.

void sbi_remote_sfence_vma(const unsigned long *hart_mask,
                           unsigned long start,
                           unsigned long size)

Instructs the remote harts to execute one or more SFENCE.VMA instructions, covering the range of virtual addresses between start and size.

void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
                                unsigned long start,
                                unsigned long size,
                                unsigned long asid)

Instruct the remote harts to execute one or more SFENCE.VMA instructions, covering the range of virtual addresses between start and size. This covers only the given ASID.

int sbi_console_getchar(void)

Read a byte from debug console; returns the byte on success, or -1 for failure. Note. This is the only SBI call that has a non-void return type.

void sbi_console_putchar(int ch)

Write data present in ch to debug console.

Unlike sbi_console_getchar, this SBI call will block if there remain any pending characters to be transmitted or if the receiving terminal is not yet ready to receive the byte. However, if the console doesn’t exist at all, then the character is thrown away.

void sbi_shutdown(void)

Puts all the harts to shut down state from supervisor point of view. This SBI call doesn’t return.

Function Listing

Function Name Function ID Extension ID Replacement Extension

sbi_set_timer

0

0x00

N/A

sbi_console_putchar

0

0x01

N/A

sbi_console_getchar

0

0x02

N/A

sbi_clear_ipi

0

0x03

N/A

sbi_send_ipi

0

0x04

N/A

sbi_remote_fence_i

0

0x05

N/A

sbi_remote_sfence_vma

0

0x06

N/A

sbi_remote_sfence_vma_asid

0

0x07

N/A

sbi_shutdown

0

0x08

N/A

RESERVED

0x09-0x0F

Hart State Managment Extension, Extension ID: 0x48534D (HSM)

The Hart State Management Extension introduces a set of functions that allow the supervisor to request higher privilege mode to start/stop harts running in supervisor mode.

struct sbiret sbi_hart_start(unsigned long hartid, unsigned long start_addr, unsigned
long priv)

Informs the SBI implementation that the supervisor would like the given hart to begin execution. This call is asynchronous — more specifically, sbi_hart_start() may return before execution has actually begin as long as the SBI implementation is capable of ensuring the return code is accurate.

start_addr points to a runtime-specified physical address, where a hart can resume execution after its initialization/resume sequence. Before jumping to start_addr, the hart MUST configure PMP if present and switch to Supervisor mode.

priv is an XLEN-bit value. Upon execution from start_addr, a2 will contain this exact value.

Returns one of the following possible SBI error codes thorugh sbiret.error.

Error code Description

SBI_SUCCESS

Hart was previously in stopped state. It will start executing from start_addr.

SBI_ERR_INVALID_ADDRESS

start_addr is not valid possibly due to following reasons.
* it is not a valid physical address.
* The address is prohibited by PMP to run in supervisor mode

SBI_ERR_INVALID_PARAM

hartid is not a valid hartid as corresponding hart cannot started in supervisor mode.

SBI_ERR_ALREADY_AVAILABLE

The given hartid is already started.

SBI_ERR_FAILED

The start request failed for unknown reasons.

struct sbiret sbi_hart_stop()

Returns ownership of the calling hart back to the SBI implementation. This call is not expected to return under normal conditions. sbi_hart_stop() must be called with supervisor and user interrupts disabled.

Returns following SBI error code through sbiret.error only if it fails.

  • SBI_ERR_FAILED

struct sbiret sbi_hart_status(unsigned long hartid)

Returns the current status of hartid in sbiret.value, or an error through sbiret.error. The possible status values are shown on the table below.

Name Value Description

AVAILABLE

0

Already available

NOT_AVAILABLE

1

Not available

START_REQUEST_PENDING

2

A start request pending

STOP_REQUEST_PENDING

3

A stop request pending

Possible error code:

  • SBI_ERR_INVALID_PARAM

Since harts may transition state at any time due to any concurrent sbi_hart_start or sbi_hart_stop calls, the return value from this function may not represent the actual state of the hart at the time of return value verification.

HSM Function Listing

Function Name Function ID Extension ID

sbi_hart_start

0

0x48534D

sbi_hart_stop

1

0x48534D

sbi_hart_get_status

2

0x48534D

Experimental SBI Extension Space, Extension IDs 0x0800000 through 0x08FFFFFF

No management.

Vendor-Specific SBI Extension Space, Extension Ids 0x09000000 through 0x09FFFFFF

Low bits from mvendorid.

You can’t perform that action at this time.