Skip to content

Commit

Permalink
Introduce new bit to mark ROM as non-executable
Browse files Browse the repository at this point in the history
This is dynamically set by hw in system_mode_ctrl. ROM will reset to
executable, but will be marked as non-executable as soon as we are no
longer executing in ROM, like system_mode.

ROM will be marked as executable again, if function calls are made to
either `syscall_addr_reg` or `blake2s_addr_reg`. Set reset value of
`blake2s_addr_reg` to an illegal address, halting the CPU if it is
called unset.

The blake2s function is 4-byte aligned, to ensure the cpu_addr is is
aligned with the address in the register.

Co-authored-by: Mikael Ågren <[email protected]>
  • Loading branch information
dehanj and agren committed Nov 21, 2024
1 parent b3af50d commit c246850
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 38 deletions.
117 changes: 80 additions & 37 deletions hw/application_fpga/core/tk1/rtl/tk1.v
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,17 @@ module tk1 (
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
reg [31 : 0] cdi_mem [0 : 7];
reg [31 : 0] cdi_mem [0 : 7];
reg cdi_mem_we;

reg system_mode_reg;
reg system_mode_new;
reg system_mode_we;

reg rom_executable_reg;
reg rom_executable_new;
reg rom_executable_we;

reg [ 2 : 0] led_reg;
reg led_we;

Expand Down Expand Up @@ -258,33 +262,34 @@ module tk1 (
//----------------------------------------------------------------
always @(posedge clk) begin : reg_update
if (!reset_n) begin
system_mode_reg <= 1'h0;
led_reg <= 3'h6;
gpio1_reg <= 2'h0;
gpio2_reg <= 2'h0;
gpio3_reg <= 1'h0;
gpio4_reg <= 1'h0;
app_start_reg <= 32'h0;
app_size_reg <= 32'h0;
blake2s_addr_reg <= 32'h0;
syscall_addr_reg <= ILLEGAL_ADDR;
cdi_mem[0] <= 32'h0;
cdi_mem[1] <= 32'h0;
cdi_mem[2] <= 32'h0;
cdi_mem[3] <= 32'h0;
cdi_mem[4] <= 32'h0;
cdi_mem[5] <= 32'h0;
cdi_mem[6] <= 32'h0;
cdi_mem[7] <= 32'h0;
cpu_trap_ctr_reg <= 24'h0;
cpu_trap_led_reg <= 3'h0;
cpu_mon_en_reg <= 1'h0;
cpu_mon_first_reg <= 32'h0;
cpu_mon_last_reg <= 32'h0;
ram_addr_rand_reg <= 15'h0;
ram_data_rand_reg <= 32'h0;
force_trap_reg <= 1'h0;
system_reset_reg <= 1'h0;
system_mode_reg <= 1'h0;
rom_executable_reg <= 1'h1;
led_reg <= 3'h6;
gpio1_reg <= 2'h0;
gpio2_reg <= 2'h0;
gpio3_reg <= 1'h0;
gpio4_reg <= 1'h0;
app_start_reg <= 32'h0;
app_size_reg <= 32'h0;
blake2s_addr_reg <= ILLEGAL_ADDR;
syscall_addr_reg <= ILLEGAL_ADDR;
cdi_mem[0] <= 32'h0;
cdi_mem[1] <= 32'h0;
cdi_mem[2] <= 32'h0;
cdi_mem[3] <= 32'h0;
cdi_mem[4] <= 32'h0;
cdi_mem[5] <= 32'h0;
cdi_mem[6] <= 32'h0;
cdi_mem[7] <= 32'h0;
cpu_trap_ctr_reg <= 24'h0;
cpu_trap_led_reg <= 3'h0;
cpu_mon_en_reg <= 1'h0;
cpu_mon_first_reg <= 32'h0;
cpu_mon_last_reg <= 32'h0;
ram_addr_rand_reg <= 15'h0;
ram_data_rand_reg <= 32'h0;
force_trap_reg <= 1'h0;
system_reset_reg <= 1'h0;
end

else begin
Expand All @@ -302,6 +307,10 @@ module tk1 (
system_mode_reg <= system_mode_new;
end

if (rom_executable_we) begin
rom_executable_reg <= rom_executable_new;
end

if (led_we) begin
led_reg <= write_data[2 : 0];
end
Expand Down Expand Up @@ -398,6 +407,13 @@ module tk1 (
//
// Trying to execute instructions in FW-RAM.
//
// Executing instructions in ROM, while ROM is marked as not
// executable. Note that there is an exception, if the cpu_addr is
// the first instruction in either functions set in syscall_addr_reg
// or blake2s_addr_reg, it is allowed. For the next instruction ROM
// will be marked as executable.
// Note that the address to the functions needs to be 4-bytes aligned.
//
// Trying to execute code in mem area set to be data access only.
// This requires execution monitor to have been setup and
// enabled.
Expand All @@ -415,6 +431,14 @@ module tk1 (
force_trap_set = 1'h1;
end

if (!rom_executable_reg) begin
if ((cpu_addr != syscall_addr_reg) && (cpu_addr != blake2s_addr_reg)) 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
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;
Expand All @@ -425,24 +449,43 @@ module tk1 (
end

//----------------------------------------------------------------
// system_mode_ctrl will raise the privilege when the function in
// `syscall_addr_reg` is called.
// system_mode_ctrl dynamically sets the system mode and if ROM is
// executable depending on where we are currently executing.
//
// If the function in `syscall_addr_reg` is called system_mode will
// be set to firmware mode, and ROM will be marked as executable.
//
// If the function in `blake2s_addr_reg` is called only ROM will be
// marked as executable.
//
// Automatically lowers the privilege when executing above ROM
// Automatically lowers the privilege and removes ROM execution when
// executing above ROM.
//
// Note that the address to the functions needs to be 4-bytes aligned.
// ----------------------------------------------------------------
always @* begin : system_mode_ctrl
system_mode_new = 1'h0;
system_mode_we = 1'h0;
system_mode_new = 1'h0;
system_mode_we = 1'h0;
rom_executable_new = 1'h0;
rom_executable_we = 1'h0;

if (cpu_valid & cpu_instr) begin
if (cpu_addr == syscall_addr_reg) begin
system_mode_new = 1'h0;
system_mode_we = 1'h1;
system_mode_new = 1'h0;
system_mode_we = 1'h1;
rom_executable_new = 1'h1;
rom_executable_we = 1'h1;
end
if (cpu_addr == blake2s_addr_reg) begin
rom_executable_new = 1'h1;
rom_executable_we = 1'h1;
end

if (cpu_addr > FW_ROM_LAST) begin
system_mode_new = 1'h1;
system_mode_we = 1'h1;
system_mode_new = 1'h1;
system_mode_we = 1'h1;
rom_executable_new = 1'h0;
rom_executable_we = 1'h1;
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion hw/application_fpga/fw/tk1/blake2s/blake2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ void blake2s_final(blake2s_ctx *ctx, void *out)
//------------------------------------------------------------------
// Convenience function for all-in-one computation.
//------------------------------------------------------------------
int blake2s(void *out, size_t outlen,
int __attribute__((aligned(4))) blake2s(void *out, size_t outlen,
const void *key, size_t keylen,
const void *in, size_t inlen,
blake2s_ctx *ctx)
Expand Down

0 comments on commit c246850

Please sign in to comment.