Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware syscall support #234

Open
dehanj opened this issue Jun 12, 2024 · 1 comment · May be fixed by #256
Open

Hardware syscall support #234

dehanj opened this issue Jun 12, 2024 · 1 comment · May be fixed by #256
Assignees
Labels
enhancement New feature or request fpga Related to the FPGA design
Milestone

Comments

@dehanj
Copy link
Member

dehanj commented Jun 12, 2024

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:

    • 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

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.

@dehanj dehanj added the fpga Related to the FPGA design label Jun 12, 2024
@dehanj dehanj added this to the Castor milestone Jun 13, 2024
@dehanj dehanj linked a pull request Aug 26, 2024 that will close this issue
9 tasks
@mchack-work mchack-work changed the title Only allow FW to access the SPI master Hardware syscall support Oct 14, 2024
@tillitis tillitis deleted a comment from secworks Oct 14, 2024
@mchack-work mchack-work added the enhancement New feature or request label Oct 14, 2024
@mchack-work
Copy link
Member

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?

@mchack-work mchack-work mentioned this issue Oct 26, 2024
10 tasks
@dehanj dehanj mentioned this issue Nov 14, 2024
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fpga Related to the FPGA design
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants