Skip to content

Commit

Permalink
Move reset control and status into the tk1 core
Browse files Browse the repository at this point in the history
The tk1 core is now able to handle external and internal reset
request, trigger a system and store reset status that persists
the reset. The reset status is exposed to SW as bits 17..16 in the
FW_APP register. The fw_app status is now bound to bit 0.

Signed-off-by: Joachim Str枚mbergson <joachim@assured.se>
  • Loading branch information
secworks authored and mchack-work committed Apr 22, 2024
1 parent 16eba3b commit bd45d3b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 34 deletions.
106 changes: 80 additions & 26 deletions hw/application_fpga/core/tk1/rtl/tk1.v
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ module tk1(
output wire [14 : 0] ram_aslr,
output wire [31 : 0] ram_scramble,

input wire external_reset,
output wire sys_reset,

output wire led_r,
output wire led_g,
output wire led_b,
Expand Down Expand Up @@ -144,6 +147,15 @@ module tk1(
reg force_trap_reg;
reg force_trap_set;

reg [1 : 0] external_reset_sample_reg = 2'h0;
reg [1 : 0] external_reset_sample_new;
reg sys_reset_reg;
reg sys_reset_we;

reg [1 : 0] reset_status_reg = 2'h0;
reg [1 : 0] reset_status_new;
reg reset_status_we;


//----------------------------------------------------------------
// Wires.
Expand Down Expand Up @@ -173,6 +185,8 @@ module tk1(
assign ram_aslr = ram_aslr_reg;
assign ram_scramble = ram_scramble_reg;

assign sys_reset = sys_reset_reg;


//----------------------------------------------------------------
// Module instance.
Expand Down Expand Up @@ -204,35 +218,40 @@ module tk1(

//----------------------------------------------------------------
// reg_update
//
// Note that the reset_status_reg is not reset, since that would
// erase the status info we want to persist between reboots.
//----------------------------------------------------------------
always @ (posedge clk)
begin : reg_update
if (!reset_n) begin
switch_app_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;
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_aslr_reg <= 15'h0;
ram_scramble_reg <= 32'h0;
force_trap_reg <= 1'h0;
switch_app_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;
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_aslr_reg <= 15'h0;
ram_scramble_reg <= 32'h0;
force_trap_reg <= 1'h0;
sys_reset_reg <= 1'h0;
external_reset_sample_reg <= 2'h0;
end

else begin
Expand All @@ -244,6 +263,17 @@ module tk1(
gpio2_reg[0] <= gpio2;
gpio2_reg[1] <= gpio2_reg[0];

external_reset_sample_reg <= external_reset_sample_new;


if (sys_reset_we) begin
sys_reset_reg <= 1'h1;
end

if (reset_status_we) begin
reset_status_reg <= reset_status_new;
end

if (switch_app_we) begin
switch_app_reg <= 1'h1;
end
Expand Down Expand Up @@ -330,6 +360,30 @@ module tk1(
end


//----------------------------------------------------------------
// system_reset_logic
//
// Sample the external reset request input. If it is set, we
// assert the sys_reset signal and sets the reset status reg
// to indicate that the reset was caused by external request.
// When the reset happens the sys_reset_reg will be cleared.
//----------------------------------------------------------------
always @*
begin : system_reset_logic
sys_reset_we = 1'h0;
reset_status_new = 2'h0;
reset_status_we = 1'h0;

external_reset_sample_new = {external_reset_sample_reg[0], external_reset};

if (external_reset_sample_reg[1]) begin
sys_reset_we = 1'h1;
reset_status_new = 2'h1;
reset_status_we = 1'h1;
end
end


//----------------------------------------------------------------
// security_monitor
//
Expand Down Expand Up @@ -476,7 +530,7 @@ module tk1(
end

if (address == ADDR_SWITCH_APP) begin
tmp_read_data = {32{switch_app_reg}};
tmp_read_data = {14'h0, reset_status_reg, 15'h0, switch_app_reg};
end

if (address == ADDR_LED) begin
Expand Down
6 changes: 5 additions & 1 deletion hw/application_fpga/rtl/application_fpga.v
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ module application_fpga(
wire force_trap;
wire [14 : 0] ram_aslr;
wire [31 : 0] ram_scramble;
wire tk1_sys_reset;
/* verilator lint_on UNOPTFLAT */


Expand All @@ -150,7 +151,7 @@ module application_fpga(
//----------------------------------------------------------------
clk_reset_gen #(.RESET_CYCLES(200))
reset_gen_inst(
.host_reset(interface_rts),
.sys_reset(tk1_sys_reset),
.clk(clk),
.rst_n(reset_n)
);
Expand Down Expand Up @@ -322,6 +323,9 @@ module application_fpga(
.ram_aslr(ram_aslr),
.ram_scramble(ram_scramble),

.external_reset(interface_rts),
.sys_reset(tk1_sys_reset),

.led_r(led_r),
.led_g(led_g),
.led_b(led_b),
Expand Down
14 changes: 7 additions & 7 deletions hw/application_fpga/rtl/clk_reset_gen.v
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

module clk_reset_gen #(parameter RESET_CYCLES = 200)
(
input wire host_reset,
input wire sys_reset,
output wire clk,
output wire rst_n
);
Expand All @@ -37,7 +37,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
reg rst_n_reg = 1'h0;
reg rst_n_new;

reg [1 : 0] host_reset_sample_reg = 2'h0;
reg sys_reset_reg;

wire hfosc_clk;
wire pll_clk;
Expand Down Expand Up @@ -102,8 +102,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
//----------------------------------------------------------------
always @(posedge clk)
begin : reg_update
rst_n_reg <= rst_n_new;
host_reset_sample_reg <= {host_reset_sample_reg[0], host_reset};
rst_n_reg <= rst_n_new;
sys_reset_reg <= sys_reset;

if (rst_ctr_we)
rst_ctr_reg <= rst_ctr_new;
Expand All @@ -118,8 +118,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
// logic is active, and the reset is being asserted for
// RESET_CYCLES. Then the default reset reg value is applied.
//
// When a second reset is requested from the host we
// reset the counter. This activates the counter logic.
// When a system reset is requested we reset the counter.
// This activates the counter logic and the reset is asserted.
//----------------------------------------------------------------
always @*
begin : rst_logic
Expand All @@ -133,7 +133,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
rst_ctr_we = 1'h1;
end

if (host_reset_sample_reg[1]) begin
if (sys_reset_reg) begin
rst_ctr_new = 8'h0;
rst_ctr_we = 1'h1;
end
Expand Down

0 comments on commit bd45d3b

Please sign in to comment.