FPGA: Add SPI access control logic

Access logic looks at instruction execution from a defined
      trampoline address to enable stateful SPI access.

      The access is disabled as soon as an instruction is executed
      from any address in RAM.

Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2024-06-24 15:13:10 +02:00 committed by Daniel Jobson
parent a42a0252e5
commit 4511096630
No known key found for this signature in database
GPG Key ID: 3707A9DBF4BB8F1A
2 changed files with 112 additions and 32 deletions

View File

@ -100,6 +100,7 @@ module tk1(
localparam ADDR_SPI_EN = 8'h80; localparam ADDR_SPI_EN = 8'h80;
localparam ADDR_SPI_XFER = 8'h81; localparam ADDR_SPI_XFER = 8'h81;
localparam ADDR_SPI_DATA = 8'h82; localparam ADDR_SPI_DATA = 8'h82;
localparam ADDR_SPI_CMD = 8'h83;
`endif // INCLUDE_SPI_MASTER `endif // INCLUDE_SPI_MASTER
localparam TK1_NAME0 = 32'h746B3120; // "tk1 " localparam TK1_NAME0 = 32'h746B3120; // "tk1 "
@ -109,6 +110,10 @@ module tk1(
localparam FW_RAM_FIRST = 32'hd0000000; localparam FW_RAM_FIRST = 32'hd0000000;
localparam FW_RAM_LAST = 32'hd00007ff; localparam FW_RAM_LAST = 32'hd00007ff;
`ifdef INCLUDE_SPI_MASTER
localparam RAM_PREFIX = 2'h1;
`endif // INCLUDE_SPI_MASTER
//---------------------------------------------------------------- //----------------------------------------------------------------
// Registers including update variables and write enable. // Registers including update variables and write enable.
@ -162,6 +167,15 @@ module tk1(
reg force_trap_reg; reg force_trap_reg;
reg force_trap_set; reg force_trap_set;
`ifdef INCLUDE_SPI_MASTER
reg [31 : 0] spi_cmd_addr_reg;
reg spi_cmd_addr_we;
reg spi_access_ctrl_reg;
reg spi_access_ctrl_new;
reg spi_access_ctrl_we;
`endif // INCLUDE_SPI_MASTER
//---------------------------------------------------------------- //----------------------------------------------------------------
// Wires. // Wires.
@ -259,32 +273,37 @@ module tk1(
always @ (posedge clk) always @ (posedge clk)
begin : reg_update begin : reg_update
if (!reset_n) begin if (!reset_n) begin
switch_app_reg <= 1'h0; switch_app_reg <= 1'h0;
led_reg <= 3'h6; led_reg <= 3'h6;
gpio1_reg <= 2'h0; gpio1_reg <= 2'h0;
gpio2_reg <= 2'h0; gpio2_reg <= 2'h0;
gpio3_reg <= 1'h0; gpio3_reg <= 1'h0;
gpio4_reg <= 1'h0; gpio4_reg <= 1'h0;
app_start_reg <= 32'h0; app_start_reg <= 32'h0;
app_size_reg <= 32'h0; app_size_reg <= 32'h0;
blake2s_addr_reg <= 32'h0; blake2s_addr_reg <= 32'h0;
cdi_mem[0] <= 32'h0; cdi_mem[0] <= 32'h0;
cdi_mem[1] <= 32'h0; cdi_mem[1] <= 32'h0;
cdi_mem[2] <= 32'h0; cdi_mem[2] <= 32'h0;
cdi_mem[3] <= 32'h0; cdi_mem[3] <= 32'h0;
cdi_mem[4] <= 32'h0; cdi_mem[4] <= 32'h0;
cdi_mem[5] <= 32'h0; cdi_mem[5] <= 32'h0;
cdi_mem[6] <= 32'h0; cdi_mem[6] <= 32'h0;
cdi_mem[7] <= 32'h0; cdi_mem[7] <= 32'h0;
cpu_trap_ctr_reg <= 24'h0; cpu_trap_ctr_reg <= 24'h0;
cpu_trap_led_reg <= 3'h0; cpu_trap_led_reg <= 3'h0;
cpu_mon_en_reg <= 1'h0; cpu_mon_en_reg <= 1'h0;
cpu_mon_first_reg <= 32'h0; cpu_mon_first_reg <= 32'h0;
cpu_mon_last_reg <= 32'h0; cpu_mon_last_reg <= 32'h0;
ram_addr_rand_reg <= 15'h0; ram_addr_rand_reg <= 15'h0;
ram_data_rand_reg <= 32'h0; ram_data_rand_reg <= 32'h0;
force_trap_reg <= 1'h0; force_trap_reg <= 1'h0;
system_reset_reg <= 1'h0; system_reset_reg <= 1'h0;
`ifdef INCLUDE_SPI_MASTER
spi_cmd_addr_reg <= 32'h0;
spi_access_ctrl_reg <= 1'h0;
`endif // INCLUDE_SPI_MASTER
end end
else begin else begin
@ -357,6 +376,17 @@ module tk1(
if (force_trap_set) begin if (force_trap_set) begin
force_trap_reg <= 1'h1; force_trap_reg <= 1'h1;
end end
`ifdef INCLUDE_SPI_MASTER
if (spi_cmd_addr_we) begin
spi_cmd_addr_reg <= write_data;
end
if (spi_access_ctrl_we) begin
spi_access_ctrl_reg <= spi_access_ctrl_new;
end
`endif // INCLUDE_SPI_MASTER
end end
end // reg_update end // reg_update
@ -424,6 +454,39 @@ module tk1(
end end
`ifdef INCLUDE_SPI_MASTER
//----------------------------------------------------------------
// spi_access_ctrl
//
// Logic that implements the detection of a SPI command trampoline
// event, when the CPU reads an instruction from the specified
// SPI command handler FW entry point. When that happens SPI
// access is enabled.
//
// The logic also handles the event when the SPI access control
// API is written to. WHen that happens SPI access is
// disabled.
//----------------------------------------------------------------
always @*
begin : spi_access_ctrl
spi_access_ctrl_new = 1'h0;
spi_access_ctrl_we = 1'h0;
if (cpu_valid & cpu_instr) begin
if (cpu_addr == spi_cmd_addr_reg) begin
spi_access_ctrl_new = 1'h1;
spi_access_ctrl_we = 1'h1;
end
if (cpu_addr[31 : 30] == RAM_PREFIX) begin
spi_access_ctrl_new = 1'h0;
spi_access_ctrl_we = 1'h1;
end
end
end
`endif // INCLUDE_SPI_MASTER
//---------------------------------------------------------------- //----------------------------------------------------------------
// api // api
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -449,12 +512,14 @@ module tk1(
tmp_ready = 1'h0; tmp_ready = 1'h0;
`ifdef INCLUDE_SPI_MASTER `ifdef INCLUDE_SPI_MASTER
spi_cmd_addr_we = 1'h0;
spi_enable_vld = 1'h0; spi_enable_vld = 1'h0;
spi_start = 1'h0; spi_start = 1'h0;
spi_tx_data_vld = 1'h0; spi_tx_data_vld = 1'h0;
spi_enable = write_data[0]; spi_enable = write_data[0] & spi_access_ctrl_reg;
spi_tx_data = write_data[7 : 0]; spi_tx_data = write_data[7 : 0] & {8{spi_access_ctrl_reg}};
`endif // INCLUDE_SPI_MASTER `endif // INCLUDE_SPI_MASTER
if (cs) begin if (cs) begin
@ -531,15 +596,21 @@ module tk1(
`ifdef INCLUDE_SPI_MASTER `ifdef INCLUDE_SPI_MASTER
if (address == ADDR_SPI_EN) begin if (address == ADDR_SPI_EN) begin
spi_enable_vld = 1'h1; spi_enable_vld = spi_access_ctrl_reg;
end end
if (address == ADDR_SPI_XFER) begin if (address == ADDR_SPI_XFER) begin
spi_start = 1'h1; spi_start = spi_access_ctrl_reg;
end end
if (address == ADDR_SPI_DATA) begin if (address == ADDR_SPI_DATA) begin
spi_tx_data_vld = 1'h1; spi_tx_data_vld = spi_access_ctrl_reg;
end
if (address == ADDR_SPI_CMD) begin
if (!switch_app_reg) begin
spi_cmd_addr_we = 1'h1;
end
end end
`endif // INCLUDE_SPI_MASTER `endif // INCLUDE_SPI_MASTER
@ -594,12 +665,20 @@ module tk1(
`ifdef INCLUDE_SPI_MASTER `ifdef INCLUDE_SPI_MASTER
if (address == ADDR_SPI_XFER) begin if (address == ADDR_SPI_XFER) begin
if (spi_access_ctrl_reg) begin
tmp_read_data[0] = spi_ready; tmp_read_data[0] = spi_ready;
end
end end
if (address == ADDR_SPI_DATA) begin if (address == ADDR_SPI_DATA) begin
tmp_read_data[7 : 0] = spi_rx_data; if (spi_access_ctrl_reg) begin
tmp_read_data[7 : 0] = spi_rx_data;
end
end end
if (address == ADDR_SPI_CMD) begin
tmp_read_data = spi_cmd_addr_reg;
end
`endif // INCLUDE_SPI_MASTER `endif // INCLUDE_SPI_MASTER
end end

View File

@ -149,4 +149,5 @@
#define TK1_MMIO_TK1_SPI_EN 0xff000200 #define TK1_MMIO_TK1_SPI_EN 0xff000200
#define TK1_MMIO_TK1_SPI_XFER 0xff000204 #define TK1_MMIO_TK1_SPI_XFER 0xff000204
#define TK1_MMIO_TK1_SPI_DATA 0xff000208 #define TK1_MMIO_TK1_SPI_DATA 0xff000208
#define TK1_MMIO_TK1_SPI_CMD 0xff00020c
#endif #endif