Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/mci/config/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ requires:
- axi_sub
- soc_ifc_top
- mci_pkg
- lc_ctrl_pkg
- fuse_ctrl_pkg
# for beh_lib with rvecc_encode/decode
- el2_veer_pkg
targets:
Expand All @@ -35,6 +37,7 @@ targets:
- $COMPILE_ROOT/rtl/mci_wdt_top.sv
- $COMPILE_ROOT/rtl/mci_reg_top.sv
- $COMPILE_ROOT/rtl/mci_reg.sv
- $COMPILE_ROOT/rtl/mci_lcc_st_trans.sv
tops: [mci_top]
rtl_lint:
directories: [$COMPILE_ROOT/config/design_lint]
Expand All @@ -59,3 +62,62 @@ global:
default:
- '-assert svaext'
- '-noinherit_timescale=1ns/1ps'
---
provides: [mci_lcc_st_trans]
schema_version: 2.4.0
requires:
- caliptra_prim
- soc_ifc_top
- mci_pkg
- el2_veer_pkg
- lc_ctrl_pkg
- fuse_ctrl_pkg
targets:
rtl:
directories:
- $COMPILE_ROOT/rtl
files:
- $COMPILE_ROOT/rtl/mci_lcc_st_trans.sv
tops: [mci_lcc_st_trans]
rtl_lint:
directories: [$COMPILE_ROOT/config/design_lint]
waiver_files:
- $MSFT_REPO_ROOT/src/integration/config/design_lint/sglint_waivers
tops: [mci_lcc_st_trans]
---
provides: [mci_lcc_st_trans_tb]
schema_version: 2.4.0
requires:
- caliptra_prim
- soc_ifc_top
- mci_pkg
- el2_veer_pkg
- lc_ctrl_pkg
- fuse_ctrl_pkg
- mci_lcc_st_trans
targets:
rtl:
directories: [$COMPILE_ROOT/tb]
files:
- $COMPILE_ROOT/tb/mci_lcc_st_trans_tb.sv
tops: [mci_lcc_st_trans_tb]
global:
tool:
vcs:
default:
- '-assert svaext'
- '-noinherit_timescale=1ns/1ps'
#sim:
#- '-ucli -i dump.ucli'
# Suppress a warning due to calling $fgets as task instead of function
# i.e. discarding the return value. This is in auto-generated code.
- '+warn=noRVOSFD'
# Suppress NOTE about repeated package imports within the same
# package (each .svh file included in the auto-generated UVM _pkg.sv
# files imports the same dependencies)
- '-suppress=SV-LCM-PPWI'
elab:
# Suppress warnings about too few port connections - auto-generated interfaces
# declare all signals as inout, but are driven at a lower layer than the
# instantiation, so they will always flag this
- '-suppress=TFIPC'
233 changes: 233 additions & 0 deletions src/mci/rtl/mci_lcc_st_trans.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

module mci_lcc_st_trans
import mci_pkg::*;
import lc_ctrl_state_pkg::*;
import soc_ifc_pkg::*;
(
input logic clk,
input logic rst_n,
// Inputs from top level of MCI
input logic state_error, // That represents any invalid state errors
// Inputs from LCC
input otp_ctrl_pkg::lc_otp_program_req_t from_lcc_to_otp_program_i,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
// Inputs from OTP_Ctrl
input otp_ctrl_pkg::otp_lc_data_t from_otp_to_lcc_program_i,
// Inputs from Caliptra_Core
input logic ss_dbg_manuf_enable_i,
input logic [63:0] ss_soc_dbg_unlock_level_i,
// Inputs from SoC
input logic [63:0] ss_soc_dft_en_mask_reg0_1,
input logic [63:0] ss_soc_dbg_unlock_mask_reg0_1, // Check FSM's TRANSLATOR_PROD_NON_DEBUG state
input logic [63:0] ss_soc_CLTAP_unlock_mask_reg0_1,

// Converted Signals from LCC
output logic SOC_DFT_EN,
output logic SOC_HW_DEBUG_EN,

output soc_ifc_pkg::security_state_t security_state_o
);

soc_ifc_pkg::security_state_t security_state_comb;
mci_state_translator_fsm_state_e mci_trans_st_next;
mci_state_translator_fsm_state_e mci_trans_st_current;
lc_state_e lc_alive_state;
lc_state_e otp_static_state;

logic otp_data_valid;
logic lc_otp_prog_req;
logic lcc_valid_SCRAP_req;
logic SOC_DFT_EN_AND;
logic SOC_HW_DEBUG_EN_AND;
logic CLPTR_PROD_DEBUG_UNLOCK_AND;


