diff --git a/.github/workflow_metadata/pr_hash b/.github/workflow_metadata/pr_hash index c1a986177..44b56164e 100644 --- a/.github/workflow_metadata/pr_hash +++ b/.github/workflow_metadata/pr_hash @@ -1 +1 @@ -5655dd9cdb6d63f2e14b99b3b873d82dd91d20bca430811592949581784ecfef8c8bd319569a73b25feada15e28b196b \ No newline at end of file +a1c6b4e9634eda1208a2bdc365434561792dbe62102bcb254a470c3f9216bc45a755aadd6334294ab3116b82593f1eb6 \ No newline at end of file diff --git a/.github/workflow_metadata/pr_timestamp b/.github/workflow_metadata/pr_timestamp index 71cbe74ff..cc9863c4f 100644 --- a/.github/workflow_metadata/pr_timestamp +++ b/.github/workflow_metadata/pr_timestamp @@ -1 +1 @@ -1714169869 \ No newline at end of file +1714426957 \ No newline at end of file diff --git a/src/integration/tb/caliptra_top_tb_services.sv b/src/integration/tb/caliptra_top_tb_services.sv index a3f2582fc..5eaf68bd6 100644 --- a/src/integration/tb/caliptra_top_tb_services.sv +++ b/src/integration/tb/caliptra_top_tb_services.sv @@ -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; @@ -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 @@ -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 @@ -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 @@ -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; diff --git a/src/integration/test_suites/fw_test_rom/fw_test_rom.makefile b/src/integration/test_suites/fw_test_rom/fw_test_rom.makefile index eabd715f4..7935b6895 100644 --- a/src/integration/test_suites/fw_test_rom/fw_test_rom.makefile +++ b/src/integration/test_suites/fw_test_rom/fw_test_rom.makefile @@ -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 @@ -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 @@ -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: diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh index 9182b23a6..4f0ead9ab 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh @@ -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 diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh index 5253bd642..334e73d6c 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh @@ -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 { @@ -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) diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh index 6362a605b..145117700 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh @@ -33,6 +33,13 @@ class soc_ifc_env_rom_bringup_sequence extends soc_ifc_env_reset_sequence_base; typedef soc_ifc_ctrl_rom_poweron_sequence soc_ifc_ctrl_agent_poweron_sequence_t; + localparam SHA384_DIGEST_SIZE = 48; // bytes + + // 384-bit (12 dwords) vector to store calculated hash of Key Manifest and Owner + // public keys from ROM image + bit [0:SHA384_DIGEST_SIZE/4-1] [31:0] key_manifest_pk_hash_val; + bit [0:SHA384_DIGEST_SIZE/4-1] [31:0] owner_pk_hash_val; + // Decide which fuses to initialize constraint always_set_uds_c { this.fuses_to_set.uds == 1'b1; } constraint always_set_fe_c { this.fuses_to_set.field_entropy == 1'b1; } @@ -44,42 +51,73 @@ class soc_ifc_env_rom_bringup_sequence extends soc_ifc_env_reset_sequence_base; this.fuses_to_set.idevid_cert_attr[6] == 1'b1; this.fuses_to_set.idevid_cert_attr[7] == 1'b1; } // Configure the values to set to initialized fuses - constraint key_manifest_pk_hash_values_c { key_manifest_pk_hash_rand[0] == 32'h6DC8DE16; - key_manifest_pk_hash_rand[1] == 32'hD559D129; - key_manifest_pk_hash_rand[2] == 32'h7BAB1E43; - key_manifest_pk_hash_rand[3] == 32'hEBD7C533; - key_manifest_pk_hash_rand[4] == 32'hDFE57001; - key_manifest_pk_hash_rand[5] == 32'h1AA56220; - key_manifest_pk_hash_rand[6] == 32'h0F66AD6D; - key_manifest_pk_hash_rand[7] == 32'h87051086; - key_manifest_pk_hash_rand[8] == 32'hC785E930; - key_manifest_pk_hash_rand[9] == 32'hD3D947B4; - key_manifest_pk_hash_rand[10] == 32'h7495822E; - key_manifest_pk_hash_rand[11] == 32'hCB643FF1; + constraint key_manifest_pk_hash_values_c { key_manifest_pk_hash_rand[0] == this.key_manifest_pk_hash_val[0] ; //32'h6DC8DE16; + key_manifest_pk_hash_rand[1] == this.key_manifest_pk_hash_val[1] ; //32'hD559D129; + key_manifest_pk_hash_rand[2] == this.key_manifest_pk_hash_val[2] ; //32'h7BAB1E43; + key_manifest_pk_hash_rand[3] == this.key_manifest_pk_hash_val[3] ; //32'hEBD7C533; + key_manifest_pk_hash_rand[4] == this.key_manifest_pk_hash_val[4] ; //32'hDFE57001; + key_manifest_pk_hash_rand[5] == this.key_manifest_pk_hash_val[5] ; //32'h1AA56220; + key_manifest_pk_hash_rand[6] == this.key_manifest_pk_hash_val[6] ; //32'h0F66AD6D; + key_manifest_pk_hash_rand[7] == this.key_manifest_pk_hash_val[7] ; //32'h87051086; + key_manifest_pk_hash_rand[8] == this.key_manifest_pk_hash_val[8] ; //32'hC785E930; + key_manifest_pk_hash_rand[9] == this.key_manifest_pk_hash_val[9] ; //32'hD3D947B4; + key_manifest_pk_hash_rand[10] == this.key_manifest_pk_hash_val[10]; //32'h7495822E; + key_manifest_pk_hash_rand[11] == this.key_manifest_pk_hash_val[11]; //32'hCB643FF1; solve this.fuses_to_set before this.key_manifest_pk_hash_rand; } - constraint owner_pk_hash_values_c { owner_pk_hash_rand[0] == 32'hF58D4920; - owner_pk_hash_rand[1] == 32'hBA65DA44; - owner_pk_hash_rand[2] == 32'hB0F728BC; - owner_pk_hash_rand[3] == 32'hFB893202; - owner_pk_hash_rand[4] == 32'hCFAAA942; - owner_pk_hash_rand[5] == 32'hBC66A0C0; - owner_pk_hash_rand[6] == 32'h007A2CE2; - owner_pk_hash_rand[7] == 32'h29A8E08F; - owner_pk_hash_rand[8] == 32'h9E8EEBAE; - owner_pk_hash_rand[9] == 32'hB36E9CC0; - owner_pk_hash_rand[10] == 32'h962E4B7A; - owner_pk_hash_rand[11] == 32'h50214999; + constraint owner_pk_hash_values_c { owner_pk_hash_rand[0] == owner_pk_hash_val[0] ;//32'hF58D4920; + owner_pk_hash_rand[1] == owner_pk_hash_val[1] ;//32'hBA65DA44; + owner_pk_hash_rand[2] == owner_pk_hash_val[2] ;//32'hB0F728BC; + owner_pk_hash_rand[3] == owner_pk_hash_val[3] ;//32'hFB893202; + owner_pk_hash_rand[4] == owner_pk_hash_val[4] ;//32'hCFAAA942; + owner_pk_hash_rand[5] == owner_pk_hash_val[5] ;//32'hBC66A0C0; + owner_pk_hash_rand[6] == owner_pk_hash_val[6] ;//32'h007A2CE2; + owner_pk_hash_rand[7] == owner_pk_hash_val[7] ;//32'h29A8E08F; + owner_pk_hash_rand[8] == owner_pk_hash_val[8] ;//32'h9E8EEBAE; + owner_pk_hash_rand[9] == owner_pk_hash_val[9] ;//32'hB36E9CC0; + owner_pk_hash_rand[10] == owner_pk_hash_val[10];//32'h962E4B7A; + owner_pk_hash_rand[11] == owner_pk_hash_val[11];//32'h50214999; solve this.fuses_to_set before this.owner_pk_hash_rand; } constraint idevid_values_c { idevid_cert_attr_rand[0] == '0; /* SHA1 */ idevid_cert_attr_rand[6] == 32'hFFFF_FFFF; /* UEID LSWord */ idevid_cert_attr_rand[7] == 32'hFFFF_FFFF; /* MSWord */} + //========================================== + // Function: new + // Description: Constructor + //========================================== function new(string name = "" ); uvm_object obj; + int fd; + string hex_val; super.new(name); obj = soc_ifc_ctrl_agent_poweron_sequence_t::get_type().create_object("soc_ifc_ctrl_agent_poweron_seq"); if (!$cast(soc_ifc_ctrl_seq,obj)) `uvm_fatal("SOC_IFC_BRINGUP", "Failed to cast object as poweron sequence!") + + // Read the PK Hash values extracted/calculated from the ROM image + fd = $fopen("key_manifest_pk_hash_val.hex", "r"); + if (!fd) begin + integer errno; + string str; + errno = $ferror(fd, str); + `uvm_fatal("SOC_IFC_BRINGUP", $sformatf("fopen failed to open key_manifest_pk_hash_val.hex with code [0x%x] message [%s]", errno, str)) + end + void'($fscanf(fd, "%x", key_manifest_pk_hash_val)); + $fclose(fd); + + fd = $fopen("owner_pk_hash_val.hex", "r"); + if (!fd) begin + integer errno; + string str; + errno = $ferror(fd, str); + `uvm_fatal("SOC_IFC_BRINGUP", $sformatf("fopen failed to open owner_pk_hash_val.hex with code [0x%x] message [%s]", errno, str)) + end + void'($fscanf(fd, "%x", owner_pk_hash_val )); + $fclose(fd); + + `uvm_info("SOC_IFC_BRINGUP", $sformatf("Using Vendor Public Key Hash of 0x%x %p from ROM image", key_manifest_pk_hash_val, key_manifest_pk_hash_val), UVM_LOW) + `uvm_info("SOC_IFC_BRINGUP", $sformatf("Using Owner Public Key Hash of 0x%x %p from ROM image", owner_pk_hash_val, owner_pk_hash_val), UVM_LOW) + endfunction endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh index 88b054f13..dfbfd73f3 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh @@ -44,7 +44,8 @@ task soc_ifc_env_mbox_dlen_underflow_sequence::mbox_push_datain(); int unsigned underflow_bytes; // Push less data than dlen requires - randomize how much less - if (!std::randomize(underflow_bytes) with {underflow_bytes <= mbox_op_rand.dlen - 8;}) + if (!std::randomize(underflow_bytes) with {!mbox_op_rand.cmd.cmd_s.resp_reqd -> underflow_bytes <= mbox_op_rand.dlen; + mbox_op_rand.cmd.cmd_s.resp_reqd -> underflow_bytes <= mbox_op_rand.dlen - 8;}) `uvm_error("MBOX_UNDERFLOW_SEQ", "Failed to randomize underflow bytes") else `uvm_info("MBOX_UNDERFLOW_SEQ", $sformatf("Randomized underflow bytes to %0d", underflow_bytes), UVM_MEDIUM) diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh index 2ba96ccd8..0f43ea537 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh @@ -30,13 +30,14 @@ class soc_ifc_env_mbox_rom_fw_sequence extends soc_ifc_env_mbox_sequence_base; // 128KiB memory, with 32768 single-dword entries bit [7:0] fw_img [soc_ifc_pkg::MBOX_DEPTH][soc_ifc_pkg::MBOX_DATA_W/8-1:0]; + int fw_img_size; extern virtual task mbox_setup(); extern virtual task mbox_push_datain(); // This shouldn't be randomized, specify it constraint mbox_cmd_c { mbox_op_rand.cmd == mbox_cmd_e'(MBOX_CMD_ROM_FW_UPD); } - constraint mbox_dlen_c { mbox_op_rand.dlen == 17772; } + constraint mbox_dlen_c { mbox_op_rand.dlen == fw_img_size; } // Response data is only non-zero if a response is requested, and also must // be small enough to fit in the mailbox // Firmware team encodes commands differently from this environment; response @@ -44,6 +45,28 @@ class soc_ifc_env_mbox_rom_fw_sequence extends soc_ifc_env_mbox_sequence_base; // Override to force this to 0. constraint mbox_resp_dlen_c { mbox_resp_expected_dlen == 0; } + //========================================== + // Function: new + // Description: Constructor + //========================================== + function new(string name = "" ); + integer fd; + + super.new(name); + + //read FW size for command constraint + fd = $fopen("fw_update.size", "r"); + if (!fd) begin + integer errno; + string str; + errno = $ferror(fd, str); + `uvm_fatal("SOC_IFC_BRINGUP", $sformatf("fopen failed to open fw_update.size with code [0x%x] message [%s]", errno, str)) + end + void'($fscanf(fd, "%d", fw_img_size)); + `uvm_info("MBOX_ROM_SEQ", $sformatf("Found firmware update image with size: [%d] bytes", fw_img_size), UVM_LOW)// UVM_HIGH) + $fclose(fd); + endfunction + endclass task soc_ifc_env_mbox_rom_fw_sequence::mbox_setup(); @@ -59,13 +82,13 @@ task soc_ifc_env_mbox_rom_fw_sequence::mbox_push_datain(); firmware_end_dw = this.mbox_op_rand.dlen / 4 + (this.mbox_op_rand.dlen%4 ? 1 : 0); - `uvm_info("MBOX_SEQ", $sformatf("Starting FW push_datain. Size: [0x%x] dwords", firmware_end_dw), UVM_LOW) + `uvm_info("MBOX_ROM_SEQ", $sformatf("Starting FW push_datain. Size: [0x%x] dwords", firmware_end_dw), UVM_LOW) for (datain_ii=0; datain_ii < firmware_end_dw; datain_ii++) begin data = uvm_reg_data_t'({fw_img[datain_ii][3],fw_img[datain_ii][2],fw_img[datain_ii][1],fw_img[datain_ii][0]}); if (datain_ii < 10) - `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", datain_ii, data), UVM_LOW) + `uvm_info("MBOX_ROM_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", datain_ii, data), UVM_LOW) else - `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", datain_ii, data), UVM_DEBUG) + `uvm_info("MBOX_ROM_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", datain_ii, data), UVM_DEBUG) reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); reg_model.mbox_csr_rm.mbox_datain_sem.put(); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rst_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rst_sequence.svh index 51a415fff..e6ba8aae6 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rst_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rst_sequence.svh @@ -75,7 +75,7 @@ endfunction task soc_ifc_env_top_mbox_rst_sequence::start_seqs(); int unsigned delay_clks; // Delay prior to system reset - if (!std::randomize(delay_clks) with {delay_clks < 4*soc_ifc_env_mbox_seq.mbox_op_rand.dlen;}) begin + if (!std::randomize(delay_clks) with {delay_clks > 0; delay_clks < 4*soc_ifc_env_mbox_seq.mbox_op_rand.dlen;}) begin `uvm_fatal("SOC_IFC_MBOX_TOP", $sformatf("soc_ifc_env_top_mbox_rst_sequence::body() - %s randomization failed", "delay_clks")); end fork @@ -86,6 +86,7 @@ task soc_ifc_env_top_mbox_rst_sequence::start_seqs(); soc_ifc_env_cptra_handler_seq.start(configuration.vsqr); end begin + `uvm_info("SOC_IFC_MBOX_TOP", $sformatf("Waiting for %d clocks before issuing reset", delay_clks), UVM_HIGH) configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(delay_clks); fork begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh index 9a3354c21..f6e3b31aa 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh @@ -1140,8 +1140,12 @@ class soc_ifc_predictor #( end end "CPTRA_BOOT_STATUS": begin - // Handled in callbacks via reg predictor - `uvm_info("PRED_AHB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) + if (ahb_txn.RnW == AHB_WRITE) begin + `uvm_info("PRED_AHB", $sformatf("Write to %s with value %d (0x%x) has no effect on system prediction.", axs_reg.get_name(), data_active, data_active), UVM_LOW) + end + else begin + `uvm_info("PRED_AHB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) + end end "CPTRA_FLOW_STATUS": begin if (ahb_txn.RnW == AHB_WRITE && @@ -1229,28 +1233,28 @@ class soc_ifc_predictor #( end "CPTRA_GENERIC_OUTPUT_WIRES[0]": begin if (ahb_txn.RnW == AHB_WRITE) begin - case (data_active) inside - 32'h0,[32'h2:32'h5],32'h7F,[32'h80:32'hf7]: + case (data_active[7:0]) inside + 8'h0,[8'h2:8'h5],8'h7F,[8'h80:8'hf7]: `uvm_warning("PRED_AHB", $sformatf("Observed write to CPTRA_GENERIC_OUTPUT_WIRES with an unassigned value: 0x%x", data_active)) - 32'h1: + 8'h1: `uvm_fatal("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES to Kill Simulation with Error!") /* TODO put this in the scoreboard? */ - [32'h6:32'h7E]: + [8'h6:8'h7E]: `uvm_info("PRED_AHB", $sformatf("Observed write to CPTRA_GENERIC_OUTPUT_WIRES and translating as ASCII character: %c", data_active[7:0]), UVM_MEDIUM) - 32'hf8: + 8'hf8: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Assert interrupt flags at fixed intervals to wake up halted core]", UVM_MEDIUM) - 32'hf9: + 8'hf9: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Lock debug in security state]", UVM_MEDIUM) - 32'hfa: + 8'hfa: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Unlock debug in security state]", UVM_MEDIUM) - 32'hfb: + 8'hfb: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Set the isr_active bit]", UVM_MEDIUM) - 32'hfc: + 8'hfc: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Clear the isr_active bit]", UVM_MEDIUM) - 32'hfd: + 8'hfd: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM single bit flip injection]", UVM_MEDIUM) - 32'hfe: + 8'hfe: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM double bit flip injection]", UVM_MEDIUM) - 32'hff: + 8'hff: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES to End the simulation with a Success status", UVM_LOW) endcase send_soc_ifc_sts_txn = data_active != generic_output_wires[31:0]; @@ -1382,7 +1386,7 @@ class soc_ifc_predictor #( "internal_iccm_lock": begin if (ahb_txn.RnW == AHB_WRITE && !iccm_locked) begin iccm_locked = 1'b1; - `uvm_info("FW_RST_DEBUG", $sformatf("Write to set iccm lock, value is 0x%x", p_soc_ifc_rm.soc_ifc_reg_rm.internal_iccm_lock.lock.get_mirrored_value()), UVM_LOW) + `uvm_info("PRED_AHB", $sformatf("Write to set iccm lock, value is 0x%x", p_soc_ifc_rm.soc_ifc_reg_rm.internal_iccm_lock.lock.get_mirrored_value()), UVM_LOW) send_cptra_sts_txn = 1; end else if (ahb_txn.RnW == AHB_WRITE) begin @@ -2295,6 +2299,9 @@ class soc_ifc_predictor #( `uvm_info("PRED_APB", $sformatf("Write to %s has no effect on boot FSM due to state [%p] breakpoint [%d] and txn type [%p]", axs_reg.get_name(), p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs, bootfsm_breakpoint, apb_txn.read_or_write), UVM_FULL) end end + "CPTRA_TIMER_CONFIG": begin + `uvm_info("PRED_APB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) + end "CPTRA_BOOTFSM_GO": begin // FIXME -- use reg predictor somehow? //When uc reset is still asserted and we're writing to bootfsm go, expect uc to be brough out of reset