From e8762d80fc05e268da76d0c29c9aec1c86309407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Str=C3=B6mbergson?= Date: Thu, 29 Aug 2024 13:53:46 +0200 Subject: [PATCH 1/2] (fpga) First attempt at PoC of HW trampoline for syscall. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a first attempt at adding a HW based syscall trampoline. Basicallt the FW can set a fixed address in a register in the API. The app can write an API adress. When written the HW will (should) force the CPU to read the instruction pointed to by the address set by the FW. This probably doesn't work. One problem is probably timing (cycles between writing the API and loading of the next instruction). We need to try. Signed-off-by: Joachim Strömbergson --- hw/application_fpga/core/tk1/rtl/tk1.v | 31 ++++++++++++++++++++++ hw/application_fpga/rtl/application_fpga.v | 19 ++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index fe9c243e..488316ce 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -26,6 +26,9 @@ module tk1( output wire force_trap, output system_reset, + output wire [31 : 0] syscall_addr, + output wire syscall, + output wire [14 : 0] ram_addr_rand, output wire [31 : 0] ram_data_rand, @@ -81,6 +84,9 @@ module tk1( localparam ADDR_BLAKE2S = 8'h10; + localparam ADDR_SYSCALL_ADDR = 8'h12; + localparam ADDR_SYSCALL_START = 8'h13; + localparam ADDR_CDI_FIRST = 8'h20; localparam ADDR_CDI_LAST = 8'h27; @@ -138,6 +144,9 @@ module tk1( reg [31 : 0] blake2s_addr_reg; reg blake2s_addr_we; + reg [31 : 0] syscall_addr_reg; + reg syscall_addr_we; + reg [23 : 0] cpu_trap_ctr_reg; reg [23 : 0] cpu_trap_ctr_new; reg [2 : 0] cpu_trap_led_reg; @@ -175,6 +184,8 @@ module tk1( wire [31:0] udi_rdata; + reg start_syscall; + `ifdef INCLUDE_SPI_MASTER reg spi_enable; reg spi_enable_vld; @@ -204,6 +215,9 @@ module tk1( assign system_reset = system_reset_reg; + assign syscall_addr = syscall_addr_reg; + assign syscall = start_syscall; + //---------------------------------------------------------------- // Module instance. @@ -268,6 +282,7 @@ module tk1( app_start_reg <= 32'h0; app_size_reg <= 32'h0; blake2s_addr_reg <= 32'h0; + syscall_addr_reg <= 32'h0; cdi_mem[0] <= 32'h0; cdi_mem[1] <= 32'h0; cdi_mem[2] <= 32'h0; @@ -326,6 +341,10 @@ module tk1( blake2s_addr_reg <= write_data; end + if (syscall_addr_we) begin + syscall_addr_reg <= write_data; + end + if (cdi_mem_we) begin cdi_mem[address[2 : 0]] <= write_data; end @@ -436,6 +455,8 @@ module tk1( app_start_we = 1'h0; app_size_we = 1'h0; blake2s_addr_we = 1'h0; + syscall_addr_we = 1'h0; + start_syscall = 1'h0; cdi_mem_we = 1'h0; cdi_mem_we = 1'h0; ram_addr_rand_we = 1'h0; @@ -495,6 +516,16 @@ module tk1( end end + if (address == ADDR_SYSCALL_ADDR) begin + if (!switch_app_reg) begin + syscall_addr_we = 1'h1; + end + end + + if (address == ADDR_SYSCALL_START) begin + start_syscall = 1'h1; + end + if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin if (!switch_app_reg) begin cdi_mem_we = 1'h1; diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 92c91f0c..c783cacb 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -149,6 +149,8 @@ module application_fpga( wire [14 : 0] ram_addr_rand; wire [31 : 0] ram_data_rand; wire tk1_system_reset; + wire [31 : 0] tk1_syscall_addr; + wire tk1_syscall; /* verilator lint_on UNOPTFLAT */ @@ -328,6 +330,9 @@ module application_fpga( .system_reset(tk1_system_reset), + .syscall_addr(tk1_syscall_addr), + .syscall(tk1_syscall), + .ram_addr_rand(ram_addr_rand), .ram_data_rand(ram_data_rand), @@ -443,10 +448,16 @@ module application_fpga( end RAM_PREFIX: begin - ram_cs = 1'h1; - ram_we = cpu_wstrb; - muxed_rdata_new = ram_read_data ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}}; - muxed_ready_new = ram_ready; + if (tk1_syscall) begin + muxed_rdata_new = tk1_syscall_addr; + muxed_ready_new = 1'h1; + end + else begin + ram_cs = 1'h1; + ram_we = cpu_wstrb; + muxed_rdata_new = ram_read_data ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}}; + muxed_ready_new = ram_ready; + end end RESERVED_PREFIX: begin From fe8350422f61fe20cfff1b0cedca7ce7d7324d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Str=C3=B6mbergson?= Date: Thu, 29 Aug 2024 15:02:04 +0200 Subject: [PATCH 2/2] (fpga) Possibly working syscall hw functionality. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't want to set which address the CPU should jump to when a syscall is made, we want to push the jump instruction to execute. If that works. Signed-off-by: Joachim Strömbergson --- hw/application_fpga/core/tk1/rtl/tk1.v | 33 +++++++++++++--------- hw/application_fpga/rtl/application_fpga.v | 24 ++++++++-------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index 488316ce..4e22ce15 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -26,7 +26,7 @@ module tk1( output wire force_trap, output system_reset, - output wire [31 : 0] syscall_addr, + output wire [31 : 0] syscall_instr, output wire syscall, output wire [14 : 0] ram_addr_rand, @@ -84,7 +84,7 @@ module tk1( localparam ADDR_BLAKE2S = 8'h10; - localparam ADDR_SYSCALL_ADDR = 8'h12; + localparam ADDR_SYSCALL_INSTR = 8'h12; localparam ADDR_SYSCALL_START = 8'h13; localparam ADDR_CDI_FIRST = 8'h20; @@ -144,8 +144,11 @@ module tk1( reg [31 : 0] blake2s_addr_reg; reg blake2s_addr_we; - reg [31 : 0] syscall_addr_reg; - reg syscall_addr_we; + reg [31 : 0] syscall_instr_reg; + reg syscall_instr_we; + + reg syscall_reg; + reg syscall_new; reg [23 : 0] cpu_trap_ctr_reg; reg [23 : 0] cpu_trap_ctr_new; @@ -215,8 +218,8 @@ module tk1( assign system_reset = system_reset_reg; - assign syscall_addr = syscall_addr_reg; - assign syscall = start_syscall; + assign syscall_instr = syscall_instr_reg; + assign syscall = syscall_reg; //---------------------------------------------------------------- @@ -282,7 +285,8 @@ module tk1( app_start_reg <= 32'h0; app_size_reg <= 32'h0; blake2s_addr_reg <= 32'h0; - syscall_addr_reg <= 32'h0; + syscall_instr_reg <= 32'h0; + syscall_reg <= 1'h0; cdi_mem[0] <= 32'h0; cdi_mem[1] <= 32'h0; cdi_mem[2] <= 32'h0; @@ -306,6 +310,7 @@ module tk1( cpu_trap_ctr_reg <= cpu_trap_ctr_new; system_reset_reg <= system_reset_new; + syscall_reg <= syscall_new; gpio1_reg[0] <= gpio1; gpio1_reg[1] <= gpio1_reg[0]; @@ -341,8 +346,8 @@ module tk1( blake2s_addr_reg <= write_data; end - if (syscall_addr_we) begin - syscall_addr_reg <= write_data; + if (syscall_instr_we) begin + syscall_instr_reg <= write_data; end if (cdi_mem_we) begin @@ -455,8 +460,8 @@ module tk1( app_start_we = 1'h0; app_size_we = 1'h0; blake2s_addr_we = 1'h0; - syscall_addr_we = 1'h0; - start_syscall = 1'h0; + syscall_instr_we = 1'h0; + syscall_new = 1'h0; cdi_mem_we = 1'h0; cdi_mem_we = 1'h0; ram_addr_rand_we = 1'h0; @@ -516,14 +521,14 @@ module tk1( end end - if (address == ADDR_SYSCALL_ADDR) begin + if (address == ADDR_SYSCALL_INSTR) begin if (!switch_app_reg) begin - syscall_addr_we = 1'h1; + syscall_instr_we = 1'h1; end end if (address == ADDR_SYSCALL_START) begin - start_syscall = 1'h1; + syscall_new = 1'h1; end if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index c783cacb..06b633ab 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -149,7 +149,7 @@ module application_fpga( wire [14 : 0] ram_addr_rand; wire [31 : 0] ram_data_rand; wire tk1_system_reset; - wire [31 : 0] tk1_syscall_addr; + wire [31 : 0] tk1_syscall_instr; wire tk1_syscall; /* verilator lint_on UNOPTFLAT */ @@ -330,7 +330,7 @@ module application_fpga( .system_reset(tk1_system_reset), - .syscall_addr(tk1_syscall_addr), + .syscall_instr(tk1_syscall_instr), .syscall(tk1_syscall), .ram_addr_rand(ram_addr_rand), @@ -439,6 +439,12 @@ module application_fpga( muxed_rdata_new = ILLEGAL_INSTRUCTION; muxed_ready_new = 1'h1; end + + else if (tk1_syscall) begin + muxed_rdata_new = tk1_syscall_instr; + muxed_ready_new = 1'h1; + end + else begin case (area_prefix) ROM_PREFIX: begin @@ -448,16 +454,10 @@ module application_fpga( end RAM_PREFIX: begin - if (tk1_syscall) begin - muxed_rdata_new = tk1_syscall_addr; - muxed_ready_new = 1'h1; - end - else begin - ram_cs = 1'h1; - ram_we = cpu_wstrb; - muxed_rdata_new = ram_read_data ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}}; - muxed_ready_new = ram_ready; - end + ram_cs = 1'h1; + ram_we = cpu_wstrb; + muxed_rdata_new = ram_read_data ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}}; + muxed_ready_new = ram_ready; end RESERVED_PREFIX: begin