Rocket RISC-V processor - Adding a custom CSR, software point of view
Introduction
In the context of a research project related to RIMI [1], we need to add a new CSR (Control & Status Register) in the Rocket processor [2] in order to store new security settings. There are obviously modifications to do in the hardware description of the processor (it will be the topic of a future article). However, we also need to modify a few lines of the software stack.
Software stack for Rocket Chip
rocket-tools [3] is the reference repository given by Rocket Chip maintainers. It contains:
-
The cross-compiler :
riscv-gnu-toolchain
-
The simulator :
riscv-isa-sim
(also known as Spike) -
An on-chip debugger :
riscv-openocd
-
A proxy kernel :
riscv-pk
-
Several tests :
riscv-tests
Adding a custom CSR - Use case
Initial configuration
Let’s say we want to add a custom CSR labeled dmpcfg
at address 0x308
(CSR ID isn’t used by any existing register).
Modifications in the software toolchain
It turns out that we have to modify a few lines in fsf-binutils-gdb @ ffea142:
|
|
This repository contains several tools such as objdump, the linker and the assembler. Modifying binutils source code didn’t seem trivial at first sight.
Why is this modification needed?
If we want to access this new CSR with a very simple C code with a default toolchain, an error appears:
|
|
-
Yes, the assembler is involved here.
-
It seems that the
dmpcfg
is unknown to the software toolchain.
This error comes from a function called check_absolute_expr which call graph is as follows:
The description of riscv_ip
is interesting:
This routine assembles an instruction into its binary format.
When looking at the code related to CSR (csrrw
instruction):
|
|
It turns out the GNU assembler is checking the CSR name before assembling the binary!
|
|
Once the CSR ID has been correctly in the GNU assembler (fsf-binutils-gdb
submodule of [3]), the C code given in [4] is compiled without error.