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.
This commit is contained in:
Jonas Thörnblad 2025-02-19 16:45:05 +01:00 committed by Michael Cardell Widerkrantz
parent 3126a9c51e
commit 3c74f93184
No known key found for this signature in database
GPG Key ID: D3DB3DDF57E704E5
13 changed files with 309 additions and 77 deletions

View File

@ -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

View File

@ -1 +1 @@
93e311e4bfa7e2f8c3c89f194b5fbe7b83eff81e6d32fd73c8859d5d76324b48 application_fpga.bin
5287588b9929a5709859e5fd85cc585dda6524821740bd06829258be7e9fad7d application_fpga.bin

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
5e655ba4f25e7f5bc033ce0d9707c9a0b8990258c4b87470c2bcef90d50df79813705c1ef9d22c8670a37aff68f0e5146e5d0c21406916aabf7704579eb7f15c firmware.bin
866ad99a5fe0466f49b81d4b12b4ec81c3e0d6dba3ef8ad94ae44e6fa190ff495c95fbc5571214e890302f88997d0db45034e12fc8b8880fa01c10411b26f960 firmware.bin

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;"

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;