assign otp_data_valid = from_otp_to_lcc_program_i.valid;
assign lc_otp_prog_req = from_lcc_to_otp_program_i.req;
assign lc_alive_state = from_lcc_to_otp_program_i.state;
assign SOC_DFT_EN_AND = |(ss_soc_dbg_unlock_level_i & ss_soc_dft_en_mask_reg0_1);
assign SOC_HW_DEBUG_EN_AND = |(ss_soc_dbg_unlock_level_i & ss_soc_CLTAP_unlock_mask_reg0_1);
assign CLPTR_PROD_DEBUG_UNLOCK_AND = |(ss_soc_dbg_unlock_level_i & ss_soc_dbg_unlock_mask_reg0_1);
assign lcc_valid_SCRAP_req = (lc_alive_state == LcStScrap && lc_otp_prog_req);



always_ff @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
mci_trans_st_current <= TRANSLATOR_RESET;
security_state_o <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // Default case
otp_static_state <= LcStRaw; // This is all zeros
SOC_DFT_EN <= 1'b0;
SOC_HW_DEBUG_EN <= 1'b0;
end
else begin
if (otp_data_valid) begin
mci_trans_st_current <= mci_trans_st_next;
security_state_o <= security_state_comb; // Default case
otp_static_state <= lc_state_e'(from_otp_to_lcc_program_i.state);
SOC_DFT_EN <= (lc_dft_en_i == lc_ctrl_pkg::On) | SOC_DFT_EN_AND;
SOC_HW_DEBUG_EN <= (lc_hw_debug_en_i == lc_ctrl_pkg::On) | SOC_HW_DEBUG_EN_AND;
end
else begin
mci_trans_st_current <= TRANSLATOR_RESET;
security_state_o <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // Default case
otp_static_state <= LcStRaw; // This is all zeros
SOC_DFT_EN <= 1'b0;
SOC_HW_DEBUG_EN <= 1'b0;
end
end
end



always_comb begin: state_branch

