在实现多核操作系统的时候, 有一个问题很重要, 就是如何存储并读取和处理器核(RISC-V的核也叫做hart)相关的数据结构(hart-local data structure / context)。
一种直接的实现方法是, 对该类数据结构, 开设一个数组, 用核编号作为下标。在访问的时候只需要通过某种办法, 获得核编号, 然后就可以直接访问了。例如, 在RISC-V中, 可以设法读取mhartid来获得核编号。不幸的是, mhartid是一个M态的寄存器, 在S态的操作系统无法直接读取, 若想要读取, 需要通过类似于系统调用的方式。由于核编号在操作系统中使用非常频繁, 所以通过系统调用来读取mhartid会有很大的性能损失。
注意到sscratch是一个S态可以随意读写的不会产生副作用的CSR(寄存器), 并且不会被用户修改。事实上, RISC-V的特权指令集规范[A. Waterman. et al. 2017]已经大致说明了如何使用sscratch解决这个问题:
Typically, sscratch is used to hold a pointer to the hart-local supervisor context while the hart is executing user code. At the beginning of a trap handler, sscratch is swapped with a user register to provide an initial working register.
通常, 在运行用户态代码时, sscratch用来存储一个hart相关的S态上下文的指针。在中断处理程序的开始, sscratch会和一个通用寄存器交换来提供首个可用的通用寄存器。
我的实现与Linux类似。
参考文献:
A. Waterman, K. Asanovic, SiFive Inc. 2017. The RISC-V Instruction Set Manual Volume II: Privileged Architecture Privileged Architecture Version 1.10 https://riscv.org/specifications/
强强!已阅。
强强!已阅。
原文提到“mhartid是一个M态的寄存器, 在S态的操作系统无法直接读取, 若想要读取, 需要通过类似于系统调用的方式。”这一表述或许与SBI Spec有误。
经观察SBI Spec,并未提供有关获取hartid的调用。且Spec中HSM Hart Start Register State指出会将hartid放在a0寄存器中,因此S-Mode软件只在启动时拿到自己的hartid并自己通过某些方式维护。
谢谢指出!!
是这个文档说的吗?
https://github.com/riscv-software-src/opensbi/blob/master/docs/firmware/fw.md
OpenSBI provides firmware builds for specific platforms. Different types of firmwares are supported to deal with the differences between different platforms early boot stage. All firmwares will execute the same initialization procedure of the platform hardware according to the platform specific code as well as OpenSBI generic library code. The supported firmwares type will differ in how the arguments passed by the platform early boot stage are handled, as well as how the boot stage following the firmware will be handled and executed.
The previous booting stage will pass information via the following registers of RISC-V CPU:
hartid via a0 register
device tree blob address in memory via a1 register. The address must be aligned to 8 bytes.
OpenSBI currently supports three different types of firmwares.