Skip to content

Commit

Permalink
[UVM] Update UVM ROM test with bringup fixes, infra to test latest pu…
Browse files Browse the repository at this point in the history
…blic builds, auto-extract PK values (#478)

* Program timer configuration regs as part of reset/bringup

* Syntax fix for localparam sizing

* Only look at lower 8-bits when parsing writes to GENERIC_OUTPUT_WIRES in TB

* Add info messages

* Add CPTRA_TIMER_CONFIG detection and nop message to resolve warning

* Update ROM image makefile to fetch the latest build from caliptra-sw

* Use 7z instead of unzip for pipeline compatibility

* Updates for running latest ROM imageUpdate the makefile to extract PK values from ROM, hash them
Update top ROM test sequence to wait for BOOT_STATUS=320
Update bringup sequence to use calculated PK hash values for fuse programming
Update ROM firmware updater sequence to use the generated size of fw image
submitting the fw update command

* Fix derivation of pk offets/sizes

* Add required byte-swizzling when programming PK hash values to fuses

* increase verbosity for reporting writes to BOOT_STATUS

* Use the firmware bundle image instead of the ROM to extract PK values

* Revert the byte-swap macro -- this is not necessary when using sha384sum raw output

* Constraint fix to prevent call to wait_for_num_clocks with 0 arg

* Increase WDT configuration from 150 to 250ms

* Wait for ICCM_LOCK instead of BOOT_STATUS (which requires debugging mode enabled)

* Fix the uvm_info tag when reporting iccm_lock access

* Fix for an underflow case where dlen is so small that the underflow_bytes constraint wraps around

* MICROSOFT AUTOMATED PIPELINE: Stamp 'cwhitehead-msft-ROM-uvm-updates' with updated timestamp and hash after successful run

* MICROSOFT AUTOMATED PIPELINE: Stamp 'cwhitehead-msft-ROM-uvm-updates' with updated timestamp and hash after successful run

* Fatal error reporting on failure to open required ROM hex files

* MICROSOFT AUTOMATED PIPELINE: Stamp 'cwhitehead-msft-ROM-uvm-updates' with updated timestamp and hash after successful run
  • Loading branch information
calebofearth authored Apr 29, 2024
1 parent 67fc658 commit 778da6f
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .github/workflow_metadata/pr_hash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5655dd9cdb6d63f2e14b99b3b873d82dd91d20bca430811592949581784ecfef8c8bd319569a73b25feada15e28b196b
a1c6b4e9634eda1208a2bdc365434561792dbe62102bcb254a470c3f9216bc45a755aadd6334294ab3116b82593f1eb6
2 changes: 1 addition & 1 deletion .github/workflow_metadata/pr_timestamp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1714169869
1714426957
22 changes: 11 additions & 11 deletions src/integration/tb/caliptra_top_tb_services.sv
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,19 @@ module caliptra_top_tb_services
ras_test_ctrl.reset_ooo_done_flag <= 1'b0;
ras_test_ctrl.reset_no_lock_done_flag <= 1'b0;
end
else if((WriteData == 8'he5) && mailbox_write) begin
else if((WriteData[7:0] == 8'he5) && mailbox_write) begin
ras_test_ctrl.do_no_lock_access <= 1'b1;
ras_test_ctrl.do_ooo_access <= 1'b0;
ras_test_ctrl.reset_ooo_done_flag <= 1'b0;
ras_test_ctrl.reset_no_lock_done_flag <= 1'b0;
end
else if((WriteData == 8'he6) && mailbox_write) begin
else if((WriteData[7:0] == 8'he6) && mailbox_write) begin
ras_test_ctrl.do_no_lock_access <= 1'b0;
ras_test_ctrl.do_ooo_access <= 1'b1;
ras_test_ctrl.reset_ooo_done_flag <= 1'b0;
ras_test_ctrl.reset_no_lock_done_flag <= 1'b0;
end
else if ((WriteData == 8'he7) && mailbox_write) begin
else if ((WriteData[7:0] == 8'he7) && mailbox_write) begin
ras_test_ctrl.do_no_lock_access <= 1'b0;
ras_test_ctrl.do_ooo_access <= 1'b0;
ras_test_ctrl.reset_ooo_done_flag <= 1'b1;
Expand Down Expand Up @@ -631,13 +631,13 @@ endgenerate //IV_NO


always@(negedge clk) begin
if((WriteData == 'hf2) && mailbox_write) begin
if((WriteData[7:0] == 8'hf2) && mailbox_write) begin
force caliptra_top_dut.soc_ifc_top1.clk_gating_en = 1;
end
end

always@(negedge clk) begin
if ((WriteData == 'he9) && mailbox_write) begin
if ((WriteData[7:0] == 8'he9) && mailbox_write) begin
cycleCnt_ff <= cycleCnt;
en_jtag_access <= 'b1;
end
Expand All @@ -659,7 +659,7 @@ endgenerate //IV_NO
inject_zeroize_to_hmac <= 1'b0;
inject_zeroize_to_hmac_cnt <= '0;
end
else if((WriteData == 'h99) && mailbox_write) begin
else if((WriteData[7:0] == 8'h99) && mailbox_write) begin
inject_zeroize_to_hmac_cmd <= 1'b1;
end
else if (inject_zeroize_to_hmac_cmd) begin
Expand Down Expand Up @@ -687,7 +687,7 @@ endgenerate //IV_NO
//Inject fatal error after a delay
logic inject_fatal_error;
always@(negedge clk) begin
if((WriteData == 'heb) && mailbox_write) begin
if((WriteData[7:0] == 8'heb) && mailbox_write) begin
cycleCnt_ff <= cycleCnt;
inject_fatal_error <= 'b1;
end
Expand Down Expand Up @@ -878,18 +878,18 @@ endgenerate //IV_NO

always@(negedge clk) begin

if((WriteData == 'hf5) && mailbox_write) begin
if((WriteData[7:0] == 8'hf5) && mailbox_write) begin
cold_rst <= 'b1;
rst_cyclecnt <= cycleCnt;
end
else if((WriteData == 'hf6) && mailbox_write) begin
else if((WriteData[7:0] == 8'hf6) && mailbox_write) begin
warm_rst <= 'b1;
rst_cyclecnt <= cycleCnt;
end
else if((WriteData == 'hf7) && mailbox_write) begin
else if((WriteData[7:0] == 8'hf7) && mailbox_write) begin
timed_warm_rst <= 'b1;
end
else if((WriteData == 'hee) && mailbox_write) begin
else if((WriteData[7:0] == 8'hee) && mailbox_write) begin
wait_time_to_rst = $urandom_range(5,100);
prandom_warm_rst <= 'b1;
rst_cyclecnt <= cycleCnt;
Expand Down
90 changes: 81 additions & 9 deletions src/integration/test_suites/fw_test_rom/fw_test_rom.makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#
GCC_PREFIX = riscv64-unknown-elf
BUILD_DIR = $(CURDIR)
today=$(shell date +%Y%m%d)

# Define test name
TESTNAME ?= fw_test_rom
Expand All @@ -23,6 +24,26 @@ TEST_DIR = $(CALIPTRA_ROOT)/src/integration/test_suites/$(TESTNAME)

VPATH = $(TEST_DIR) $(BUILD_DIR)

# Offset calculations for fetching keys from ROM image
KEY_MANIFEST_ECC_PK_COUNT = 4
KEY_MANIFEST_ECC_PK_SIZE = 96
KEY_MANIFEST_ECC_PK_ROM_OFFSET = 8
KEY_MANIFEST_ECC_PK_LENGTH = $(shell bc <<< "$(KEY_MANIFEST_ECC_PK_COUNT)*$(KEY_MANIFEST_ECC_PK_SIZE)")

KEY_MANIFEST_LMS_PK_COUNT = 32
KEY_MANIFEST_LMS_PK_SIZE = 48
KEY_MANIFEST_LMS_PK_ROM_OFFSET = $(shell bc <<< "$(KEY_MANIFEST_ECC_PK_ROM_OFFSET) + $(KEY_MANIFEST_ECC_PK_COUNT)*$(KEY_MANIFEST_ECC_PK_SIZE)")
KEY_MANIFEST_LMS_PK_LENGTH = $(shell bc <<< "$(KEY_MANIFEST_LMS_PK_COUNT)*$(KEY_MANIFEST_LMS_PK_SIZE)")

KEY_MANIFEST_PK_LENGTH = $(shell bc <<< "$(KEY_MANIFEST_LMS_PK_LENGTH) + $(KEY_MANIFEST_ECC_PK_LENGTH)")

OWNER_ECC_PK_SIZE = 96
OWNER_ECC_PK_ROM_OFFSET = 3652
OWNER_LMS_PK_SIZE = 48
OWNER_LMS_PK_ROM_OFFSET = $(shell bc <<< "$(OWNER_ECC_PK_ROM_OFFSET) + $(OWNER_ECC_PK_SIZE)")

OWNER_PK_LENGTH = $(shell bc <<< "$(OWNER_LMS_PK_SIZE) + $(OWNER_ECC_PK_SIZE)")

# Targets
all: program.hex

Expand All @@ -35,19 +56,70 @@ clean:
############ TEST build ###############################

# Build program.hex from RUST executable
program.hex: fw_update.hex
@echo "Building program.hex from $(TESTNAME) using Crypto Test rules for pre-compiled RUST executables"
-$(GCC_PREFIX)-objcopy -O verilog --pad-to 0x8000 --gap-fill 0xFF --no-change-warnings $(TEST_DIR)/$(TESTNAME) program.hex
$(GCC_PREFIX)-objdump -S $(TEST_DIR)/$(TESTNAME) > $(TESTNAME).dis
$(GCC_PREFIX)-size $(TEST_DIR)/$(TESTNAME) | tee $(TESTNAME).size
program.hex: key_manifest_pk_hash_val.hex owner_pk_hash_val.hex fw_update.hex $(TEST_DIR)/$(TESTNAME).extracted $(TEST_DIR)/$(TESTNAME)
@-echo "Building program.hex from $(TESTNAME) using Crypto Test rules for pre-compiled RUST executables"
$(GCC_PREFIX)-objcopy -I binary -O verilog --pad-to 0x8000 --gap-fill 0xFF --no-change-warnings $(TEST_DIR)/$(TESTNAME) program.hex
du -b $(TEST_DIR)/$(TESTNAME) | cut -f1 > $(TESTNAME).size

fw_update.hex: $(TEST_DIR)/$(TESTNAME).extracted $(TEST_DIR)/$(TESTNAME_fw)
@-echo "Building fw_update.hex from $(TESTNAME_fw) using binary objcopy pre-compiled RUST package"
$(GCC_PREFIX)-objcopy -I binary -O verilog --pad-to 0x20000 --gap-fill 0xFF --no-change-warnings $(TEST_DIR)/$(TESTNAME_fw) fw_update.hex
du -b $(TEST_DIR)/$(TESTNAME_fw) | cut -f1 > fw_update.size

fw_update.hex:
@echo "Building fw_update.hex from $(TESTNAME_fw) using simple hexdump on pre-compiled RUST package"
-hexdump -v -e '16/1 "%02x " "\n"' $(TEST_DIR)/$(TESTNAME_fw) > fw_update.hex
# Extract public keys from ROM binary and dump as hex values
key_manifest_pk_hash_val.hex: key_manifest_pk_val.bin
sha384sum key_manifest_pk_val.bin | sed 's,\s\+\S\+$$,,' > key_manifest_pk_hash_val.hex

key_manifest_pk_val.bin: $(TEST_DIR)/$(TESTNAME).extracted
dd ibs=1 obs=1 if=$(TEST_DIR)/$(TESTNAME_fw) of=key_manifest_pk_val.bin skip=$(KEY_MANIFEST_ECC_PK_ROM_OFFSET) count=$(KEY_MANIFEST_PK_LENGTH)

owner_pk_hash_val.hex: owner_pk_val.bin
sha384sum owner_pk_val.bin | sed 's,\s\+\S\+$$,,' > owner_pk_hash_val.hex

owner_pk_val.bin: $(TEST_DIR)/$(TESTNAME).extracted
dd ibs=1 obs=1 if=$(TEST_DIR)/$(TESTNAME_fw) of=owner_pk_val.bin skip=$(OWNER_ECC_PK_ROM_OFFSET) count=$(OWNER_PK_LENGTH)

# Extract compiled FW from latest retrieved release
$(TEST_DIR)/$(TESTNAME).extracted: caliptra_release_v$(today)_0.zip
@7z x -o"$(TEST_DIR)" $< caliptra-rom-with-log.bin
7z x -o"$(TEST_DIR)" $< image-bundle.bin
rm $<
mv $(TEST_DIR)/caliptra-rom-with-log.bin $(TEST_DIR)/$(TESTNAME)
mv $(TEST_DIR)/image-bundle.bin $(TEST_DIR)/$(TESTNAME_fw)
touch $(TEST_DIR)/$(TESTNAME).extracted

# Retrieve latest build from caliptra-sw repo
# Fail if a build from within the last 30 days is not found
caliptra_release_v$(today)_0.zip: $(TEST_DIR)/$(TESTNAME)
@base_url='https://github.com/chipsalliance/caliptra-sw/releases/download/'
found=0
full_path=""
for days_ago in $$(seq 0 31); do
test_date=$$(date +%Y%m%d --date="$(today) -$${days_ago} days")
echo "Checking date $${test_date} for package"
super_base="release_v$${test_date}_0"
zipfile_base="caliptra_release_v$${test_date}_0"
full_path="$${base_url}/$${super_base}/$${zipfile_base}.zip"
if wget --spider --quiet $${full_path}; then
echo "Found $${full_path}";
found=1
break;
fi
done
if [[ $${found} -eq 1 ]]; then
wget --no-use-server-timestamps $${full_path}
else
exit 1
fi
# Cheesy rename to satisfy makefile dependency
if [[ ! -f "caliptra_release_v$(today)_0.zip" ]]; then
mv $${zipfile_base}.zip "caliptra_release_v$(today)_0.zip"
fi

help:
@echo Make sure the environment variable RV_ROOT is set.
@echo Possible targets: help clean all program.hex
echo Possible targets: help clean all program.hex

.PHONY: help clean

.ONESHELL:
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,19 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base;

run_firmware_init(soc_ifc_env_mbox_rom_seq);

// After firmware init, wait for generic_output_wires write to 0xFF
while(soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.generic_output_val[31:0] != 32'hff) begin
sts_rsp_count = 0;
while(!sts_rsp_count) soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); // Wait for new status updates
end
// After firmware init, wait for ICCM_LOCK to be set, indicating transition from ROM to FMC
while (reg_model.soc_ifc_reg_rm.internal_iccm_lock.lock.get_mirrored_value() != 1)
soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(10);

// UVMF_CHANGE_ME : Extend the simulation XXX number of clocks after
// the last sequence to allow for the last sequence item to flow
// through the design.
fork
soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(400);
soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(400);
soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(400);
soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(400);
soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(400);
soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(4000);
soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(4000);
soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(4000);
soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(4000);
soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(4000);
join

// pragma uvmf custom body end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI
typedef soc_ifc_ctrl_reset_sequence_base soc_ifc_ctrl_sequence_t;
soc_ifc_ctrl_sequence_t soc_ifc_ctrl_seq;

localparam CPTRA_CLK_PERIOD_PS = 10000; // 100MHz clk = 10ns. FIXME derive from system?
localparam [63:0] CPTRA_WDT_TIMEOUT_IN_PS = 64'd250_000_000_000; // 250ms
localparam [63:0] CPTRA_WDT_CFG_VALUE = CPTRA_WDT_TIMEOUT_IN_PS / CPTRA_CLK_PERIOD_PS; // clock cycles

caliptra_apb_user apb_user_obj;

typedef struct packed {
Expand Down Expand Up @@ -175,6 +179,17 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI
if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", "Failed when writing to lms_verify")
end

// Not a 'FUSE', but WDT timeout is configured by SoC... do it here anyway.
`uvm_info("SOC_IFC_RST", $sformatf("Writing CPTRA_CLK_PERIOD_PS [%d] to CPTRA_TIMER_CONFIG", CPTRA_CLK_PERIOD_PS), UVM_LOW)
reg_model.soc_ifc_reg_rm.CPTRA_TIMER_CONFIG.write(sts, uvm_reg_data_t'(CPTRA_CLK_PERIOD_PS), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj));
if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", "Failed when writing to CPTRA_TIMER_CONFIG")

`uvm_info("SOC_IFC_RST", $sformatf("Writing CPTRA_WDT_CFG_VALUE [0x%x_%x] to CPTRA_WDT_CFG", CPTRA_WDT_CFG_VALUE[63:32], CPTRA_WDT_CFG_VALUE[31:0]), UVM_LOW)
reg_model.soc_ifc_reg_rm.CPTRA_WDT_CFG[0].write(sts, uvm_reg_data_t'(CPTRA_WDT_CFG_VALUE[31:0]), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj));
if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", "Failed when writing to CPTRA_WDT_CFG[0]")
reg_model.soc_ifc_reg_rm.CPTRA_WDT_CFG[1].write(sts, uvm_reg_data_t'(CPTRA_WDT_CFG_VALUE[63:32]), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj));
if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", "Failed when writing to CPTRA_WDT_CFG[1]")

// Set Fuse Done
reg_model.soc_ifc_reg_rm.CPTRA_FUSE_WR_DONE.write(sts, `UVM_REG_DATA_WIDTH'(1), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj));
`uvm_info("SOC_IFC_RST", $sformatf("Fuse download completed, status: %p", sts), UVM_MEDIUM)
Expand Down
Loading

0 comments on commit 778da6f

Please sign in to comment.