当前位置: 首页 > 工具软件 > OpenSBI > 使用案例 >

OpenSBI知识结构整理

邢昊焜
2023-12-01

参考资料

SBI Introduction

SBIRISC-V Supervisor Binary Interface,它通过抽象出特定平台的特定功能,在原来s-u mode架构中新增了一个hs mode中间层,从而允许s-mode应用在所有risc-v实现中移植

新版本qemu中默认安装了opensbi

$ qemu-system-riscv64 \
  --machine virt \
  --nographic \
  --bios default

OpenSBI v0.4 (Jul  2 2023 11:53:53)
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name          : QEMU Virt Machine
Platform HART Features : RV64ACDFIMSU
Platform Max HARTs     : 8
Current Hart           : 0
Firmware Base          : 0x80000000
Firmware Size          : 112 KB
Runtime SBI Version    : 0.1

PMP0: 0x0000000080000000-0x000000008001ffff (A)
PMP1: 0x0000000000000000-0xffffffffffffffff (A,R,W,X)

Call Convention

SBI遵循如下调用约定规范:

  • ecall指令作为从HS-ModeSEE之间的控制转移指令
  • a7定义了SBI extension ID(EID)
  • a6定义了SBI function ID (FID)
  • 在调用时,被调用方必须保留除去a0a1的其他所有寄存器值
  • 函数返回:以a0a1为结构的一个结构体,其中a0为错误码
    struct sbiret {
        long error;
        long value;
    };

SBI标准返回错误码

Error TypeValue
SBI_SUCCESS0
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_ERR_ALREADY_STARTED-7
SBI_ERR_ALREADY_STOPPED-8

HART list parameter

hart是什么?一般称为管理RISC-V处理器的机制,在riscv模式中会将riscvcore称为hart,有时也称为hardware thread,即硬件线程

