Introduction to open_sbi

nylon7 370 views 19 slides Aug 11, 2020
Slide 1
Slide 1 of 19
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19

About This Presentation

Introduction to open_sbi


Slide Content

Introduction to OpenSBI

I’m Nylon Chen
Work for Andes Tech
Hello!

Outline
•SBI
•OpenSBI
•How to add a new SBI call

Ring 3










Ring 2







Ring 1



Ring 0
Least Privileged
Most Privileged
User Space (U-Mode)
Operating System (S-Mode)
Hypervisor(H-Mode)
Firmware(M-Mode)
RISC-V Privilege Modes
X-86 Protection ring
User Space (EL0)
Operating System
(EL1)
Hypervisor(EL2)
Firmware(EL3)
ARM64 Exception Levels

SBI
•SBI stands for RISC-V Supervisor Binary Interface
•The System call type interface layer between Firmware
runtime, M-Mode to Operating system(S-Mode)
•Avoid fragmentation of various OEM silicon providers
specific runtime firmware implementations
•Standard, generic runtime firmware interface
specification across all OSes, different cpu and silicon
platforms
•Specification in SBI v0.2 in usage
•Documentation available at
–https://github.com/riscv/riscv-sbi-doc
App 1 App 2 App 3
ABI ABI ABI
OS (S-Mode)
Open SBI (M-Mode)
SBI

OpenSBI
•Berkeley Boot Loader(BBL)
•OpenSBI is an open-source implementation of the RISC-
V Supervisor Binary Interface (SBI) specifications
•Aimed at providing RUNTIME services in M-mode
•Provides support for reference platforms
•Platforms supports Andes AE350, Ariane FPGA, Kendryte
K210, Nuclei ux600, SiFive U540, Thead c910, QEMU
•firmware implementations
–FW_PAYLOAD
–FW_JUMP
–FW_DYNAMIC

OpenSBI Calling Convention
•S mode traps into M mode using ecall instructions
•Arguments are passed via registers a0-a5
•a7 encodes the SBI extension ID
•a6 encodes the Function ID
•SBI functions must return a pair of values in a0 & a1
•Unsupported SBI returns -2 (SBI_ENOTSUPP in
Linux)
[arch/riscv/include/asm/sbi.h]

#define SBI_SUCCESS 0
#define SBI_ERR_FAILURE -1
#define SBI_ERR_NOT_SUPPORTED -2
...
struct sbiret {
long error;
long value;
};

SBI Call
[arch/riscv/kernel/sbi.c]

struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg1, unsigned long arg2,…)
{

register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);

asm volatile ("ecall"
: "+r" (a0), "+r" (a1)
: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
: "memory");

ret.error = a0;
ret.value = a1;
return ret;
}
Linux kernel
User mode
Supervisor mode
Machine mode
mret
sret
ecall
sbi_trap_handl
e
mtvec

SBI Call (Cont’)
[lib/sbi/sbi_ecall.c]

int sbi_ecall_handler(struct sbi_trap_regs *regs)
{

unsigned long extension_id = regs->a7
unsigned long func_id = regs->a6;
unsigned long args[6];

args[0] = regs->a0;


ext = sbi_ecall_find_extension(extension_id);

if (ext && ext->handle) {
ret = ext->handle(extension_id, func_id,
args, &out_val, &trap);
….
}
regs->a0 = ret;
if (!is_0_1_spec)
regs->a1 = out_val;
}
User mode
Supervisor mode
Machine mode
mret
sret
ecall
mepc
OpenSBI

Legacy SBI Extension
BBL & SBI-v0.1
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

SBI Base Functionality
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
Vendor-Specific SBI Extension Space, Extension Ids 0x09000000 ~ 0x09FFFFFF
sbi_get_mvendorid = 0x31e
andes’s extension ID = 0x0900031E

RFENCE Extension
Function Name Function ID Extension ID
sbi_remote_fence_i 0 0x52464E43
sbi_remote_sfence_vma 1 0x52464E43
sbi_remote_sfence_vma_asid 2 0x52464E43
sbi_remote_hfence_gvma_vmid 3 0x52464E43
sbi_remote_hfence_gvma 4 0x52464E43
sbi_remote_hfence_vvma_asid 5 0x52464E43
sbi_remote_hfence_vvma 6 0x52464E43

