From 3c74f93184b163dfa3380f066146e3e41c6ca387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Th=C3=B6rnblad?= Date: Wed, 19 Feb 2025 16:45:05 +0100 Subject: [PATCH] fpga/fw: Resize ROM and FW_RAM, add RESETINFO partition In order to be able to leave data for firmware signalling the intention with a reset or to leave data for the next app in a chain of apps, we introduce a part of FW_RAM that can be used to store this data. In order to do this, we: - Change size of ROM from 6 KB to 8 KB. - Change size of FW_RAM, from 2 KB to 4 KB. - Add RESETINFO memory partition inside FW_RAM. - Add generation of map file. - Change CFLAGS from using -O2 to using -Os. - Update address ranges for valid access to ROM and FW_RAM. - Move stack to be located before data+bss and the RESETINFO data above them. This also means we introduce hardware stack overflow protection through the Security Monitor. - Revise firmware README to the new use of FW_RAM. --- hw/application_fpga/Makefile | 30 +-- .../application_fpga.bin.sha256 | 2 +- hw/application_fpga/core/fw_ram/rtl/fw_ram.v | 235 ++++++++++++++++-- hw/application_fpga/core/tk1/rtl/tk1.v | 6 +- hw/application_fpga/firmware.bin.sha512 | 2 +- hw/application_fpga/fw/README.md | 20 +- hw/application_fpga/fw/testfw/main.c | 2 +- hw/application_fpga/fw/tk1/firmware.lds | 44 ++-- hw/application_fpga/fw/tk1/main.c | 4 +- hw/application_fpga/fw/tk1/start.S | 19 +- hw/application_fpga/fw/tk1_mem.h | 6 +- hw/application_fpga/rtl/application_fpga.v | 8 +- hw/application_fpga/tb/application_fpga_sim.v | 8 +- 13 files changed, 309 insertions(+), 77 deletions(-) diff --git a/hw/application_fpga/Makefile b/hw/application_fpga/Makefile index 61c9f0d..09e1f84 100644 --- a/hw/application_fpga/Makefile +++ b/hw/application_fpga/Makefile @@ -32,7 +32,7 @@ TARGET_FREQ ?= 24 # Size in 32-bit words, must be divisible by 256 (pairs of EBRs, because 16 # bits wide; an EBR is 128 32-bits words) -BRAM_FW_SIZE ?= 1536 +BRAM_FW_SIZE ?= 2048 PIN_FILE ?= application_fpga_tk1.pcf @@ -47,7 +47,7 @@ CFLAGS = \ -mabi=ilp32 \ -static \ -std=gnu99 \ - -O2 \ + -Os \ -ffast-math \ -fno-common \ -fno-builtin-printf \ @@ -156,7 +156,10 @@ all: application_fpga.bin # incorrect BRAM_FW_SIZE # ------------------------------------------------------------------- %_size_mismatch: %.elf phony_explicit - @test $$($(SIZE) $< | awk 'NR==2{print $$4}') -le $$(( 32 / 8 * $(BRAM_FW_SIZE) )) \ + @test $$(( \ + $$($(SIZE) -A $< | grep text | awk 'NR==1{print $$2}') + \ + $$($(SIZE) -A $< | grep text | awk 'NR==2{print $$2}') \ + )) -le $$(( 32 / 8 * $(BRAM_FW_SIZE) )) \ || { printf "The 'BRAM_FW_SIZE' variable needs to be increased\n"; \ [[ $< =~ testfw ]] && printf "Note that testfw fits if built with -Os\n"; \ false; } @@ -177,17 +180,19 @@ secret: # Firmware generation. # Included in the bitstream. #------------------------------------------------------------------- -LDFLAGS = -T $(P)/fw/tk1/firmware.lds +LDFLAGS = \ + -T $(P)/fw/tk1/firmware.lds \ + -Wl,--cref,-M $(FIRMWARE_OBJS): $(FIRMWARE_DEPS) $(TESTFW_OBJS): $(FIRMWARE_DEPS) firmware.elf: $(FIRMWARE_OBJS) $(P)/fw/tk1/firmware.lds - $(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@ + $(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@ > $(basename $@).map simfirmware.elf: CFLAGS += -DSIMULATION simfirmware.elf: $(FIRMWARE_OBJS) $(P)/fw/tk1/firmware.lds - $(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@ + $(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@ > $(basename $@).map qemu_firmware.elf: CFLAGS += -DQEMU_CONSOLE qemu_firmware.elf: firmware.elf @@ -221,7 +226,7 @@ splint: $(FIRMWARE_SOURCES) testfw.elf: $(TESTFW_OBJS) $(P)/fw/tk1/firmware.lds - $(CC) $(CFLAGS) $(TESTFW_OBJS) $(LDFLAGS) -o $@ + $(CC) $(CFLAGS) $(TESTFW_OBJS) $(LDFLAGS) -o $@ > $(basename $@).map # Generate a fake BRAM file that will be filled in later after place-n-route bram_fw.hex: @@ -242,9 +247,6 @@ check-binary-hashes: sha256sum -c application_fpga.bin.sha256 %.bin: %.elf - $(SIZE) $< - @test "$$($(SIZE) $< | awk 'NR==2{print $$2, $$3}')" = "0 0" \ - || { printf "Non-empty data or bss section!\n"; false; } $(OBJCOPY) --input-target=elf32-littleriscv --output-target=binary $< $@ chmod -x $@ @@ -371,7 +373,7 @@ synth.json: $(FPGA_VERILOG_SRCS) $(VERILOG_SRCS) $(PICORV32_SRCS) bram_fw.hex application_fpga_par.json: synth.json $(P)/data/$(PIN_FILE) $(NEXTPNR_PATH)nextpnr-ice40 \ -l application_fpga_par.txt \ - --seed 9106179903728618585 \ + --seed 16549106670644347421 \ --freq $(TARGET_FREQ) \ --ignore-loops \ --up5k \ @@ -484,15 +486,15 @@ clean: clean_sim clean_fw clean_tb .PHONY: clean clean_fw: - rm -f firmware.{elf,elf.map,bin,hex} + rm -f firmware.{elf,map,bin,hex} rm -f $(FIRMWARE_OBJS) - rm -f testfw.{elf,elf.map,bin,hex} + rm -f testfw.{elf,map,bin,hex} rm -f $(TESTFW_OBJS) rm -f qemu_firmware.elf .PHONY: clean_fw clean_sim: - rm -f simfirmware.{elf,elf.map,bin,hex} + rm -f simfirmware.{elf,map,bin,hex} rm -f tb_application_fpga_sim.fst rm -f tb_application_fpga_sim.fst.hier rm -f tb/output_spram*.hex diff --git a/hw/application_fpga/application_fpga.bin.sha256 b/hw/application_fpga/application_fpga.bin.sha256 index 8182449..52e28c3 100644 --- a/hw/application_fpga/application_fpga.bin.sha256 +++ b/hw/application_fpga/application_fpga.bin.sha256 @@ -1 +1 @@ -93e311e4bfa7e2f8c3c89f194b5fbe7b83eff81e6d32fd73c8859d5d76324b48 application_fpga.bin +5287588b9929a5709859e5fd85cc585dda6524821740bd06829258be7e9fad7d application_fpga.bin diff --git a/hw/application_fpga/core/fw_ram/rtl/fw_ram.v b/hw/application_fpga/core/fw_ram/rtl/fw_ram.v index 150f6b5..7ff7103 100644 --- a/hw/application_fpga/core/fw_ram/rtl/fw_ram.v +++ b/hw/application_fpga/core/fw_ram/rtl/fw_ram.v @@ -21,7 +21,7 @@ module fw_ram ( input wire cs, input wire [ 3 : 0] we, - input wire [ 8 : 0] address, + input wire [ 9 : 0] address, input wire [31 : 0] write_data, output wire [31 : 0] read_data, output wire ready @@ -34,10 +34,14 @@ module fw_ram ( reg [31 : 0] tmp_read_data; reg [31 : 0] mem_read_data0; reg [31 : 0] mem_read_data1; + reg [31 : 0] mem_read_data2; + reg [31 : 0] mem_read_data3; reg ready_reg; wire system_mode_cs; reg bank0; reg bank1; + reg bank2; + reg bank3; //---------------------------------------------------------------- @@ -51,7 +55,24 @@ module fw_ram ( //---------------------------------------------------------------- // Block RAM instances. //---------------------------------------------------------------- - SB_RAM40_4K fw_ram0_0 ( + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram0_0 ( .RDATA(mem_read_data0[15 : 0]), .RADDR({3'h0, address[7 : 0]}), .RCLK(clk), @@ -65,7 +86,24 @@ module fw_ram ( .MASK({{8{~we[1]}}, {8{~we[0]}}}) ); - SB_RAM40_4K fw_ram0_1 ( + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram0_1 ( .RDATA(mem_read_data0[31 : 16]), .RADDR({3'h0, address[7 : 0]}), .RCLK(clk), @@ -79,8 +117,24 @@ module fw_ram ( .MASK({{8{~we[3]}}, {8{~we[2]}}}) ); - - SB_RAM40_4K fw_ram1_0 ( + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram1_0 ( .RDATA(mem_read_data1[15 : 0]), .RADDR({3'h0, address[7 : 0]}), .RCLK(clk), @@ -94,7 +148,24 @@ module fw_ram ( .MASK({{8{~we[1]}}, {8{~we[0]}}}) ); - SB_RAM40_4K fw_ram1_1 ( + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram1_1 ( .RDATA(mem_read_data1[31 : 16]), .RADDR({3'h0, address[7 : 0]}), .RCLK(clk), @@ -108,6 +179,130 @@ module fw_ram ( .MASK({{8{~we[3]}}, {8{~we[2]}}}) ); + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram2_0 ( + .RDATA(mem_read_data2[15 : 0]), + .RADDR({3'h0, address[7 : 0]}), + .RCLK(clk), + .RCLKE(1'h1), + .RE(system_mode_cs & bank2), + .WADDR({3'h0, address[7 : 0]}), + .WCLK(clk), + .WCLKE(1'h1), + .WDATA(write_data[15 : 0]), + .WE((|we & system_mode_cs & bank2)), + .MASK({{8{~we[1]}}, {8{~we[0]}}}) + ); + + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram2_1 ( + .RDATA(mem_read_data2[31 : 16]), + .RADDR({3'h0, address[7 : 0]}), + .RCLK(clk), + .RCLKE(1'h1), + .RE(system_mode_cs & bank2), + .WADDR({3'h0, address[7 : 0]}), + .WCLK(clk), + .WCLKE(1'h1), + .WDATA(write_data[31 : 16]), + .WE((|we & system_mode_cs & bank2)), + .MASK({{8{~we[3]}}, {8{~we[2]}}}) + ); + + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram3_0 ( + .RDATA(mem_read_data3[15 : 0]), + .RADDR({3'h0, address[7 : 0]}), + .RCLK(clk), + .RCLKE(1'h1), + .RE(system_mode_cs & bank3), + .WADDR({3'h0, address[7 : 0]}), + .WCLK(clk), + .WCLKE(1'h1), + .WDATA(write_data[15 : 0]), + .WE((|we & system_mode_cs & bank3)), + .MASK({{8{~we[1]}}, {8{~we[0]}}}) + ); + + SB_RAM40_4K #( + .INIT_0(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000) + ) fw_ram3_1 ( + .RDATA(mem_read_data3[31 : 16]), + .RADDR({3'h0, address[7 : 0]}), + .RCLK(clk), + .RCLKE(1'h1), + .RE(system_mode_cs & bank3), + .WADDR({3'h0, address[7 : 0]}), + .WCLK(clk), + .WCLKE(1'h1), + .WDATA(write_data[31 : 16]), + .WE((|we & system_mode_cs & bank3)), + .MASK({{8{~we[3]}}, {8{~we[2]}}}) + ); + //---------------------------------------------------------------- // reg_update //---------------------------------------------------------------- @@ -127,17 +322,29 @@ module fw_ram ( always @* begin : rw_mux bank0 = 1'h0; bank1 = 1'h0; + bank2 = 1'h0; + bank3 = 1'h0; tmp_read_data = 32'h0; if (system_mode_cs) begin - if (address[8]) begin - bank1 = 1'h1; - tmp_read_data = mem_read_data1; - end - else begin - bank0 = 1'h1; - tmp_read_data = mem_read_data0; - end + case (address[9:8]) + 2'b11: begin + bank3 = 1'h1; + tmp_read_data = mem_read_data3; + end + 2'b10: begin + bank2 = 1'h1; + tmp_read_data = mem_read_data2; + end + 2'b01: begin + bank1 = 1'h1; + tmp_read_data = mem_read_data1; + end + 2'b00: begin + bank0 = 1'h1; + tmp_read_data = mem_read_data0; + end + endcase end end diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index 939897c..eb31549 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -105,7 +105,7 @@ module tk1 #( localparam TK1_VERSION = 32'h00000005; localparam FW_RAM_FIRST = 32'hd0000000; - localparam FW_RAM_LAST = 32'hd00007ff; + localparam FW_RAM_LAST = 32'hd0000fff; // 4 KB //---------------------------------------------------------------- @@ -395,7 +395,7 @@ module tk1 #( if (cpu_valid) begin // Outside ROM area - if (cpu_addr[31 : 30] == 2'h0 & |cpu_addr[29 : 14]) begin + if (cpu_addr[31 : 30] == 2'h0 & |cpu_addr[29 : 13]) begin force_trap_set = 1'h1; end @@ -443,7 +443,7 @@ module tk1 #( end // Outside FW_RAM - if (cpu_addr[29 : 24] == 6'h10 & |cpu_addr[23 : 11]) begin + if (cpu_addr[29 : 24] == 6'h10 & |cpu_addr[23 : 12]) begin force_trap_set = 1'h1; end diff --git a/hw/application_fpga/firmware.bin.sha512 b/hw/application_fpga/firmware.bin.sha512 index 34f5869..2e44ad2 100644 --- a/hw/application_fpga/firmware.bin.sha512 +++ b/hw/application_fpga/firmware.bin.sha512 @@ -1 +1 @@ -5e655ba4f25e7f5bc033ce0d9707c9a0b8990258c4b87470c2bcef90d50df79813705c1ef9d22c8670a37aff68f0e5146e5d0c21406916aabf7704579eb7f15c firmware.bin +866ad99a5fe0466f49b81d4b12b4ec81c3e0d6dba3ef8ad94ae44e6fa190ff495c95fbc5571214e890302f88997d0db45034e12fc8b8880fa01c10411b26f960 firmware.bin diff --git a/hw/application_fpga/fw/README.md b/hw/application_fpga/fw/README.md index 458139b..e4dfe2d 100644 --- a/hw/application_fpga/fw/README.md +++ b/hw/application_fpga/fw/README.md @@ -73,7 +73,9 @@ Dev Handbook for specific details. ## Memory constraints - ROM: 6 kByte. -- FW\_RAM: 2 kByte. +- FW\_RAM: 4 kByte. + - fw stack: 3824 bytes. + - resetinfo: 272 bytes. - RAM: 128 kByte. ## Firmware behaviour @@ -158,7 +160,7 @@ in the memory map, so it's still possible to execute firmware code in application mode, but with no privileged access. Firmware loads the application at the start of RAM (`0x4000_0000`). It -uses the special FW\_RAM for its own stack. +use a part of the special FW\_RAM for its own stack. When reset is released, the CPU starts executing the firmware. It begins by clearing all CPU registers, clears all FW\_RAM, sets up a @@ -203,9 +205,9 @@ Typical expected use scenario: let the device application know where it is loaded and how large it is, if it wants to relocate in RAM. - 7. The firmware now clears the special `FW_RAM` where it keeps it - stack. After this it performs no more function calls and uses no - more automatic variables. + 7. The firmware now clears the part of the special `FW_RAM` where it + keeps it stack. After this it performs no more function calls and + uses no more automatic variables. 8. Firmware starts the application by first switching from firmware mode to application mode by writing to the `SYSTEM_MODE_CTRL` @@ -245,8 +247,8 @@ implementation in the FPGA at this time. The firmware instead does the CDI computation using the special firmware-only `FW_RAM` which is invisible after switching to app mode. -We keep the entire firmware stack in `FW_RAM` and clear it just before -switching to app mode just in case. +We keep the entire firmware stack in `FW_RAM` and clear the stack just +before switching to app mode just in case. We sleep for a random number of cycles before reading out the UDS, call `blake2s_update()` with it and then immediately call @@ -259,10 +261,6 @@ Then we continue with the CDI computation by updating with an optional USS and then finalizing the hash, storing the resulting digest in `CDI`. -We also clear the entire `FW_RAM` where the stack lived, including the -BLAKE2s context with the UDS, very soon after that, just before -jumping to the application. - ### Firmware services The firmware exposes a BLAKE2s function through a function pointer diff --git a/hw/application_fpga/fw/testfw/main.c b/hw/application_fpga/fw/testfw/main.c index fe97d53..3f5460e 100644 --- a/hw/application_fpga/fw/testfw/main.c +++ b/hw/application_fpga/fw/testfw/main.c @@ -295,7 +295,7 @@ int main(void) } // Test FW_RAM. - puts("\r\nTesting FW_RAM (takes 15s on hw)...\r\n"); + puts("\r\nTesting FW_RAM (takes 50s on hw)...\r\n"); for (unsigned int i = 0; i < TK1_MMIO_FW_RAM_SIZE; i++) { zero_fwram(); *(volatile uint8_t *)(TK1_MMIO_FW_RAM_BASE + i) = 0x42; diff --git a/hw/application_fpga/fw/tk1/firmware.lds b/hw/application_fpga/fw/tk1/firmware.lds index 5a423ff..c9c8579 100644 --- a/hw/application_fpga/fw/tk1/firmware.lds +++ b/hw/application_fpga/fw/tk1/firmware.lds @@ -3,13 +3,18 @@ * SPDX-License-Identifier: GPL-2.0-only */ -OUTPUT_ARCH( "riscv" ) +OUTPUT_ARCH("riscv") ENTRY(_start) +/* Define stack size */ +STACK_SIZE = 0xEF0; /* 3824 B */ + MEMORY { - ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128 KB */ - RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 0x20000 /* 128 KB */ + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* 8 KB */ + FWRAM (rw) : ORIGIN = 0xd0000000, LENGTH = 0xF00 /* 3840 B */ + RESETINFO (rw) : ORIGIN = 0xd0000F00, LENGTH = 0x100 /* 256 B (part of FW_RAM area) */ + RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 0x20000 /* 128 KB */ } SECTIONS @@ -28,31 +33,38 @@ SECTIONS .text : { . = ALIGN(4); + _stext = .; *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - *(.srodata) /* .rodata sections (constants, strings, etc.) */ - *(.srodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.srodata) /* .srodata sections (constants, strings, etc.) */ + *(.srodata*) /* .srodata* sections (constants, strings, etc.) */ . = ALIGN(4); _etext = .; - _sidata = _etext; } >ROM - /* XXX We don't allow any data or BSS - but they need be defined or linking will fail */ + .stack (NOLOAD) : + { + . = ALIGN(16); + _sstack = .; + . += STACK_SIZE; + . = ALIGN(16); + _estack = .; + } >FWRAM - .data : AT (_etext) + .data : { . = ALIGN(4); _sdata = .; - . = ALIGN(4); *(.data) /* .data sections */ *(.data*) /* .data* sections */ - *(.sdata) /* .sdata sections */ - *(.sdata*) /* .sdata* sections */ + *(.sdata) /* .sdata sections */ + *(.sdata*) /* .sdata* sections */ . = ALIGN(4); _edata = .; - } >ROM + } >FWRAM AT>ROM + _sidata = LOADADDR(.data); /* Uninitialized data section */ .bss : @@ -64,8 +76,12 @@ SECTIONS *(.sbss) *(.sbss*) *(COMMON) - . = ALIGN(4); _ebss = .; - } >ROM + } >FWRAM } + +_sfwram = ORIGIN(FWRAM); +_efwram = ORIGIN(FWRAM) + LENGTH(FWRAM); +_sresetinfo = ORIGIN(RESETINFO); +_eresetinfo = ORIGIN(RESETINFO) + LENGTH(RESETINFO); diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index 40e548c..c299fa5 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -334,8 +334,8 @@ static void run(const struct context *ctx) // clang-format off #ifndef S_SPLINT_S asm volatile( - "li a0, 0xd0000000;" // FW_RAM - "li a1, 0xd0000800;" // End of 2 KB FW_RAM (just past the end) + "la a0, _sstack;" + "la a1, _estack;" "loop:;" "sw zero, 0(a0);" "addi a0, a0, 4;" diff --git a/hw/application_fpga/fw/tk1/start.S b/hw/application_fpga/fw/tk1/start.S index 93a2fb0..8f09a97 100644 --- a/hw/application_fpga/fw/tk1/start.S +++ b/hw/application_fpga/fw/tk1/start.S @@ -39,17 +39,24 @@ _start: li x31,0 /* Clear FW_RAM */ - li a0, 0xd0000000 // TK1_MMIO_FW_RAM_BASE - li a1, 0xd0000800 // TK1_MMIO_FW_RAM_BASE + TK1_MMIO_FW_RAM_SIZE + la a0, _sfwram + la a1, _efwram clear: sw zero, 0(a0) addi a0, a0, 4 blt a0, a1, clear - /* - * Init stack at top of fw_ram. - */ - li sp, 0xd0000800 // 2 kiB (TK1_MMIO_FW_RAM_SIZE) + /* Zero-init bss section */ + la a0, _sbss + la a1, _ebss + +loop_init_bss: + sw zero, 0(a0) + addi a0, a0, 4 + blt a0, a1, loop_init_bss + + /* Init stack */ + la sp, _estack call main diff --git a/hw/application_fpga/fw/tk1_mem.h b/hw/application_fpga/fw/tk1_mem.h index 89d6b7d..1cec14a 100644 --- a/hw/application_fpga/fw/tk1_mem.h +++ b/hw/application_fpga/fw/tk1_mem.h @@ -54,6 +54,8 @@ */ #define TK1_ROM_BASE 0x00000000 +#define TK1_ROM_SIZE 0x2000 + #define TK1_RAM_BASE 0x40000000 #define TK1_RAM_SIZE 0x20000 @@ -63,8 +65,8 @@ #define TK1_APP_MAX_SIZE 0x20000 #define TK1_MMIO_FW_RAM_BASE 0xd0000000 -// FW_RAM is 2048 bytes -#define TK1_MMIO_FW_RAM_SIZE 0x800 +// FW_RAM is 4096 bytes +#define TK1_MMIO_FW_RAM_SIZE 0x1000 #define TK1_MMIO_TRNG_BASE 0xc0000000 #define TK1_MMIO_TRNG_STATUS 0xc0000024 diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 4d86e10..09c1ecb 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -89,7 +89,7 @@ module application_fpga ( wire [31 : 0] cpu_wdata; reg rom_cs; - reg [11 : 0] rom_address; + reg [10 : 0] rom_address; wire [31 : 0] rom_read_data; wire rom_ready; @@ -128,7 +128,7 @@ module application_fpga ( reg fw_ram_cs; reg [ 3 : 0] fw_ram_we; - reg [ 8 : 0] fw_ram_address; + reg [ 9 : 0] fw_ram_address; reg [31 : 0] fw_ram_write_data; wire [31 : 0] fw_ram_read_data; wire fw_ram_ready; @@ -394,7 +394,7 @@ module application_fpga ( muxed_rdata_new = 32'h0; rom_cs = 1'h0; - rom_address = cpu_addr[13 : 2]; + rom_address = cpu_addr[12 : 2]; ram_cs = 1'h0; ram_we = 4'h0; @@ -403,7 +403,7 @@ module application_fpga ( fw_ram_cs = 1'h0; fw_ram_we = cpu_wstrb; - fw_ram_address = cpu_addr[10 : 2]; + fw_ram_address = cpu_addr[11 : 2]; fw_ram_write_data = cpu_wdata; trng_cs = 1'h0; diff --git a/hw/application_fpga/tb/application_fpga_sim.v b/hw/application_fpga/tb/application_fpga_sim.v index 94e13ee..f2d4b33 100644 --- a/hw/application_fpga/tb/application_fpga_sim.v +++ b/hw/application_fpga/tb/application_fpga_sim.v @@ -101,7 +101,7 @@ module application_fpga_sim ( wire [31 : 0] cpu_wdata; reg rom_cs; - reg [11 : 0] rom_address; + reg [10 : 0] rom_address; wire [31 : 0] rom_read_data; wire rom_ready; @@ -140,7 +140,7 @@ module application_fpga_sim ( reg fw_ram_cs; reg [ 3 : 0] fw_ram_we; - reg [ 8 : 0] fw_ram_address; + reg [ 9 : 0] fw_ram_address; reg [31 : 0] fw_ram_write_data; wire [31 : 0] fw_ram_read_data; wire fw_ram_ready; @@ -408,7 +408,7 @@ module application_fpga_sim ( muxed_rdata_new = 32'h0; rom_cs = 1'h0; - rom_address = cpu_addr[13 : 2]; + rom_address = cpu_addr[12 : 2]; ram_cs = 1'h0; ram_we = 4'h0; @@ -417,7 +417,7 @@ module application_fpga_sim ( fw_ram_cs = 1'h0; fw_ram_we = cpu_wstrb; - fw_ram_address = cpu_addr[10 : 2]; + fw_ram_address = cpu_addr[11 : 2]; fw_ram_write_data = cpu_wdata; trng_cs = 1'h0;