PoC: Trap when executing from ROM in app mode

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>
This commit is contained in:
Mikael Ågren 2024-12-11 11:49:41 +01:00
parent cd959e9966
commit 89c77ca4de
No known key found for this signature in database
GPG Key ID: E02DA3D397792C46
4 changed files with 48 additions and 11 deletions

View File

@ -11,9 +11,10 @@ The design top level is in `rtl/application_fpga.v`. It contains
instances of all cores as well as the memory system.
The memory system allows the CPU to access cores in different ways
given the current execution mode. There are two execution modes -
firmware and application. Basically, in application mode the access is
more restrictive.
given the current execution mode. There are three execution modes -
firmware, application and system call. Each mode give access to a
different set of resources. Where app mode is the most restrictive and
firmware mode is the least restrictive.
The rest of the components are under `cores`. They typically have
their own `README.md` file documenting them and their API in detail.
@ -118,10 +119,10 @@ be inspected to determine the interrupt source. Each interrupt source
is assigned one bit in x4. Triggered interrupts have their bit set to
`1`.
| *Interrupt source* | *x4 bit* |
|--------------------|----------|
| IRQ30\_SET | 30 |
| IRQ31\_SET | 31 |
| *Interrupt Name* | *Source* | *x4 Bit* |
|------------------|------------|----------|
| IRQ_SYSCALL_LO | IRQ30\_SET | 30 |
| IRQ_SYSCALL_HI | IRQ31\_SET | 31 |
The return address is located in register `x3`. Calling the PicoRV32
specific instruction `retirq` exits the interrupt handler and clears
@ -133,6 +134,22 @@ handler. It is up to the software to store/restore as necessary.
Interrupts can be enabled/disabled using the PicoRV32 specific
`maskirq` instruction.
## Restricted resources
The following table shows resource availablility for each execution
mode:
| *Execution Mode* | *ROM* |
|---------------------|--------|
| Firmware mode | r/x |
| App mode | r |
| IRQ_SYSCALL_LO | r/x |
| IRQ_SYSCALL_HI | r/x |
Legend:
r = readable
x = executable
## `tk1`
See [tk1 README](core/tk1/README.md) for details.

View File

@ -45,6 +45,9 @@ module tk1 #(
output wire gpio3,
output wire gpio4,
input wire access_level_hi,
input wire access_level_med,
input wire cs,
input wire we,
input wire [ 7 : 0] address,
@ -178,6 +181,7 @@ module tk1 #(
wire spi_ready;
wire [ 7 : 0] spi_rx_data;
wire rom_exec_en;
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
@ -197,6 +201,7 @@ module tk1 #(
assign system_reset = system_reset_reg;
assign rom_exec_en = !system_mode | access_level_med | access_level_hi;
//----------------------------------------------------------------
// Module instance.
@ -379,6 +384,9 @@ module tk1 #(
//
// Trying to execute instructions in FW-RAM.
//
// Executing instructions in ROM, while ROM is marked as not
// executable.
//
// Trying to execute code in mem area set to be data access only.
// This requires execution monitor to have been setup and
// enabled.
@ -456,6 +464,12 @@ module tk1 #(
force_trap_set = 1'h1;
end
if (!rom_exec_en) begin
if (cpu_addr <= FW_ROM_LAST) begin // Only valid as long as ROM starts at address 0x00.
force_trap_set = 1'h1;
end
end
if (cpu_mon_en_reg) begin
if ((cpu_addr >= cpu_mon_first_reg) && (cpu_addr <= cpu_mon_last_reg)) begin
force_trap_set = 1'h1;

View File

@ -147,11 +147,11 @@ module application_fpga (
reg irq30_cs;
reg irq30_we;
(* keep *)reg irq30_eoi;
reg irq30_eoi;
reg irq31_cs;
reg irq31_we;
(* keep *)reg irq31_eoi;
reg irq31_eoi;
reg tk1_cs;
reg tk1_we;
@ -373,6 +373,9 @@ module application_fpga (
.gpio3(app_gpio3),
.gpio4(app_gpio4),
.access_level_hi (irq31_eoi),
.access_level_med(irq30_eoi),
.cs(tk1_cs),
.we(tk1_we),
.address(tk1_address),

View File

@ -159,11 +159,11 @@ module application_fpga_sim (
reg irq30_cs;
reg irq30_we;
(* keep *)reg irq30_eoi;
reg irq30_eoi;
reg irq31_cs;
reg irq31_we;
(* keep *)reg irq31_eoi;
reg irq31_eoi;
reg tk1_cs;
reg tk1_we;
@ -386,6 +386,9 @@ module application_fpga_sim (
.gpio3(app_gpio3),
.gpio4(app_gpio4),
.access_level_hi (irq31_eoi),
.access_level_med(irq30_eoi),
.cs(tk1_cs),
.we(tk1_we),
.address(tk1_address),