Function Name Function ID Extension ID
sbi_set_timer 0 0x54494D45
Function Name Function ID Extension ID
sbi_send_ipi 0 0x735049
LinuxKernel>=5.7
Function Name Function ID Extension ID
sbi_hart_start 0 0x48534D
sbi_hart_stop 1 0x48534D
sbi_hart_get_status 2 0x48534D
Timer, IPI, Hart State Management
Extension

How to Add a New SBI Call
•Platform-specific: If the platform has an extension ID, you can direct-
contribute to OpenSBI mailing list
•Vendor-Specific SBI Extension Space, Extension Ids 0x09000000 through
0x09FFFFFF
•Step 1. Check Low bits from mvendorid
–e.g. andes’s mvendorid = 0x31e -> 0x0900031E
•Step 2. Add sbi_ext_id to Linux
•Step 3. Add a new enum about platform SBI call’s number to Linux
•Step 4. Add platform’s SBI function call by sbi_ecall()
–e.g. sbi_ecall(Platform’s sbi_ext_id, Platform’s sbi number, 0, 0, 0…);
•Step 5. Add hook function to your platform’s SBI handler
–e.g. .vendor_ext_provider = platform_vendor_ext_provider

Add Extension & Function ID
[arch/riscv/include/asm/sbi.h]

enum sbi_ext_id {
#ifdef CONFIG_RISCV_SBI_V01
SBI_EXT_0_1_SET_TIMER = 0x0,
SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
SBI_EXT_0_1_CLEAR_IPI = 0x3,
SBI_EXT_0_1_SEND_IPI = 0x4,
SBI_EXT_0_1_REMOTE_FENCE_I = 0x5,
SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
SBI_EXT_0_1_SHUTDOWN = 0x8,
#endif
SBI_EXT_BASE = 0x10,
SBI_EXT_TIME = 0x54494D45,
SBI_EXT_IPI = 0x735049,
SBI_EXT_RFENCE = 0x52464E43,
SBI_EXT_HSM = 0x48534D,
SBI_EXT_ANDES = 0x0900031E,
};

enum sbi_ext_andes_fid {
SBI_EXT_ANDES_GET_MCACHE_CTL_STATUS = 0
….
}
[include/sbi/sbi_ecall_interface.h]

/* SBI Extension IDs */
#define SBI_EXT_0_1_SET_TIMER 0x0
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
#define SBI_EXT_BASE 0x10
#define SBI_EXT_TIME 0x54494D45
#define SBI_EXT_IPI 0x735049
#define SBI_EXT_RFENCE 0x52464E43
#define SBI_EXT_HSM 0x48534D

….

/* SBI function IDs for HSM extension */
#define SBI_EXT_HSM_HART_START 0x0
#define SBI_EXT_HSM_HART_STOP 0x1
#define SBI_EXT_HSM_HART_GET_STATUS 0x2


#define SBI_EXT_VENDOR_START 0x09000000
#define SBI_EXT_VENDOR_END 0x09FFFFFF
Linux kernel
OpenSBI
R

Add Hook Function to SBI Handler
[platform/andes/ae350/platform.c]


/* Vendor-Specific SBI handler */
static int ae350_vendor_ext_provider(long extid, long funcid,
unsigned long *args, unsigned long *out_value,
struct sbi_trap_info *out_trap)
{
int ret = 0;
switch (funcid) {
case SBI_EXT_ANDES_GET_MCACHE_CTL_STATUS:
*out_value = csr_read(CSR_MCACHECTL);
break;

default:
sbi_printf("Unsupported vendor sbi call : %ld\n", funcid);
}

return ret;
}

const struct sbi_platform_operations platform_ops = {

.vendor_ext_provider = ae350_vendor_ext_provider

}
OpenSBI
R

How to add a new SBI call
•non-platform-specific:
–Think about whether it fits into an existing extension or
else create a new extension
–Think about all of the details of the behaviour and
error cases
–Document that in a patch for the SBI document
–Send it to the (Mailing List] (You need to be subscribed
to be able to post) and create a PR on GitHub
–Argue for it
•How to decide Extension ID
–TIME: 0x54, 0x49, 0x4D, 0x45 - by ASCII

How to add a new SBI call

References
•Working experience on RISC-V
•SBI
•OpenSBI
•Atish Patra “RISC-V Boot Process: One step at a time”
•Atish Patra “Fixing the boot process in RISC-V”
•Anup Patel “Xvisor: Embedded Hypervisor for RISC-V”
•Anup Patel “OpenSBI Deep Dive”
•Jagan Teki “An Introduction to RISC-V Boot flow: Overview, Blob vs
Blobfree standards”
Tags