case(mci_trans_st_current)
TRANSLATOR_RESET: begin
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // Default case
if (otp_data_valid) begin
mci_trans_st_next = TRANSLATOR_IDLE;
end
else begin
mci_trans_st_next = TRANSLATOR_RESET;
end
end
TRANSLATOR_IDLE: begin
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // Default case
// This module takes lcc state as a valid input only if LCC decides to enter SCRAP
// or Invalid state. This if condition also take SoC decision if it wants to put Caliptra
// into non-debug mode due to a state error triggered through MCI fatal error logic
if (lcc_valid_SCRAP_req || otp_static_state == LcStScrap || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
end
// RAW to TEST_LOCK0-6 are the non-debug modes. RAW is the default mode of LCC
else if (otp_static_state inside {LcStRaw,
LcStTestLocked0,
LcStTestLocked1,
LcStTestLocked2,
LcStTestLocked3,
LcStTestLocked4,
LcStTestLocked5,
LcStTestLocked6}) begin

mci_trans_st_next = TRANSLATOR_NON_DEBUG;
end
else if (otp_static_state inside {LcStTestUnlocked0,
LcStTestUnlocked1,
LcStTestUnlocked2,
LcStTestUnlocked3,
LcStTestUnlocked4,
LcStTestUnlocked5,
LcStTestUnlocked6,
LcStTestUnlocked7}) begin

mci_trans_st_next = TRANSLATOR_UNPROV_DEBUG;
end
else if (otp_static_state == LcStDev) begin

mci_trans_st_next = TRANSLATOR_MANUF_NON_DEBUG;
end
else if (otp_static_state == LcStProd) begin

mci_trans_st_next = TRANSLATOR_PROD_NON_DEBUG;
end
else if (otp_static_state == LcStProdEnd) begin

mci_trans_st_next = TRANSLATOR_PROD_NON_DEBUG;
end
else if (otp_static_state == LcStRma) begin

mci_trans_st_next = TRANSLATOR_PROD_DEBUG;
end
else begin

mci_trans_st_next = TRANSLATOR_IDLE;
end
end
TRANSLATOR_NON_DEBUG: begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
TRANSLATOR_UNPROV_DEBUG: begin
if (lcc_valid_SCRAP_req || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else begin
mci_trans_st_next = TRANSLATOR_UNPROV_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_UNPROVISIONED, debug_locked: 1'b0};
end
end
TRANSLATOR_MANUF_NON_DEBUG: begin
if (lcc_valid_SCRAP_req || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else if (ss_dbg_manuf_enable_i) begin
mci_trans_st_next = TRANSLATOR_MANUF_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_MANUFACTURING, debug_locked: 1'b1};
end
else begin
mci_trans_st_next = TRANSLATOR_MANUF_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_MANUFACTURING, debug_locked: 1'b1};
end
end
TRANSLATOR_MANUF_DEBUG: begin
if (lcc_valid_SCRAP_req || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else begin
mci_trans_st_next = TRANSLATOR_MANUF_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_MANUFACTURING, debug_locked: 1'b0};
end
end
TRANSLATOR_PROD_NON_DEBUG: begin
if (lcc_valid_SCRAP_req || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else if (CLPTR_PROD_DEBUG_UNLOCK_AND) begin // TODO: Be careful for fault injections
mci_trans_st_next = TRANSLATOR_PROD_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else begin
mci_trans_st_next = TRANSLATOR_PROD_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
end
TRANSLATOR_PROD_DEBUG: begin
if (lcc_valid_SCRAP_req || state_error) begin
mci_trans_st_next = TRANSLATOR_NON_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1};
end
else begin
mci_trans_st_next = TRANSLATOR_MANUF_DEBUG;
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b0};
end
end
default: begin
security_state_comb = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // Default case
mci_trans_st_next = TRANSLATOR_IDLE;
end
endcase

end

endmodule


11 changes: 11 additions & 0 deletions src/mci/rtl/mci_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,16 @@ package mci_pkg;
BOOT_RST_MCU = 4'b1001
} mci_boot_fsm_state_e;

typedef enum logic [2:0] {
TRANSLATOR_RESET = 3'd0,
TRANSLATOR_IDLE = 3'd1,
TRANSLATOR_NON_DEBUG = 3'd2,
TRANSLATOR_UNPROV_DEBUG = 3'd3,
TRANSLATOR_MANUF_NON_DEBUG = 3'd4,
TRANSLATOR_MANUF_DEBUG = 3'd5,
TRANSLATOR_PROD_NON_DEBUG = 3'd6,
TRANSLATOR_PROD_DEBUG = 3'd7
} mci_state_translator_fsm_state_e;

endpackage
`endif /*MCI_PKG*/
43 changes: 42 additions & 1 deletion src/mci/rtl/mci_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,28 @@ module mci_top
mci_mcu_sram_if.request mci_mbox0_sram_req_if,

// Mbox1 SRAM Interface
mci_mcu_sram_if.request mci_mbox1_sram_req_if
mci_mcu_sram_if.request mci_mbox1_sram_req_if,


//=============== LCC GASKET PORTS ========================

// Inputs from LCC
input otp_ctrl_pkg::lc_otp_program_req_t from_lcc_to_otp_program_i,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
// Inputs from OTP_Ctrl
input otp_ctrl_pkg::otp_lc_data_t from_otp_to_lcc_program_i,
// Inputs from Caliptra_Core
input logic ss_dbg_manuf_enable_i,
input logic [63:0] ss_soc_dbg_unlock_level_i,

// Converted Signals from LCC
output logic SOC_DFT_EN,
output logic SOC_HW_DEBUG_EN,

output soc_ifc_pkg::security_state_t security_state_o

//============================================================

);

Expand Down Expand Up @@ -471,4 +492,24 @@ mci_mbox1_i (
end
endgenerate


// DUT instantiation
mci_lcc_st_trans LCC_state_translator (
.clk(clk),
.rst_n(mci_rst_b),
.state_error(1'b0), // TODO: This needs to be added to put caliptra into debug locked position
.from_lcc_to_otp_program_i(from_lcc_to_otp_program_i),
.lc_dft_en_i(lc_dft_en_i),
.lc_hw_debug_en_i(lc_hw_debug_en_i),
.from_otp_to_lcc_program_i(from_otp_to_lcc_program_i),
.ss_dbg_manuf_enable_i(ss_dbg_manuf_enable_i),
.ss_soc_dbg_unlock_level_i(ss_soc_dbg_unlock_level_i),
.ss_soc_dft_en_mask_reg0_1(64'h0), // TODO: there should be two registers for this connection
.ss_soc_dbg_unlock_mask_reg0_1(64'h0), // TODO: there should be two registers for this connection
.ss_soc_CLTAP_unlock_mask_reg0_1(64'h0), // TODO: there should be two registers for this connection
.SOC_DFT_EN(SOC_DFT_EN),
.SOC_HW_DEBUG_EN(SOC_HW_DEBUG_EN),
.security_state_o(security_state_o)
);

endmodule
Loading