You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our firmware is gaining more functionality. We are developing, in effect, system calls so device apps can access flash memory in an isolated way. See PR #273
The firmware will need hardware assistance to keep this safe. We need to protect at least SPI access and the FW_RAM from the device apps. We would also like to protect the firmware ROM from execution in app mode.
Hardware requirements
A system call mechanism. See below for some alternatives.
Raising privilege mode somehow, probably either a toggled bit or a third mode between FW mode and App mode, whichever is cheaper. In the privileged mode:
FW_RAM available for read/write.
SPI master available.
ROM executable.
A way of lowering the privilege mode:
FW_RAM no longer available.
SPI master no longer available.
ROM not executable. Note that this means ROM is no longer executable in app mode. This breaks BLAKE2s access! Can we live with that?
System calls
In the RISC-V specification a system call to a kernel (or even a firmware call from a kernel) is initiated with the ecall instruction. The higher privileged level registers an exception handler vector (STVEC for kernel, MTVEC for machine mode). When the ecall is called the CPU saves the PC, raises the privilege level, and jumps to the registered address for the exception handler. When the handler is finished it jumps back to corresponding saved PC (SEPC or MEPC).
We would like to do something very similar, but preferably without changing anything in the PicoRV32 design. However, PicoRV32 doesn't even implement ecall, nor the necessary CSR registers. We are running in machine mode all the time. We are currently not even using the simplified interrupt handling PicoRV32 supports, which would give us at least ebreak. If built with IRQ, the design doesn't fit in our chip (160% LC utilization).
We have a couple of options to solve this:
1. Traditional syscall
A traditional syscall solution, where firmware registers an address for syscalls, the device app triggers something which makes the hardware raise the privilege (see requirements above) and jump to the address.
The "something" that the device app can trigger can be as easy as a write to a specific memory address. We can probably solve save/restore of the PC with software.
We might even consider implementing a simpler version of ecall in PicoRV32 itself, but if we can do it in MMIO that will keep PicoRV32 pristine.
2. Blessed address or jump table
A blessed jump or branch table that automatically raises the privilege when the program counter reaches it.
This jump table might be filled in in the building process and be part of the ROM or it might be filled in by firmware when starting. Note that if it's stored in ROM we have to exclude this from the ROM execution prevention.
A function trampoline similar to how we offer the firmware's BLAKE2s function to device apps might be used for something like this.
The design will have to watch the program counter and when it reaches the blessed address(es) in the table (which might be just one slot), it will raise the privilege: make FW\RAM available, ROM executable, and enable SPI.
The BLAKE2s is currently implemented like this: The firmware registers the address of the function to call in an MMIO, TK1_MMIO_TK1_BLAKE2S (0xff000040). The contents of TK1_MMIO_TK1_BLAKE2s is just the address to the beginning of the C function in the firmware. It's called directly a function pointer right into ROM.
To use this for privelege raising, the design must watch PC for the address stored in TK1_MMIO_TK1_BLAKE2S and then raise the privileges.
We might to keep backwards compatibility and use a new MMIO, if it's at all possible, and keep the BLAKE2s one.
More options?
Existing hardware design PoCs
PoC: create a syscall by forcing the next CPU instruction #259: Close to the hardware support for number 1. Doesn't actually change PC when triggering. Instead of an address in an exception handler vector, firmware will register an instruction. When triggering that instruction will be fed to the CPU. This might be a jump instruction so it would be very similar. Note though the problems noted in the PR. Would be nicer if we can just insert an address and force a jump.
Access control to the SPI core #256: Trampoline like in number 2 BLAKE2s but uses PC leaving firmware as a way of automatically leaving the higher privilege?
It seems very complex to follow the program counter's every move in qemu to see if it suddenly ends up on a blessed address and then raise the privileges.
From an emulation standpoint solution number 1 above where we trigger the actual exception by reading or writing to some specific memory is much easier. Would that work with the real hardware, too?
Introduction
Our firmware is gaining more functionality. We are developing, in effect, system calls so device apps can access flash memory in an isolated way. See PR #273
The firmware will need hardware assistance to keep this safe. We need to protect at least SPI access and the FW_RAM from the device apps. We would also like to protect the firmware ROM from execution in app mode.
Hardware requirements
A system call mechanism. See below for some alternatives.
Raising privilege mode somehow, probably either a toggled bit or a third mode between FW mode and App mode, whichever is cheaper. In the privileged mode:
A way of lowering the privilege mode:
System calls
In the RISC-V specification a system call to a kernel (or even a firmware call from a kernel) is initiated with the
ecall
instruction. The higher privileged level registers an exception handler vector (STVEC for kernel, MTVEC for machine mode). When theecall
is called the CPU saves the PC, raises the privilege level, and jumps to the registered address for the exception handler. When the handler is finished it jumps back to corresponding saved PC (SEPC or MEPC).We would like to do something very similar, but preferably without changing anything in the PicoRV32 design. However, PicoRV32 doesn't even implement
ecall
, nor the necessary CSR registers. We are running in machine mode all the time. We are currently not even using the simplified interrupt handling PicoRV32 supports, which would give us at leastebreak
. If built with IRQ, the design doesn't fit in our chip (160% LC utilization).We have a couple of options to solve this:
1. Traditional syscall
A traditional syscall solution, where firmware registers an address for syscalls, the device app triggers something which makes the hardware raise the privilege (see requirements above) and jump to the address.
The "something" that the device app can trigger can be as easy as a write to a specific memory address. We can probably solve save/restore of the PC with software.
We might even consider implementing a simpler version of
ecall
in PicoRV32 itself, but if we can do it in MMIO that will keep PicoRV32 pristine.2. Blessed address or jump table
A blessed jump or branch table that automatically raises the privilege when the program counter reaches it.
This jump table might be filled in in the building process and be part of the ROM or it might be filled in by firmware when starting. Note that if it's stored in ROM we have to exclude this from the ROM execution prevention.
A function trampoline similar to how we offer the firmware's BLAKE2s function to device apps might be used for something like this.
The design will have to watch the program counter and when it reaches the blessed address(es) in the table (which might be just one slot), it will raise the privilege: make FW\RAM available, ROM executable, and enable SPI.
The BLAKE2s is currently implemented like this: The firmware registers the address of the function to call in an MMIO,
TK1_MMIO_TK1_BLAKE2S
(0xff000040). The contents ofTK1_MMIO_TK1_BLAKE2s
is just the address to the beginning of the C function in the firmware. It's called directly a function pointer right into ROM.To use this for privelege raising, the design must watch PC for the address stored in
TK1_MMIO_TK1_BLAKE2S
and then raise the privileges.We might to keep backwards compatibility and use a new MMIO, if it's at all possible, and keep the BLAKE2s one.
More options?
Existing hardware design PoCs
PoC: create a syscall by forcing the next CPU instruction #259: Close to the hardware support for number 1. Doesn't actually change PC when triggering. Instead of an address in an exception handler vector, firmware will register an instruction. When triggering that instruction will be fed to the CPU. This might be a jump instruction so it would be very similar. Note though the problems noted in the PR. Would be nicer if we can just insert an address and force a jump.
Access control to the SPI core #256: Trampoline like in number 2 BLAKE2s but uses PC leaving firmware as a way of automatically leaving the higher privilege?
PoC: Raise privilege if executing in ROM #258: Trampoline like BLAKE2s.
PoC: Automatically control system_mode in hardware using a "blessed" address #299: A combination of both Access control to the SPI core #256 and PoC: Raise privilege if executing in ROM #258. Includes both the automatic privilege raising and revoking, using a blessed address and monitoring if we are executing above ROM. This is based on the persistent storage poc Poc: persistant storage #298 and works on target.
Existing software PoCs
The
#273#298 PR uses the existing BLAKE2s as a trampoline to access syscall. It relies on the hardware to raise the privilege.The text was updated successfully, but these errors were encountered: