Skip to content

Commit

Permalink
Merged PR 118807: 2:1 Mux bugfix and added current read pointer to mb…
Browse files Browse the repository at this point in the history
…ox status

Added current mailbox read pointer to the mailbox status register.
Adding a new sequence to have runtime FW use the direct read path in the mailbox.
Fixing a bug in the 2:1 ahb mux that could cause a hang.

Related work items: #443133, #460321, #522026
  • Loading branch information
Nitsirks authored and Anjana Parthasarathy committed Aug 14, 2023
1 parent 45149d1 commit 4fdf169
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 27 deletions.
8 changes: 4 additions & 4 deletions src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,13 @@ always_comb hready_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ?
//Send the data coming from responder when selected
always_comb hresp_o_0 = initiator0_data_ph ? hresp_i : '0;
always_comb hrdata_o_0 = initiator0_data_ph ? hrdata_i : '0;
always_comb hready_o_0 = initiator0_pend_addr_ph ? '0 :
initiator0_data_ph ? hreadyout_i : '1;
always_comb hready_o_0 = initiator0_data_ph ? hreadyout_i :
initiator0_pend_addr_ph ? '0 : '1;

always_comb hresp_o_1 = initiator1_data_ph? hresp_i: '0;
always_comb hrdata_o_1 = initiator1_data_ph ? hrdata_i: '0;
always_comb hready_o_1 = initiator1_pend_addr_ph ? '0 :
initiator1_data_ph ? hreadyout_i : '1;
always_comb hready_o_1 = initiator1_data_ph ? hreadyout_i :
initiator1_pend_addr_ph ? '0 : '1;

`CALIPTRA_ASSERT_MUTEX(ERR_2TO1MUX_MUTEX_DATA_PH, {initiator0_data_ph,initiator1_data_ph}, hclk, hreset_n)
`CALIPTRA_ASSERT_NEVER(ERR_2TO1MUX_BAD_HTRANS, (htrans_o == 2'b01), hclk, hreset_n)
Expand Down
2 changes: 2 additions & 0 deletions src/integration/rtl/caliptra_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -5183,6 +5183,8 @@
#define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (0x1c0)
#define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9)
#define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (0x200)
#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10)
#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (0x1fffc00)
#define CLP_MBOX_CSR_MBOX_UNLOCK (0x30020020)
#define MBOX_CSR_MBOX_UNLOCK (0x20)
#define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0)
Expand Down
2 changes: 2 additions & 0 deletions src/integration/rtl/caliptra_reg_defines.svh
Original file line number Diff line number Diff line change
Expand Up @@ -5183,6 +5183,8 @@
`define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (32'h1c0)
`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9)
`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (32'h200)
`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10)
`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (32'h1fffc00)
`define CLP_MBOX_CSR_MBOX_UNLOCK (32'h30020020)
`define MBOX_CSR_MBOX_UNLOCK (32'h20)
`define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0)
Expand Down
11 changes: 10 additions & 1 deletion src/integration/rtl/caliptra_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,6 @@ el2_veer_wrapper rvtop (
cptra_security_state_Latched <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; //Setting the default value to be debug locked and in production mode
security_state_f <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; //Setting the default value to be debug locked and in production mode
cptra_security_state_captured <= 0;
scan_mode_f <= 0;
end
else if(!cptra_security_state_captured) begin
cptra_security_state_Latched <= security_state;
Expand All @@ -611,10 +610,20 @@ el2_veer_wrapper rvtop (
// Asset flushing happens 'anytime' switch happens for safe side
//security_state_f <= security_state;
security_state_f <= security_state;
end
end

always_ff @(posedge clk or negedge cptra_pwrgood) begin
if (~cptra_pwrgood) begin
scan_mode_f <= '0;
end
else begin
scan_mode_f <= scan_mode;
end
end



// When scan mode goes from 0->1, generate a pulse to clear the assets
// Note that when scan goes to '1, Caliptra state as well as SOC state
// gets messed up. So switch to scan is destructive (obvious! Duh!)
Expand Down
19 changes: 15 additions & 4 deletions src/integration/test_suites/caliptra_rt/caliptra_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,24 @@ void caliptra_rt() {
}
else {
VPRINTF(MEDIUM, "Received mailbox command (no expected RESP) from SOC! Got 0x%x\n", op.cmd);
VPRINTF(MEDIUM, "Got command with DLEN 0x%x\n", op.dlen);
//Command to exercise direct read path to mailbox
if (op.cmd == MBOX_CMD_DIR_RD) {
// Read provided data through direct path
for (loop_iter = 0; loop_iter<op.dlen; loop_iter+=4) {
read_data = soc_ifc_mbox_dir_read_dataout_single(loop_iter);
}
}
//For overrun command, read an extra dword
if (op.cmd == MBOX_CMD_UC_OVERRUN) op.dlen = op.dlen + 4;
// Read provided data
for (loop_iter = 0; loop_iter<op.dlen; loop_iter+=4) {
read_data = soc_ifc_mbox_read_dataout_single();
else {
if (op.cmd == MBOX_CMD_UC_OVERRUN) op.dlen = op.dlen + 4;
// Read provided data
for (loop_iter = 0; loop_iter<op.dlen; loop_iter+=4) {
read_data = soc_ifc_mbox_read_dataout_single();
}
}
lsu_write_32((uintptr_t) (CLP_MBOX_CSR_MBOX_DLEN), 0);
//Mark the command complete
soc_ifc_set_mbox_status_field(CMD_COMPLETE);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/integration/test_suites/libs/soc_ifc/soc_ifc.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ enum {
};

enum mbox_cmd_e {
MBOX_CMD_DIR_RD = 0x01000000,
MBOX_CMD_UC_BASIC = 0x20000000,
MBOX_CMD_UC_OVERRUN = 0x20000001,
MBOX_CMD_RESP_BASIC = 0x40000000,
Expand Down Expand Up @@ -93,6 +94,9 @@ enum sha_accel_mode_e {
inline uint32_t soc_ifc_mbox_read_dataout_single() {
return lsu_read_32(CLP_MBOX_CSR_MBOX_DATAOUT);
}
inline uint32_t soc_ifc_mbox_dir_read_dataout_single(uint32_t rdptr) {
return lsu_read_32(0x30000000 + rdptr);
}
void soc_ifc_clear_execute_reg();
void soc_ifc_set_mbox_status_field(enum mbox_status_e field);
void soc_ifc_set_flow_status_field(uint32_t field);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
IDX_SOC_IFC_ENV_MBOX_SHA_ACCEL,
IDX_SOC_IFC_ENV_SHA_ACCEL,
IDX_SOC_IFC_ENV_FW_UPD,
IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS
IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS,
IDX_SOC_IFC_ENV_MBOX_DIR_READ
} rand_seq_idx;

rand int iteration_count;
Expand Down Expand Up @@ -116,7 +117,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
IDX_SOC_IFC_ENV_MBOX_SHA_ACCEL := 100,
IDX_SOC_IFC_ENV_SHA_ACCEL := 100,
IDX_SOC_IFC_ENV_FW_UPD := 10,
IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS := 100
IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS := 100,
IDX_SOC_IFC_ENV_MBOX_DIR_READ := 100
};
}
constraint iter_count_c {
Expand Down Expand Up @@ -337,6 +339,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
obj = soc_ifc_env_mbox_fw_upd_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS:
obj = soc_ifc_env_mbox_uc_reg_access_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_DIR_READ:
obj = soc_ifc_env_mbox_dir_read_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
default:
`uvm_error("CALIPTRA_TOP_RAND_TEST", $sformatf("rand_seq_idx randomized to illegal value: %p", rand_seq_idx))
endcase
Expand Down
24 changes: 14 additions & 10 deletions src/keyvault/rtl/kv.sv
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,6 @@ end
always_comb begin : keyvault_ctrl
//keyvault control registers
for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin
//Qualify lock signals as they are on fw upd reset and create RDC violations if allowed to reset asynchronously
lock_wr_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_wr.value & ~fw_update_rst_window;
lock_use_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_use.value & ~fw_update_rst_window;
//once lock is set, only reset can unset it
kv_reg_hwif_in.KEY_CTRL[entry].lock_wr.swwel = lock_wr_q[entry];
kv_reg_hwif_in.KEY_CTRL[entry].lock_use.swwel = lock_use_q[entry];
//clear dest valid and last dword
kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry];
kv_reg_hwif_in.KEY_CTRL[entry].last_dword.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry];
//init for AND-OR
key_entry_ctrl_we[entry] = '0;
key_entry_dest_valid_next[entry] = '0;
Expand All @@ -147,6 +138,16 @@ always_comb begin : keyvault_ctrl
//store the final offset on the last write cycle, we'll use that to signal last dword on reads
key_entry_last_dword_next[entry] |= kv_write[client].write_en & (kv_write[client].write_entry == entry) ? kv_write[client].write_offset : '0;
end
//Qualify lock signals as they are on fw upd reset and create RDC violations if allowed to reset asynchronously
lock_wr_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_wr.value & ~fw_update_rst_window;
lock_use_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_use.value & ~fw_update_rst_window;
//once lock is set, only reset can unset it
kv_reg_hwif_in.KEY_CTRL[entry].lock_wr.swwel = lock_wr_q[entry];
kv_reg_hwif_in.KEY_CTRL[entry].lock_use.swwel = lock_use_q[entry];
//clear dest valid and last dword
kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~key_entry_ctrl_we[entry] & ~lock_wr_q[entry] & ~lock_use_q[entry];
kv_reg_hwif_in.KEY_CTRL[entry].last_dword.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~key_entry_ctrl_we[entry] & ~lock_wr_q[entry] & ~lock_use_q[entry];

kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.we = key_entry_ctrl_we[entry];
kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.next = key_entry_dest_valid_next[entry];
kv_reg_hwif_in.KEY_CTRL[entry].last_dword.we = key_entry_ctrl_we[entry];
Expand All @@ -172,7 +173,10 @@ always_comb begin : keyvault_ctrl
kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.we = key_entry_we[entry][dword];
kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.next = key_entry_next[entry][dword];
//don't clear when writes are locked
kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry];
//don't clear when write is in progress, this could lead to partial key generation
kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value &
~key_entry_ctrl_we[entry] &
~lock_wr_q[entry] & ~lock_use_q[entry];
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions src/soc_ifc/rtl/caliptra_top_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
#define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (0x1c0)
#define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9)
#define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (0x200)
#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10)
#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (0x1fffc00)
#define CALIPTRA_TOP_REG_MBOX_CSR_MBOX_UNLOCK (0x30020020)
#define MBOX_CSR_MBOX_UNLOCK (0x20)
#define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0)
Expand Down
2 changes: 2 additions & 0 deletions src/soc_ifc/rtl/caliptra_top_reg_defines.svh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
`define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (32'h1c0)
`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9)
`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (32'h200)
`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10)
`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (32'h1fffc00)
`define CALIPTRA_TOP_REG_MBOX_CSR_MBOX_UNLOCK (32'h30020020)
`define MBOX_CSR_MBOX_UNLOCK (32'h20)
`define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0)
Expand Down
4 changes: 3 additions & 1 deletion src/soc_ifc/rtl/mbox.sv
Original file line number Diff line number Diff line change
Expand Up @@ -547,10 +547,12 @@ always_comb hwif_in.mbox_execute.execute.hwclr = arc_FORCE_MBOX_UNLOCK;
always_comb hwif_in.mbox_status.ecc_single_error.hwset = sram_single_ecc_error;
always_comb hwif_in.mbox_status.ecc_double_error.hwset = sram_double_ecc_error;
always_comb hwif_in.mbox_status.soc_has_lock.next = soc_has_lock;
always_comb hwif_in.mbox_status.mbox_rdptr.next = mbox_rdptr;

always_comb dmi_reg.MBOX_DLEN = hwif_out.mbox_dlen.length.value;
always_comb dmi_reg.MBOX_DOUT = hwif_out.mbox_dataout.dataout.value;
always_comb dmi_reg.MBOX_STATUS = {22'd0, /* [31:10] */
always_comb dmi_reg.MBOX_STATUS = {7'd0, /* [31:25] */
hwif_out.mbox_status.mbox_rdptr.value, /* [24:10]*/
hwif_out.mbox_status.soc_has_lock.value, /* [9] */
hwif_out.mbox_status.mbox_fsm_ps.value, /* [8:6] */
hwif_out.mbox_status.ecc_double_error.value, /* [5] */
Expand Down
7 changes: 7 additions & 0 deletions src/soc_ifc/rtl/mbox_csr.rdl
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ addrmap mbox_csr {
[br]SOC Access: RO
[br]TAP Access [in debug/manuf mode]: RO";
sw=r; hw=rw;} soc_has_lock=1'b0;
field {
name = "Current Mailbox Read Pointer";
desc = "Returns the current read pointer for the mailbox
[br]Caliptra Access: RO
[br]SOC Access: RO
[br]TAP Access [in debug/manuf mode]: RO";
sw=r; hw=rw;} mbox_rdptr[15] = 0;
} mbox_status;

reg {
Expand Down
29 changes: 28 additions & 1 deletion src/soc_ifc/rtl/mbox_csr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ module mbox_csr (
logic next;
logic load_next;
} soc_has_lock;
struct packed{
logic [14:0] next;
logic load_next;
} mbox_rdptr;
} mbox_status;
struct packed{
struct packed{
Expand Down Expand Up @@ -231,6 +235,9 @@ module mbox_csr (
struct packed{
logic value;
} soc_has_lock;
struct packed{
logic [14:0] value;
} mbox_rdptr;
} mbox_status;
struct packed{
struct packed{
Expand Down Expand Up @@ -491,6 +498,25 @@ module mbox_csr (
end
end
assign hwif_out.mbox_status.soc_has_lock.value = field_storage.mbox_status.soc_has_lock.value;
// Field: mbox_csr.mbox_status.mbox_rdptr
always_comb begin
automatic logic [14:0] next_c = field_storage.mbox_status.mbox_rdptr.value;
automatic logic load_next_c = '0;
if(1) begin // HW Write
next_c = hwif_in.mbox_status.mbox_rdptr.next;
load_next_c = '1;
end
field_combo.mbox_status.mbox_rdptr.next = next_c;
field_combo.mbox_status.mbox_rdptr.load_next = load_next_c;
end
always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin
if(~hwif_in.cptra_rst_b) begin
field_storage.mbox_status.mbox_rdptr.value <= 'h0;
end else if(field_combo.mbox_status.mbox_rdptr.load_next) begin
field_storage.mbox_status.mbox_rdptr.value <= field_combo.mbox_status.mbox_rdptr.next;
end
end
assign hwif_out.mbox_status.mbox_rdptr.value = field_storage.mbox_status.mbox_rdptr.value;
// Field: mbox_csr.mbox_unlock.unlock
always_comb begin
automatic logic [0:0] next_c = field_storage.mbox_unlock.unlock.value;
Expand Down Expand Up @@ -536,7 +562,8 @@ module mbox_csr (
assign readback_array[7][5:5] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.ecc_double_error.value : '0;
assign readback_array[7][8:6] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.mbox_fsm_ps.value : '0;
assign readback_array[7][9:9] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.soc_has_lock.value : '0;
assign readback_array[7][31:10] = '0;
assign readback_array[7][24:10] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.mbox_rdptr.value : '0;
assign readback_array[7][31:25] = '0;
assign readback_array[8][0:0] = (decoded_reg_strb.mbox_unlock && !decoded_req_is_wr) ? field_storage.mbox_unlock.unlock.value : '0;
assign readback_array[8][31:1] = '0;

Expand Down
10 changes: 10 additions & 0 deletions src/soc_ifc/rtl/mbox_csr_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,17 @@ package mbox_csr_pkg;
logic next;
} mbox_csr__mbox_status__soc_has_lock__in_t;

typedef struct packed{
logic [14:0] next;
} mbox_csr__mbox_status__mbox_rdptr__in_t;

typedef struct packed{
mbox_csr__mbox_status__status__in_t status;
mbox_csr__mbox_status__ecc_single_error_next_e066e214_wel_e066e214__in_t ecc_single_error;
mbox_csr__mbox_status__ecc_double_error_next_e066e214_wel_e066e214__in_t ecc_double_error;
mbox_csr__mbox_status__mbox_fsm_ps__in_t mbox_fsm_ps;
mbox_csr__mbox_status__soc_has_lock__in_t soc_has_lock;
mbox_csr__mbox_status__mbox_rdptr__in_t mbox_rdptr;
} mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760__in_t;

typedef struct packed{
Expand Down Expand Up @@ -158,12 +163,17 @@ package mbox_csr_pkg;
logic value;
} mbox_csr__mbox_status__soc_has_lock__out_t;

typedef struct packed{
logic [14:0] value;
} mbox_csr__mbox_status__mbox_rdptr__out_t;

typedef struct packed{
mbox_csr__mbox_status__status__out_t status;
mbox_csr__mbox_status__ecc_single_error_next_e066e214_wel_e066e214__out_t ecc_single_error;
mbox_csr__mbox_status__ecc_double_error_next_e066e214_wel_e066e214__out_t ecc_double_error;
mbox_csr__mbox_status__mbox_fsm_ps__out_t mbox_fsm_ps;
mbox_csr__mbox_status__soc_has_lock__out_t soc_has_lock;
mbox_csr__mbox_status__mbox_rdptr__out_t mbox_rdptr;
} mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760__out_t;

typedef struct packed{
Expand Down
Loading

0 comments on commit 4fdf169

Please sign in to comment.