Hart State Management Extension (EID #0x48534D “HSM”)可见

如果SBI函数需要将hart列表传递到更高权限模式,它必须使用如下所定义的hart掩码

  • unsigned long hart_mask是一个包含hartids的标量
  • unsigned long hart_mask_base:是必须计算位向量的起始hartid

在单个SBI函数调用中,可以设置的最大哈特数总是XLEN

hart_mask_base可以设置为-1,表示可以忽略hart_mask,并且必须考虑所有可用的hart


在此提一下RISC-V的特权级寄存器

首先来看下通用寄存器:RV32I是其中一种整数指令集,支持32个通用整数寄存器,每一个寄存器有32位,由x0~x31表示,其中x0寄存器被预留为常数0,在汇编语言中,通用寄存器组中的每一个寄存器都有别名

RegisterABI NameDescription
x0zeroHard-wired zero
x1raReturn address
x2spStack pointer
x3gpGlobal pointer
x4tpThread pointer
x5-7t0-2Temporaries
x8s0/fpSaved register/frame pointer
x9s1Saved register
x10-11a0-1Function arguments/retrurn values
x12-17a2-7Function arguments
x18-27s2-11Saved register
x28-31t3-6Temporaries

除了通用寄存器,RISC-V针对各个特权级,还定义了一系列特权级控制状态寄存器

  • misa:表示hart支持的架构扩展,包括整数、乘除、原子、浮点数、双精度浮点数和压缩指令扩展等
  • mhartid:当前正在执行代码的hartid
  • medeleg:默认情况下,所有的异常都是在M模式下处理。当相应的medeleg位置1时,该异常直接由S模式或U模式处理
  • mideleg:默认情况下,所有的中断都是在M模式下处理。当相应的mideleg位置1时,该中断直接由S模式或U模式处理
  • mtime:存储当前的时钟计数值
  • mtimecmp:时钟计数比较器。当当前mtime寄存器中的值大于mtimecmp中的值时,触发时钟中断
  • mstatus:表示当前处理器的控制状态,包括全局中断使能位。内存特权级,字节序控制位等
  • mtvec:保存发生trap时处理器需要跳转到的地址
  • mip:指示正准备处理的中断类型。EIP表示外部中断,TIP表示时钟中断,SIP表示软件中断。当相应的中断位置1时,表示存在该类型中断待处理
  • mie:指示处理器目前使能和忽略的中断类型。EIP表示外部中断,TIP表示时钟中断,SIP表示软件中断。当相应的中断位置1时,表示该类型中断可以被处理器响应
  • mscratch:保存指向当前hart上下文的指针
  • mepc:保存引发异常的指令
  • mtval:它保存了trap的附加信息:地址例外中出错的地址、发生非法指令例外的指令本身,对于其他trap,它的值为 0
  • mcause:指示发生trap的种类。当最高位为1时,低位字段表示发生中断的类型;当最高位为0时,低位字段表示发生异常或系统调用的类型

opensbiM模式的一种实现,每一个hart都有自己的上下文状态,上下文状态的指针保存在mscratch寄存器中,opensbi首先根据平台定义的hart的数量和hart栈的大小分配栈空间,然后依次为每一个hart初始化sbi scratch结构体,包括固件在内存中的地址,下一个启动阶段要执行的代码入口地址,参数以及特权级等信息,并将sbi scratch的地址赋值给mscratch寄存器

Runtime Mode

RISC-V 定义了三种特权模式

  • Machine Mode:机器模式,简称 M 模式,对应特权等级 3。这是 RISC-V hart可以执行的最高权限模式
  • Supervisor Mode:监管者模式,简称 S 模式,对应特权等级 1
  • User Mode:用户模式,简称 U 模式,对应特权等级 0

此外还定义了保留的特权等级 2,在 H 扩展中会将 S 模式扩展为 HS 模式

一般是以下三种组合:

  • M Mode:通常为简单的嵌入式系统
  • M Mode + U Mode:该系统可以实现用户和机器模式的区分,从而实现资源的保护
  • M Mode + U Mode + U Mode:该系统可以实现类Unix操作系统

SBI Extension

Base Extension (EID #0x10)

Base Extension部分被设计得尽可能小。因此,它只包含探测哪些SBI扩展可用以及查询SBI版本的功能

所有SBI实现都必须支持基本扩展中的所有函数,因此没有定义错误返回

Get SBI specification version (FID #0):返回当前SBI规范版本

struct sbiret sbi_get_spec_version(void);

Get SBI implementation ID (FID #1):返回当前的SBI实现ID,每个SBI实现的ID都不同

struct sbiret sbi_get_impl_id(void);

Get SBI implementation version (FID #2):返回当前SBI实现版本

struct sbiret sbi_get_impl_version(void);

Probe SBI extension (FID #3):如果给定的SBI扩展ID (EID)不可用,则返回0;如果可用,则返回1,除非实现将其定义为任何其他非零值

struct sbiret sbi_probe_extension(long extension_id);

Get machine vendor ID (FID #4):返回一个mvendorid CSR的合法值,0总是这个CSR的合法值

struct sbiret sbi_get_mvendorid(void);

Get machine architecture ID (FID #5):返回一个对marchid CSR合法的值,并且0始终是这个CSR的合法值

struct sbiret sbi_get_marchid(void);

Get machine implementation ID (FID #6):返回一个对于mimpid CSR合法的值,并且0始终是这个CSR的合法值

struct sbiret sbi_get_mimpid(void);

Legacy Extensions (EIDs #0x00 - #0x0F)

Legacy Extension使用了不同的Call Convention

  • a6寄存器中的SBI函数ID字段被忽略,因为它们被编码为多个SBI扩展ID
  • a1寄存器中不返回任何内容
  • SBI调用中,被调用方必须保留除a0之外的所有寄存器
  • a0寄存器中返回的值是特定于SBI Legacy Extensions

SBI Legacy Extensions已弃用,而支持下面列出的其他扩展

Extension: Set Timer (EID #0x00)

long sbi_set_timer(uint64_t stime_value)

Extension: Console Putchar (EID #0x01):将ch中出现的数据写入调试控制台

long sbi_console_putchar(int ch)

Extension: Console Getchar (EID #0x02):从调试控制台读取一个字节

long sbi_console_getchar(void)

Extension: Clear IPI (EID #0x03)

Extension: Send IPI (EID #0x04):向hart_mask中定义的所有hart发送一个处理器间中断。处理器间中断在接收端显示为管理软件中断

long sbi_send_ipi(const unsigned long *hart_mask)

Extension: Remote FENCE.I (EID #0x05):指示远程hart执行FENCE.I指令

long sbi_remote_fence_i(const unsigned long *hart_mask)

Extension: Remote SFENCE.VMA (EID #0x06):指示远程hart执行一个或多个SFENCE.VMA指令,涵盖起始地址和大小之间的虚拟地址范围

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

Extension: Remote SFENCE.VMA with ASID (EID #0x07):指示远程hart执行一个或多个SFENCE.VMA指令,涵盖起始地址和大小之间的虚拟地址范围。这只包括给定的ASID

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

Extension: System Shutdown (EID #0x08):从管理人员的角度将所有设备置于关机状态

void sbi_shutdown(void)

Timer Extension (EID #0x54494D45 “TIME”)

这将取代遗留的legacy timer extension (EID #0x00),即Extension: Set Timer (EID #0x00)

Function: Set Timer (FID #0)

struct sbiret sbi_set_timer(uint64_t stime_value)

IPI Extension (EID #0x735049 “sPI: s-mode IPI”)

这个Extension替换了 legacy extension (EID #0x04)

RFENCE Extension (EID #0x52464E43 “RFNC”)

这个Extension替换了legacy extensions (EIDs #0x05 - #0x07)

Hart State Management Extension (EID #0x48534D “HSM”)

Hart State Management(HSM)扩展引入了一组Hart State和一组允许管理模式软件请求改变Hart State的函数

下面所示的HSM哈特状态描述了所有可能的HSM状态以及每个状态的唯一HSM状态id

State IDState NameDescription
0STARTEDhart 被物理启动且正常运行
1STOPPEDhart 没有在 S 模式或任何更低的特权模式下执行。如果平台有能够关闭 hart 的机制,这可能是因为它被 SBI 的实例关闭了
2START_PENDING其它 hart 要求从 STOPPED 状态继续或启动这个 hart,SBI 实例正在尝试让该 hart 进入 STARTED 状态
3STOP_PENDING该 hart 要求将自己从 STARTED 状态停止或关闭,SBI 实例正在尝试让该 hart 进入 STOPPED 状态
4SUSPENDED该 hart 处于平台特定的挂起(或低功耗)状态
5SUSPEND_PENDING该 hart 要求让自己从 STARTED 状态进入平台特定的低功耗状态,SBI 实例正在尝试让其进入平台特定的 SUSPENDED 状态
6RESUME_PENDING中断或平台特定的硬件事件导致 hart 从 SUSPENDED 状态转为正常执行,SBI 实例正在尝试将该 hart 转为 STARTED 状态

任何时刻 hart 的状态只可能是上表中的某一种

Function: HART start (FID #0):在 start_addr 处以S 模式执行 hartid 所指定的 hart,并在开始执行时将 opaque 存入a1寄存器。其中 opaque 是一个 XLEN 位的值,XLEN 指机器位数

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

Function: HART stop (FID #1):请求SBI实现停止在监督模式下执行调用hart,并将其所有权交还给SBI实现

struct sbiret sbi_hart_stop(void)

Function: HART get status (FID #2):返回 hartid 指定的 hart 的状态

struct sbiret sbi_hart_get_status(unsigned long hartid)

Function: HART suspend (FID #3):要求 SBI 实现将调用该函数的 hart 置于 suspend_type 所指定的平台特定挂起(或低功耗)状态,resume_addr hart 在挂起结束之后回到S模式继续执行的地址,opaque 是一个 XLEN 位的值,其会在 hart 结束挂起状态时被放入 a1 寄存器

struct sbiret sbi_hart_suspend(uint32_t suspend_type,
                               unsigned long resume_addr,
                               unsigned long opaque)

System Reset Extension (EID #0x53525354 “SRST”)

系统复位扩展提供了允许管理软件请求系统级重新启动或关机的功能

Function: System reset (FID #0):根据提供的reset_typereset_reason重置系统

struct sbiret sbi_system_reset(uint32_t reset_type, uint32_t reset_reason)

Performance Monitoring Unit Extension (EID #0x504D55 “PMU”)

RISC-V硬件性能计数器,如mcycle、minstretmhpmcounterX csr,可以在管理模式下使用cycle、instrethpmcounterX csr以只读方式访问

SBI性能监控单元(PMU)扩展是supervisor-mode在machine-mode(或hypervisor-mode)的帮助下配置和使用RISC-V硬件性能计数器的接口

SBI PMU扩展提供

  • 管理模式软件用于发现和配置每个hart硬件/固件计数器的接口
  • 一个典型的perf兼容接口

Debug Console Extension (EID #0x4442434E “DBCN”)

调试控制台扩展定义了一种通用机制,用于从管理模式软件进行调试和引导时早期打印

这个扩展取代了the legacy console putchar (EID #0x01)console getchar (EID #0x02) extensions

调试控制台扩展允许管理模式软件在单个SBI调用中写入或读取多个字节

Function: Console Write (FID #0):将字节从输入内存写入调试控制台

struct sbiret sbi_debug_console_write(unsigned long num_bytes,
                                      unsigned long base_addr_lo,
                                      unsigned long base_addr_hi)

Function: Console Read (FID #1):将字节从调试控制台读入输出内存

struct sbiret sbi_debug_console_read(unsigned long num_bytes,
                                      unsigned long base_addr_lo,
                                      unsigned long base_addr_hi)

Function: Console Write Byte (FID #2):将一个字节写入调试控制台

struct sbiret sbi_debug_console_write_byte(uint8_t byte)

SBI System Suspend Extension (EID #0x53555350 “SUSP”)

system suspend extension定义了一组系统级睡眠状态和一个允许管理模式软件请求系统转换到睡眠状态的功能

CPPC Extension (EID #0x43505043 “CPPC”)

ACPI定义了Collaborative Processor Performance Control (CPPC)机制,这是一种抽象而灵活的机制,用于监督模式电源管理软件与平台中的实体协作以管理处理器的性能

Experimental SBI Extension Space (EIDs #0x08000000 - #0x08FFFFFF)

Vendor-Specific SBI Extension Space (EIDs #0x09000000 - #0x09FFFFFF)

Firmware Specific SBI Extension Space (EIDs #0x0A000000 - #0x0AFFFFFF)

 类似资料: