diff --git a/src/integration/test_suites/caliptra_rt/caliptra_rt.c b/src/integration/test_suites/caliptra_rt/caliptra_rt.c index 9939a2515..417f10e6d 100644 --- a/src/integration/test_suites/caliptra_rt/caliptra_rt.c +++ b/src/integration/test_suites/caliptra_rt/caliptra_rt.c @@ -322,6 +322,7 @@ void caliptra_rt() { if (cptra_intr_rcv.soc_ifc_notif ) { uint8_t fsm_chk; uint8_t fail = 0; + uint32_t dlen_received; VPRINTF(LOW, "Intr received: soc_ifc_notif\n"); if (cptra_intr_rcv.soc_ifc_notif & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) { CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_notif, ~SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) @@ -379,6 +380,7 @@ void caliptra_rt() { } //read the mbox command op = soc_ifc_read_mbox_cmd(); + dlen_received = op.dlen; if (op.cmd & MBOX_CMD_FIELD_FW_MASK) { VPRINTF(MEDIUM, "Received mailbox firmware command from SOC! Got 0x%x\n", op.cmd); if (op.cmd & MBOX_CMD_FIELD_RESP_MASK) { @@ -517,6 +519,14 @@ void caliptra_rt() { CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (ECC unc) after servicing\n"); soc_ifc_set_mbox_status_field(CMD_FAILURE); + // TODO Remove the mailbox sanitization op in Gen2 validation framework. + // In Gen2, Caliptra Mailbox code should be modified to avoid spurious + // SRAM prefetches that make this sanitization necessary after a double-bit + // ECC error + if (soc_ifc_sanitize_mbox_n_bytes(dlen_received >= (MBOX_DIR_SPAN) ? MBOX_DIR_SPAN : dlen_received, 0xfff) != 0) { + SEND_STDOUT_CTRL(0x1); + while(1); + } } else if (fail) { VPRINTF(LOW, "Cmd failed\n"); soc_ifc_set_mbox_status_field(CMD_FAILURE); @@ -564,6 +574,14 @@ void caliptra_rt() { CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (ECC unc) after servicing\n"); soc_ifc_set_mbox_status_field(CMD_FAILURE); + // TODO Remove the mailbox sanitization op in Gen2 validation framework. + // In Gen2, Caliptra Mailbox code should be modified to avoid spurious + // SRAM prefetches that make this sanitization necessary after a double-bit + // ECC error + if (soc_ifc_sanitize_mbox_n_bytes(dlen_received >= (MBOX_DIR_SPAN) ? MBOX_DIR_SPAN : dlen_received, 0xfff) != 0) { + SEND_STDOUT_CTRL(0x1); + while(1); + } } else { soc_ifc_set_mbox_status_field(CMD_COMPLETE); } diff --git a/src/integration/test_suites/libs/soc_ifc/soc_ifc.c b/src/integration/test_suites/libs/soc_ifc/soc_ifc.c index c7270fb2d..299846807 100644 --- a/src/integration/test_suites/libs/soc_ifc/soc_ifc.c +++ b/src/integration/test_suites/libs/soc_ifc/soc_ifc.c @@ -108,6 +108,15 @@ void soc_ifc_clr_flow_status_field(uint32_t field) { lsu_write_32(CLP_SOC_IFC_REG_CPTRA_FLOW_STATUS,reg); } +uint8_t soc_ifc_mbox_acquire_lock(uint32_t attempt_count) { + for(uint32_t ii=0; ii MBOX_DIR_SPAN) { + VPRINTF(FATAL, "SOC_IFC: Illegal byte_count 0x%x\n", byte_count); + SEND_STDOUT_CTRL(0x1); + } + if (soc_ifc_mbox_acquire_lock(attempt_count) != 0) { + VPRINTF(ERROR, "ERROR: Failed to acquire lock for mbox sanitize operation\n"); + return 1; + } + for (uint32_t ii=0; ii < byte_count; ii+=4) { + lsu_write_32(MBOX_DIR_BASE_ADDR+ii, 0x0); + } + lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); + return 0; +} + void soc_ifc_set_fw_update_reset(uint8_t wait_cycles) { uint32_t reg; VPRINTF(MEDIUM,"SOC_IFC: Set fw update reset with wait_cycles [%d] (%s)\n", wait_cycles, wait_cycles > 5 ? "will override" : wait_cycles > 0 ? "will use default 5" : "won't override"); diff --git a/src/integration/test_suites/libs/soc_ifc/soc_ifc.h b/src/integration/test_suites/libs/soc_ifc/soc_ifc.h index 22e415442..84f6ad365 100644 --- a/src/integration/test_suites/libs/soc_ifc/soc_ifc.h +++ b/src/integration/test_suites/libs/soc_ifc/soc_ifc.h @@ -112,9 +112,11 @@ inline void soc_ifc_set_iccm_lock() { lsu_write_32((CLP_SOC_IFC_REG_INTERNAL_ICCM_LOCK), SOC_IFC_REG_INTERNAL_ICCM_LOCK_LOCK_MASK); } // Mailbox command flows +uint8_t soc_ifc_mbox_acquire_lock(uint32_t attempt_count); mbox_op_s soc_ifc_read_mbox_cmd(); void soc_ifc_mbox_fw_flow(mbox_op_s op); void soc_ifc_fw_update(mbox_op_s op); +uint8_t soc_ifc_sanitize_mbox_n_bytes(uint32_t byte_count, uint32_t attempt_count); // SHA Accelerator Functions void soc_ifc_sha_accel_acquire_lock(); 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_sram_double_bit_flip_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_sram_double_bit_flip_sequence.svh index 2a1bcd3b3..a117b2a0c 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_sram_double_bit_flip_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_sram_double_bit_flip_sequence.svh @@ -40,6 +40,8 @@ class soc_ifc_env_mbox_sram_double_bit_flip_sequence extends soc_ifc_env_mbox_se `uvm_object_utils( soc_ifc_env_mbox_sram_double_bit_flip_sequence ) + extern virtual task mbox_teardown(); + // Constrain command to undefined opcode constraint mbox_cmd_undef_c { !(mbox_op_rand.cmd.cmd_s inside {defined_cmds}); } @@ -105,3 +107,13 @@ class soc_ifc_env_mbox_sram_double_bit_flip_sequence extends soc_ifc_env_mbox_se endtask endclass + +//========================================== +// Task: mbox_teardown +// Description: At end-of-sequence, inject some stalls to allow +// uC to acquire lock and sanitize the mailbox +//========================================== +task soc_ifc_env_mbox_sram_double_bit_flip_sequence::mbox_teardown(); + do_rand_delay(1, DLY_MEDIUM); + super.mbox_teardown(); +endtask