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 15 commits into
base: main
Choose a base branch
from

Conversation

agren
Copy link
Contributor

@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 from 713a9e0 to 3097cfe Compare December 11, 2024 14:49
agren and others added 4 commits December 16, 2024 17:53
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.
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 <[email protected]>
@agren agren force-pushed the syscall_picorv32_irq branch 2 times, most recently from 03df5e7 to 2dc8d2b Compare December 17, 2024 15:01
agren and others added 10 commits December 17, 2024 17:07
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 <[email protected]>
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`
…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 <[email protected]>
Removing IRQ30 since it us no longer exist
Removing IRQ30 since it us no longer exist
Removing IRQ30 since it us no longer exist
@agren agren force-pushed the syscall_picorv32_irq branch from 2dc8d2b to 4afcea2 Compare December 17, 2024 16:25
Removing IRQ30 since it us no longer exist
@agren agren force-pushed the syscall_picorv32_irq branch 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.

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.

2 participants