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

PoC: Implement syscalls using PicoRV32 interrupts #305

Draft
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

agren
Copy link
Member

@agren agren commented Dec 9, 2024

Description

This is a proof of concept of using PicoRV32 interrupts to implement syscalls.
The idea is to let in app execute system calls by raising an interrupt. The
following sequence describes a syscall call:

  1. App raises interrupt by writing to a raise-interrupt-address
  2. Interrupt handler get executed
  3. Syscall gets handled
  4. Interrupt handler returns to app by calling PicoRV32-specific
    instruction retirq.

One interrupt is added: IRQ31. An interrupt is triggered by writing
to a specific memory area. Triggering an interrupt hands over execution to the interrupt handler in firmware ROM (address 0x10).
The PicoRV32 eoi signal is used to make certain resources, which are otherwise unavailable in app mode, available to the interrupt handler.

Four example firmwares are available to demonstrate interrupt handling:

  • hw/application_fpga/fw/irqpoc/start.S
  • hw/application_fpga/fw/irqpoc_led_toggle/start.S
  • hw/application_fpga/fw/irq_poc_with_app/start.S
  • hw/application_fpga/fw/irqpoc_c_example/start.S

Added so far:

  • Enable PicoRV32 interrupts
  • Allow access to resources during syscall interrupt
    • Executing from firmware ROM allowed
    • Firmware RAM available
    • SPI accessible
  • Lock down resources only available in firmware mode
  • Example firmware with syscall implementation in C (see irqpoc_c_example)
  • Example app calling of syscalls from C

This draft PR is part of investigating #234.

@agren agren force-pushed the syscall_picorv32_irq branch from 54af78a to 713a9e0 Compare December 9, 2024 13:03
@agren agren force-pushed the syscall_picorv32_irq branch 5 times, most recently from 4afcea2 to 6023d97 Compare December 17, 2024 17:16
@@ -291,7 +293,7 @@ module tk1 #(
gpio2_reg[1] <= gpio2_reg[0];

if (system_mode_we) begin
system_mode_reg <= 1'h1;
system_mode_reg <= system_mode_new;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep system_mode_reg <= 1'h1;

Then we can remove system_mode_new completely. Since what I can see we never return to system_mode_reg = 0.

@mchack-work mchack-work linked an issue Jan 21, 2025 that may be closed by this pull request
@agren agren force-pushed the syscall_picorv32_irq branch 7 times, most recently from c40f63c to c8f43bb Compare February 4, 2025 08:35
agren added 2 commits February 4, 2025 12:25
A proof-of-concept of enabling PicoRV32 interrupts. Two interrupt
sources, which can be triggered by writes to memory addresses, are
added.  The design has only been simulated, not run on hardware.

Synthesis:

Ice40 LC utilization is 93% (4934/5280) when built using tkey-builder:4

Simulation:

A `tb_application_fpga_irqpoc` target is added. Running `make
tb_application_fpga_irqpoc` creates `tb_application_fpga_sim.fst` which
can be inspected in GTKWave or Surfer.

Firmware:

A simple firmware is added in `fw/irqpoc`. It enables both interrupts
and triggers each interrupt once.

Custom PicoRV32 instructions are located in `custom_ops.S`. It is
imported from upstream PicoRV32 commit:
YosysHQ/picorv32@70f3c33
Add example firmware for demoing interrupts on Tkey hardware.
@agren agren force-pushed the syscall_picorv32_irq branch from c8f43bb to 2a11b76 Compare February 4, 2025 11:32
dehanj and others added 7 commits February 7, 2025 12:54
Instead of manually switching to app mode using the system mode
register, app mode will be enabled when executing outside of firmware
ROM.

Co-authored-by: Mikael Ågren <mikael@tillitis.se>
Only allow executing from ROM when in one of the following execution
contexts:
- Firmware mode
- IRQ_SYSCALL_LO
- IRQ_SYSCALL_HI

Co-authored-by: Daniel Jobson <jobson@tillitis.se>
Adds a basic example firmware that copies an app to app RAM. The app
triggers syscall interrupts and tries to execute ROM code from app mode.

A make target (`tb_application_fpga_irqpoc_with_app`) that simulates a
Tkey running the firmware is added.
Allow FW RAM access only in the following execution contexts:
- Firmware mode
- IRQ_SYSCALL_HI

Input port `system_mode` of the `fw_ram` module is replaced with an
enable port. Since access to FW RAM not longer depend only on
system_mode
…ed in C

App is embedded in firmware and is loaded into app RAM when firmware
starts.
App continuously calls SET_LED syscalls.

Simulation: `make tb_application_fpga_irqpoc_c_example`
Co-authored-by: Mikael Ågren <mikael@tillitis.se>
agren and others added 23 commits February 7, 2025 12:54
…is set

After the first time system_mode is set to one, the assets will no
longer be read- or writeable, even if system_mode is set to zero at a
later syscall. This is to make sure syscalls does not have the same
privilege as the firmware has at first boot.

We need to monitor when system_mode is set to one, otherwise we might
accedentially lock the assets before actually leaving firmware, for
example if firmware would use a function set in any of the registers
used in system_mode_ctrl.

Co-authored-by: Mikael Ågren <mikael@tillitis.se>
Removing IRQ30 since it us no longer exist
Removing IRQ30 since it us no longer exist
Removing IRQ30 since it us no longer exist
Removing IRQ30 since it us no longer exist
Keep WE and CS high for one clock cycle instead of two. To avoid writing
the same address twice.
Always display errors to make them easy to find and troubleshoot.
Fixing tests that broke when adding interrupt based syscalls
Removing the blake2s test since the blake2s registers are removed.
Fix test1. It broke while implementing interrupt based syscalls.

Instead of writing to ADDR_SYSTEM_MODE_CTRL, app mode is now entered
automatically when executing outside of ROM.
Fix test1. It broke while implementing interrupt based syscalls.

Instead of writing to ADDR_SYSTEM_MODE_CTRL, app mode is now entered
automatically when executing outside of ROM.
Fix test10. It broke while implementing interrupt based syscalls.

Cleaning up after the previous test. We reset the memory bus to a known
idle state. We also reset the DUT to make the SPI master visible.
…calls

Checks availability of:
- CDI
- UDI
- RAM
- SPI
Adds:
- SYSCALL_RESET
- SYSCALL_SET_LED
Removing the blake2s test since the possibility for the firmware to
expose a blake2s function to the app has been removed.
App mode can no longer be controlled from software. So the tests have to
run from firmware RAM.
@agren agren force-pushed the syscall_picorv32_irq branch from 2a11b76 to c0a9819 Compare February 7, 2025 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hardware syscall support
2 participants