From 3438b77921941ccbf50cba46b3009a6a37203d4b Mon Sep 17 00:00:00 2001 From: Greg Chadwick Date: Tue, 8 Mar 2022 12:07:30 +0000 Subject: [PATCH] [rtl] Add minor alert for icache ECC error --- doc/03_reference/icache.rst | 3 +++ doc/03_reference/security.rst | 7 +++++++ dv/uvm/icache/dv/tb/ic_top.sv | 4 +++- rtl/ibex_core.sv | 5 +++-- rtl/ibex_icache.sv | 6 +++++- rtl/ibex_if_stage.sv | 18 ++++++++++-------- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/doc/03_reference/icache.rst b/doc/03_reference/icache.rst index 1876986e..75115ebb 100644 --- a/doc/03_reference/icache.rst +++ b/doc/03_reference/icache.rst @@ -164,6 +164,8 @@ The remaining data from hits is buffered in the fill buffer data storage and sup To deal with misalignment caused by compressed instructions, there is a 16bit skid buffer to store the upper halfword. +.. _icache-ecc: + Cache ECC protection ^^^^^^^^^^^^^^^^^^^^ @@ -193,6 +195,7 @@ Any error (single or double bit) in any RAM will effectively cancel a cache hit The request which observed an error will fetch it's data from the main instruction memory as normal for a cache miss. The cache index and way (or ways) with errors are stored in IC1, and a cache write is forced the next cycle to invalidate that line. Lookup requests will be blocked in IC0 while the invalidation write is performed. +If an ECC error is seen a minor alert will be signaled. Cache invalidation ^^^^^^^^^^^^^^^^^^ diff --git a/doc/03_reference/security.rst b/doc/03_reference/security.rst index 2c5adf4d..866ccc60 100644 --- a/doc/03_reference/security.rst +++ b/doc/03_reference/security.rst @@ -81,6 +81,13 @@ When Ibex is configured with the SecureIbex parameter, ECC checking is added to This can be useful to detect fault injection attacks since the register file covers a reasonably large area. No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action. +ICache ECC +---------- + +The ICache can be configured with ECC protection. +When an ECC error is detected a minor alert is signaled. +See :ref:`icache-ecc` for more information. + Hardened PC ----------- diff --git a/dv/uvm/icache/dv/tb/ic_top.sv b/dv/uvm/icache/dv/tb/ic_top.sv index f6432db2..94a81e3c 100644 --- a/dv/uvm/icache/dv/tb/ic_top.sv +++ b/dv/uvm/icache/dv/tb/ic_top.sv @@ -105,7 +105,9 @@ module ic_top import ibex_pkg::*; #( .icache_enable_i ( icache_enable_i ), .icache_inval_i ( icache_inval_i ), - .busy_o ( busy_o ) + .busy_o ( busy_o ), + // TODO: Probe this and verify functionality + .ecc_error_o ( ) ); /////////////////////////////// diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index bd727909..c44f5707 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -181,6 +181,7 @@ module ibex_core import ibex_pkg::*; #( logic [31:0] dummy_instr_seed; logic icache_enable; logic icache_inval; + logic icache_ecc_error; logic pc_mismatch_alert; logic csr_shadow_err; @@ -432,6 +433,7 @@ module ibex_core import ibex_pkg::*; #( .dummy_instr_seed_i (dummy_instr_seed), .icache_enable_i (icache_enable), .icache_inval_i (icache_inval), + .icache_ecc_error_o (icache_ecc_error), // branch targets .branch_target_ex_i(branch_target_ex), @@ -852,8 +854,7 @@ module ibex_core import ibex_pkg::*; #( /////////////////// // Minor alert - core is in a recoverable state - // TODO add I$ ECC errors here - assign alert_minor_o = 1'b0; + assign alert_minor_o = icache_ecc_error; // Major alert - core is unrecoverable assign alert_major_o = rf_ecc_err_comb | pc_mismatch_alert | csr_shadow_err; diff --git a/rtl/ibex_icache.sv b/rtl/ibex_icache.sv index 7bfe527e..c15a29b5 100644 --- a/rtl/ibex_icache.sv +++ b/rtl/ibex_icache.sv @@ -64,7 +64,8 @@ module ibex_icache import ibex_pkg::*; #( // Cache status input logic icache_enable_i, input logic icache_inval_i, - output logic busy_o + output logic busy_o, + output logic ecc_error_o ); // Number of fill buffers (must be >= 2) @@ -506,12 +507,15 @@ module ibex_icache import ibex_pkg::*; #( assign ecc_write_ways = ecc_correction_ways_q; assign ecc_write_index = ecc_correction_index_q; + assign ecc_error_o = ecc_err_ic1; end else begin : gen_no_data_ecc assign ecc_err_ic1 = 1'b0; assign ecc_write_req = 1'b0; assign ecc_write_ways = '0; assign ecc_write_index = '0; assign hit_data_ic1 = hit_data_ecc_ic1; + + assign ecc_error_o = 1'b0; end /////////////////////////////// diff --git a/rtl/ibex_if_stage.sv b/rtl/ibex_if_stage.sv index 463df7c1..2bb2b127 100644 --- a/rtl/ibex_if_stage.sv +++ b/rtl/ibex_if_stage.sv @@ -87,12 +87,13 @@ module ibex_if_stage import ibex_pkg::*; #( input exc_pc_sel_e exc_pc_mux_i, // selects ISR address input exc_cause_e exc_cause, // selects ISR address for // vectorized interrupt lines - input logic dummy_instr_en_i, - input logic [2:0] dummy_instr_mask_i, - input logic dummy_instr_seed_en_i, - input logic [31:0] dummy_instr_seed_i, - input logic icache_enable_i, - input logic icache_inval_i, + input logic dummy_instr_en_i, + input logic [2:0] dummy_instr_mask_i, + input logic dummy_instr_seed_en_i, + input logic [31:0] dummy_instr_seed_i, + input logic icache_enable_i, + input logic icache_inval_i, + output logic icache_ecc_error_o, // jump and branch target input logic [31:0] branch_target_ex_i, // branch/jump target address @@ -251,7 +252,8 @@ module ibex_if_stage import ibex_pkg::*; #( .icache_enable_i ( icache_enable_i ), .icache_inval_i ( icache_inval_i ), - .busy_o ( prefetch_busy ) + .busy_o ( prefetch_busy ), + .ecc_error_o ( icache_ecc_error_o ) ); end else begin : gen_prefetch_buffer // prefetch buffer, caches a fixed number of instructions @@ -301,6 +303,7 @@ module ibex_if_stage import ibex_pkg::*; #( assign ic_data_write_o = 'b0; assign ic_data_addr_o = 'b0; assign ic_data_wdata_o = 'b0; + assign icache_ecc_error_o = 'b0; `ifndef SYNTHESIS // If we don't instantiate an icache and this is a simulation then we have a problem because the @@ -317,7 +320,6 @@ module ibex_if_stage import ibex_pkg::*; #( return 0; endfunction `endif - end assign unused_fetch_addr_n0 = fetch_addr_n[0];