mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-03-12 10:06:47 -04:00
PoC: Control access to FW RAM
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
This commit is contained in:
parent
0183f25170
commit
e1d7608897
@ -139,16 +139,18 @@ Interrupts can be enabled/disabled using the PicoRV32 specific
|
||||
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 |
|
||||
| *Execution Mode* | *ROM* | *FW RAM* |
|
||||
|---------------------|--------|----------|
|
||||
| Firmware mode | r/x | r/w |
|
||||
| App mode | r | i |
|
||||
| IRQ_SYSCALL_LO | r/x | i |
|
||||
| IRQ_SYSCALL_HI | r/x | r/w |
|
||||
|
||||
Legend:
|
||||
r = readable
|
||||
w = writeable
|
||||
x = executable
|
||||
i = invisible
|
||||
|
||||
## `tk1`
|
||||
|
||||
|
@ -17,8 +17,7 @@ module fw_ram (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire system_mode,
|
||||
|
||||
input wire en,
|
||||
input wire cs,
|
||||
input wire [ 3 : 0] we,
|
||||
input wire [ 8 : 0] address,
|
||||
@ -35,7 +34,6 @@ module fw_ram (
|
||||
reg [31 : 0] mem_read_data0;
|
||||
reg [31 : 0] mem_read_data1;
|
||||
reg ready_reg;
|
||||
wire system_mode_cs;
|
||||
reg bank0;
|
||||
reg bank1;
|
||||
|
||||
@ -45,7 +43,6 @@ module fw_ram (
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = ready_reg;
|
||||
assign system_mode_cs = cs && ~system_mode;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@ -56,12 +53,12 @@ module fw_ram (
|
||||
.RADDR({3'h0, address[7 : 0]}),
|
||||
.RCLK(clk),
|
||||
.RCLKE(1'h1),
|
||||
.RE(system_mode_cs & bank0),
|
||||
.RE(en & cs & bank0),
|
||||
.WADDR({3'h0, address[7 : 0]}),
|
||||
.WCLK(clk),
|
||||
.WCLKE(1'h1),
|
||||
.WDATA(write_data[15 : 0]),
|
||||
.WE((|we & system_mode_cs & bank0)),
|
||||
.WE((|we & en & cs & bank0)),
|
||||
.MASK({{8{~we[1]}}, {8{~we[0]}}})
|
||||
);
|
||||
|
||||
@ -70,12 +67,12 @@ module fw_ram (
|
||||
.RADDR({3'h0, address[7 : 0]}),
|
||||
.RCLK(clk),
|
||||
.RCLKE(1'h1),
|
||||
.RE(system_mode_cs & bank0),
|
||||
.RE(en & cs & bank0),
|
||||
.WADDR({3'h0, address[7 : 0]}),
|
||||
.WCLK(clk),
|
||||
.WCLKE(1'h1),
|
||||
.WDATA(write_data[31 : 16]),
|
||||
.WE((|we & system_mode_cs & bank0)),
|
||||
.WE((|we & en & cs & bank0)),
|
||||
.MASK({{8{~we[3]}}, {8{~we[2]}}})
|
||||
);
|
||||
|
||||
@ -85,12 +82,12 @@ module fw_ram (
|
||||
.RADDR({3'h0, address[7 : 0]}),
|
||||
.RCLK(clk),
|
||||
.RCLKE(1'h1),
|
||||
.RE(system_mode_cs & bank1),
|
||||
.RE(en & cs & bank1),
|
||||
.WADDR({3'h0, address[7 : 0]}),
|
||||
.WCLK(clk),
|
||||
.WCLKE(1'h1),
|
||||
.WDATA(write_data[15 : 0]),
|
||||
.WE((|we & system_mode_cs & bank1)),
|
||||
.WE((|we & en & cs & bank1)),
|
||||
.MASK({{8{~we[1]}}, {8{~we[0]}}})
|
||||
);
|
||||
|
||||
@ -99,12 +96,12 @@ module fw_ram (
|
||||
.RADDR({3'h0, address[7 : 0]}),
|
||||
.RCLK(clk),
|
||||
.RCLKE(1'h1),
|
||||
.RE(system_mode_cs & bank1),
|
||||
.RE(en & cs & bank1),
|
||||
.WADDR({3'h0, address[7 : 0]}),
|
||||
.WCLK(clk),
|
||||
.WCLKE(1'h1),
|
||||
.WDATA(write_data[31 : 16]),
|
||||
.WE((|we & system_mode_cs & bank1)),
|
||||
.WE((|we & en & cs & bank1)),
|
||||
.MASK({{8{~we[3]}}, {8{~we[2]}}})
|
||||
);
|
||||
|
||||
@ -129,7 +126,7 @@ module fw_ram (
|
||||
bank1 = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
|
||||
if (system_mode_cs) begin
|
||||
if (en & cs) begin
|
||||
if (address[8]) begin
|
||||
bank1 = 1'h1;
|
||||
tmp_read_data = mem_read_data1;
|
||||
|
@ -48,6 +48,8 @@ module tk1 #(
|
||||
input wire access_level_hi,
|
||||
input wire access_level_med,
|
||||
|
||||
output wire fw_ram_en,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
input wire [ 7 : 0] address,
|
||||
@ -202,6 +204,7 @@ module tk1 #(
|
||||
assign system_reset = system_reset_reg;
|
||||
|
||||
assign rom_exec_en = !system_mode | access_level_med | access_level_hi;
|
||||
assign fw_ram_en = !system_mode | access_level_hi;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instance.
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "custom_ops.S" // PicoRV32 custom instructions
|
||||
|
||||
#define illegal_insn() .word 0
|
||||
|
||||
.section ".text.init"
|
||||
.globl _start
|
||||
_start:
|
||||
@ -24,18 +26,38 @@ irq_handler:
|
||||
// PicoRV32 stores the IRQ bitmask in x4.
|
||||
// If bit 31 is 1: IRQ31 was triggered.
|
||||
// If bit 30 is 1: IRQ30 was triggered.
|
||||
|
||||
nop // NOPs are not necessary. Only added to make it easier to find
|
||||
nop // when simulating.
|
||||
nop
|
||||
irq_syscall_lo_check:
|
||||
li t4, (1 << 30)
|
||||
bne x4, t4, irq_syscall_hi_check
|
||||
// Firmware RAM should not be readable from IRQ_SYSCALL_LO
|
||||
call check_cannot_read_test_val_from_fw_ram
|
||||
j irq_source_check_done
|
||||
irq_syscall_hi_check:
|
||||
li t4, (1 << 31)
|
||||
bne x4, t4, unexpected_irq
|
||||
// Firmware RAM should be readable from IRQ_SYSCALL_HI
|
||||
call check_can_read_test_val_from_fw_ram
|
||||
j irq_source_check_done
|
||||
unexpected_irq:
|
||||
illegal_insn()
|
||||
irq_source_check_done:
|
||||
picorv32_retirq_insn() // Return from interrupt
|
||||
|
||||
//
|
||||
// Init
|
||||
//
|
||||
.=0x20 // Setting location of init to 0x20. Makes it easier to find when
|
||||
// simulating.
|
||||
.=0x100
|
||||
init:
|
||||
// Save test value in firmware RAM
|
||||
li t0, 0xd0000000
|
||||
li t1, 0x5555aaaa
|
||||
sw t1, 0(t0)
|
||||
|
||||
// Firmware RAM should be readable from firmware mode
|
||||
call check_can_read_test_val_from_fw_ram
|
||||
|
||||
|
||||
// Enable IRQs
|
||||
li t0, 0x3fffffff // IRQ31 & IRQ30 mask
|
||||
picorv32_maskirq_insn(zero, t0) // Enable IRQs
|
||||
|
||||
@ -59,10 +81,15 @@ copy_app:
|
||||
//
|
||||
.align 4
|
||||
app_start:
|
||||
// Firmware RAM should not be readable from app mode
|
||||
call check_cannot_read_test_val_from_fw_ram
|
||||
|
||||
// Raise IRQ_SYSCALL_HI
|
||||
li t0, 0xe1000000 // IRQ_SYSCALL_HI (IRQ31) trigger address
|
||||
sw zero, 0(t0) // Raise IRQ by writing to interrupt trigger address.
|
||||
// Writing any data triggers an interrupt.
|
||||
|
||||
// Raise IRQ_SYSCALL_LO
|
||||
li t0, 0xe0000000 // IRQ_SYSCALL_LO (IRQ30) trigger address
|
||||
sw zero, 0(t0) // Raise IRQ by writing to interrupt trigger address.
|
||||
// Writing any data triggers an interrupt.
|
||||
@ -70,6 +97,27 @@ app_start:
|
||||
jalr zero, 0(zero) // Jumping to firmware. Expecting trap
|
||||
app_loop:
|
||||
j app_loop
|
||||
|
||||
|
||||
check_cannot_read_test_val_from_fw_ram:
|
||||
li t0, 0xd0000000
|
||||
lw t1, 0(t0)
|
||||
li t2, 0
|
||||
bne t1, t2, cannot_read_test_val_from_fw_ram_fail
|
||||
ret
|
||||
cannot_read_test_val_from_fw_ram_fail:
|
||||
illegal_insn()
|
||||
|
||||
check_can_read_test_val_from_fw_ram:
|
||||
// Check that saved test value can not be read while in app mode
|
||||
li t0, 0xd0000000
|
||||
lw t1, 0(t0)
|
||||
li t2, 0x5555aaaa
|
||||
bne t1, t2, can_read_test_val_from_fw_ram_fail
|
||||
ret
|
||||
can_read_test_val_from_fw_ram_fail:
|
||||
illegal_insn()
|
||||
|
||||
.align 4
|
||||
app_end:
|
||||
|
||||
|
@ -138,6 +138,7 @@ module application_fpga (
|
||||
reg [31 : 0] fw_ram_write_data;
|
||||
wire [31 : 0] fw_ram_read_data;
|
||||
wire fw_ram_ready;
|
||||
wire fw_ram_en;
|
||||
|
||||
reg touch_sense_cs;
|
||||
reg touch_sense_we;
|
||||
@ -260,7 +261,7 @@ module application_fpga (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.system_mode(system_mode),
|
||||
.en(fw_ram_en),
|
||||
|
||||
.cs(fw_ram_cs),
|
||||
.we(fw_ram_we),
|
||||
@ -376,6 +377,8 @@ module application_fpga (
|
||||
.access_level_hi (irq31_eoi),
|
||||
.access_level_med(irq30_eoi),
|
||||
|
||||
.fw_ram_en(fw_ram_en),
|
||||
|
||||
.cs(tk1_cs),
|
||||
.we(tk1_we),
|
||||
.address(tk1_address),
|
||||
|
@ -150,6 +150,7 @@ module application_fpga_sim (
|
||||
reg [31 : 0] fw_ram_write_data;
|
||||
wire [31 : 0] fw_ram_read_data;
|
||||
wire fw_ram_ready;
|
||||
wire fw_ram_en;
|
||||
|
||||
reg touch_sense_cs;
|
||||
reg touch_sense_we;
|
||||
@ -271,8 +272,7 @@ module application_fpga_sim (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.system_mode(system_mode),
|
||||
|
||||
.en(fw_ram_en),
|
||||
.cs(fw_ram_cs),
|
||||
.we(fw_ram_we),
|
||||
.address(fw_ram_address),
|
||||
@ -389,6 +389,8 @@ module application_fpga_sim (
|
||||
.access_level_hi (irq31_eoi),
|
||||
.access_level_med(irq30_eoi),
|
||||
|
||||
.fw_ram_en(fw_ram_en),
|
||||
|
||||
.cs(tk1_cs),
|
||||
.we(tk1_we),
|
||||
.address(tk1_address),
|
||||
|
@ -84,7 +84,7 @@ module tb_application_fpga_sim ();
|
||||
//----------------------------------------------------------------
|
||||
initial begin
|
||||
// End simulation after XXX time units (set by timescale)
|
||||
#1600;
|
||||
#3000;
|
||||
$display("TIMEOUT");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user