summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/cache
diff options
context:
space:
mode:
authorThi Tran <thi@us.ibm.com>2017-07-19 14:43:43 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-08-07 23:31:32 -0400
commitacf80c098f6e3761cabc16e5ec7201625fa20319 (patch)
tree976b6a3302350462ab3a84ac3d823713084e607f /src/import/chips/p9/procedures/hwp/cache
parentf68043cd75406819352d39ca247879f04a1c9238 (diff)
downloadtalos-hostboot-acf80c098f6e3761cabc16e5ec7201625fa20319.tar.gz
talos-hostboot-acf80c098f6e3761cabc16e5ec7201625fa20319.zip
L3 Update - p9_l2err_extract/linedelete HWPs
Change-Id: I77ab2172260522a1c873ce035fd46ef4ab5ec261 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43342 Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jenny Huynh <jhuynh@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43349 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/cache')
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C899
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.H91
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.mk2
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.C311
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.H72
5 files changed, 691 insertions, 684 deletions
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C
index 68370f008..b5384a880 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C
@@ -22,524 +22,525 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-//------------------------------------------------------------------------------
-// *|
-// *! TITLE : p9_l2err_extract.C
-// *! DESCRIPTION : Parse and extract error information from L2 trace array (FAPI2)
-// *!
-// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com
-// *!
-// *! ADDITIONAL COMMENTS :
-// *! See header file for additional comments.
-//------------------------------------------------------------------------------
+///----------------------------------------------------------------------------
+///
+/// @file p9_l2err_extract.C
+///
+/// @brief Parse and extract error information from L2 trace array (FAPI)
+/// See header file for additional comments
+///
+/// *HWP HWP Owner : Chen Qian <qianqc@cn.ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Quad
+/// *HWP Consumed by : PRDF
+/// *HWP Level : 3
+///----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_l2err_extract.H>
-//#include <p9_proc_gettracearray.H>
-#include "../perv/p9_proc_gettracearray.H"
+#include <p9_proc_gettracearray.H>
#include <p9_quad_scom_addresses.H>
#include <p9_quad_scom_addresses_fld.H>
+
//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
-const uint8_t P9_L2ERR_EXTRACT_ECC_PAT[73] = { 0xc4, 0x8c, 0x94, 0xd0, 0xf4, 0xb0, 0xa8, 0xe0,
- 0x62, 0x46, 0x4a, 0x68, 0x7a, 0x58, 0x54, 0x70,
- 0x31, 0x23, 0x25, 0x34, 0x3d, 0x2c, 0x2a, 0x38,
- 0x98, 0x91, 0x92, 0x1a, 0x9e, 0x16, 0x15, 0x1c,
- 0x4c, 0xc8, 0x49, 0x0d, 0x4f, 0x0b, 0x8a, 0x0e,
- 0x26, 0x64, 0xa4, 0x86, 0xa7, 0x85, 0x45, 0x07,
- 0x13, 0x32, 0x52, 0x43, 0xd3, 0xc2, 0xa2, 0x83,
- 0x89, 0x19, 0x29, 0xa1, 0xe9, 0x61, 0x51, 0xc1,
- 0xc7, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
- };
+const uint8_t P9_L2ERR_EXTRACT_ECC_PAT[73] =
+{
+ 0xc4, 0x8c, 0x94, 0xd0, 0xf4, 0xb0, 0xa8, 0xe0,
+ 0x62, 0x46, 0x4a, 0x68, 0x7a, 0x58, 0x54, 0x70,
+ 0x31, 0x23, 0x25, 0x34, 0x3d, 0x2c, 0x2a, 0x38,
+ 0x98, 0x91, 0x92, 0x1a, 0x9e, 0x16, 0x15, 0x1c,
+ 0x4c, 0xc8, 0x49, 0x0d, 0x4f, 0x0b, 0x8a, 0x0e,
+ 0x26, 0x64, 0xa4, 0x86, 0xa7, 0x85, 0x45, 0x07,
+ 0x13, 0x32, 0x52, 0x43, 0xd3, 0xc2, 0xa2, 0x83,
+ 0x89, 0x19, 0x29, 0xa1, 0xe9, 0x61, 0x51, 0xc1,
+ 0xc7, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
const uint8_t L2ERR_MAX_CYCLES_BACK = 5;
const uint8_t L2ERR_NUM_DWS = 8;
-extern "C"
-{
-
//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
// HWP entry point
-//------------------------------------------------------------------------------
- fapi2::ReturnCode p9_l2err_extract(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
- const fapi2::variable_buffer& i_ta_data,
- p9_l2err_extract_err_type i_err_type,
- p9_l2err_extract_err_data& o_err_data,
- bool& o_error_found)
+fapi2::ReturnCode p9_l2err_extract(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const fapi2::variable_buffer& i_ta_data,
+ p9_l2err_extract_err_type i_err_type,
+ p9_l2err_extract_err_data& o_err_data,
+ bool& o_error_found)
+{
+ bool error_found = false;
+ bool ce_ue = true; //ce or ue flag
+ int32_t trace_index = 0;
+
+ //the index into the trace entry that is N cycles before the fail
+ uint32_t indexes[L2ERR_MAX_CYCLES_BACK];
+ fapi2::variable_buffer trace_array[P9_TRACEARRAY_NUM_ROWS];
+ uint8_t syndrome = 0;
+ uint8_t dw = 0;
+ uint32_t ta_length = i_ta_data.getBitLength();
+ uint32_t exp_ta_length = P9_TRACEARRAY_NUM_ROWS *
+ P9_TRACEARRAY_BITS_PER_ROW;
+ bool back_of_2to1_nextcycle = false;
+ uint8_t syndrome_col = 0;
+ uint8_t addr48_55 = 0;
+ uint8_t addr56_57 = 0;
+ uint8_t addr48 = 0;
+ uint8_t addr49 = 0;
+ uint16_t addr48_57 = 0;
+ uint16_t addr48_56 = 0;
+ uint16_t cgc = 0;
+ uint32_t addrBit2 = 0;
+ fapi2::variable_buffer address( 10 );
+ uint8_t member = 0;
+ uint8_t bank = 0;
+ uint8_t ow_select = 0;
+ bool found_dw = false;
+ uint8_t macro = 0;
+ uint8_t column = 0;
+ uint8_t bitline = 0;
+ bool is_top_sa = false;
+ bool is_left_sa = false;
+ bool odd_way = false;
+ uint8_t way_bitline_offset = 0;
+ uint32_t physical_offset = 0;
+ int32_t l_ce_trace_index = 0;
+ uint32_t indexes_index = 0;
+ uint32_t cycles = 0;
+
+
+ // mark function entry
+ FAPI_DBG("Entering p9_l2err_extract...");
+
+ // check if the supplied data is the correct size, used mostly for
+ // manual tool input
+ FAPI_ASSERT(ta_length == exp_ta_length,
+ fapi2::P9_L2ERR_EXTRACT_TA_WRONG_SIZE_ERR()
+ .set_TARGET(i_target)
+ .set_TA_DATA_SIZE(ta_length)
+ .set_EXP_TA_DATA_SIZE(exp_ta_length),
+ "Specified trace array length (%u) does not match expected length (%u)",
+ ta_length, exp_ta_length);
+
+ // build the indexable array and print out contents at the same time for debug
+ for(uint8_t i = 0; i < P9_TRACEARRAY_NUM_ROWS; i++)
{
- uint32_t rc_ecmd = 0;
- // other vars
- bool error_found = false;
- bool ce_ue = true;//ce or ue flag
- int32_t trace_index = 0;
-
- //the index into the trace entry that is N cycles before the fail
- uint32_t indexes[L2ERR_MAX_CYCLES_BACK];
- fapi2::variable_buffer trace_array[P9_TRACEARRAY_NUM_ROWS];
- uint8_t syndrome = 0;
- uint8_t dw = 0;
- uint32_t ta_length = i_ta_data.getBitLength();
- uint32_t exp_ta_length = P9_TRACEARRAY_NUM_ROWS * P9_TRACEARRAY_BITS_PER_ROW;
-
- //bool back_of_2to1 = false;
- bool back_of_2to1_nextcycle = false;
- uint8_t syndrome_col = 0;
- uint8_t addr48_55 = 0;
- uint8_t addr56_57 = 0;
- uint8_t addr48 = 0;
- uint8_t addr49 = 0;
- uint16_t addr48_57 = 0;
- uint16_t addr48_56 = 0;
- uint16_t cgc = 0;
- uint32_t addrBit2 = 0;
- fapi2::variable_buffer address( 10 );
- uint8_t member = 0;
- uint8_t bank = 0;
- uint8_t ow_select = 0;
- bool found_dw = false;
- uint8_t macro = 0;
- uint8_t column = 0;
- uint8_t bitline = 0;
- bool is_top_sa = false;
- bool is_left_sa = false;
- bool odd_way = false;
- uint8_t way_bitline_offset = 0;
- uint32_t physical_offset = 0;
-
- int32_t l_ce_trace_index = 0;
- uint32_t indexes_index = 0;
- uint32_t cycles = 0;
-
-
- // mark function entry
- FAPI_DBG("Entering p9_l2err_extract...");
-
- //check if the supplied data is the correct size, used mostly for manual tool input
- FAPI_ASSERT(!(ta_length != exp_ta_length),
- fapi2::P9_L2ERR_EXTRACT_TA_WRONG_SIZE_ERR()
- .set_TARGET(i_target)
- .set_TA_DATA_SIZE(ta_length)
- .set_EXP_TA_DATA_SIZE(exp_ta_length),
- "Specified trace array length (%i) does not match expected length (%i)",
- ta_length, exp_ta_length);
+ trace_array[i].resize(P9_TRACEARRAY_BITS_PER_ROW);
+ FAPI_TRY(i_ta_data.extract(trace_array[i],
+ P9_TRACEARRAY_BITS_PER_ROW * i,
+ P9_TRACEARRAY_BITS_PER_ROW),
+ "buffer extract() call returns an error.");
+ FAPI_DBG("%2X: 0x%016llX%016llX",
+ i, trace_array[i].get<uint64_t>( 0 ),
+ trace_array[i].get<uint64_t>( 1 ));
+ }
+
+ //********************************************************************//
+ // L2 Trace (scom 0x10012000 & 0x10012001) //
+ //********************************************************************//
+ // The array has 2 parts. Both halves matter for this code. //
+ // This code will handle both parts as a whole for simplicity. //
+ // //
+ // Three entry formats exist for bits 0:94: //
+ // ============================================ //
+ // | 0:87 | 88:94 | Format Type | //
+ // |------+-------+---------------------------| //
+ // | =0 | =0 | Compression start stamp | //
+ // | !=0 | =0 | Compression stamp | //
+ // | any | !=0 | Trace data (see below) | //
+ // ============================================ //
+ // //
+ // Notes about compression: //
+ // - The compression start stamp is set when compression is turned //
+ // on, so it will probably never be in the trace. It represents //
+ // no clock cycles so it can be ignored. //
+ // - The compression stamp indicates a repeat count that should be //
+ // added to the repeat count of the previous data entry. Since we //
+ // only care about a 12 cycle window, we can ignore compression //
+ // stamps, safe in the knowledge that the data entry itself will //
+ // have a repeat count of more than 12 cycles. //
+ // //
+ // =============================================================== //
+ // | Bits | Trace data format | //
+ // |--------+----------------------------------------------------| //
+ // | 0:55 | Don't Care (debug data) | //
+ // | 56:63 | DW (Encoded, always 1 cycle back) | //
+ // | 64 | CE Occurred | //
+ // | 65 | UE Occurred | //
+ // | 66 | back_of_2to1 bit (Determines # cycles after read) | //
+ // | 67:69 | Member (2 cycles back) | //
+ // | 70:71 | address 56:57 (56=bank, 4 cycles back) | //
+ // | 72:79 | address 48:55 (4 cycles back) | //
+ // | 80:87 | Syndrome for lowesti # DW | //
+ // | 88:94 | LFSR (counts cycles) | //
+ // | 95 | Error (FIR bit has been set) | //
+ // | 96 | tied to 0 | //
+ // | 97:103 | Trace array address (auto-increments on scom read) | //
+ // | 104 | Which trace bank is valid in banked mode | //
+ // | | 0 = addresses 0-63 are valid | //
+ // | | 1 = addresses 64-127 are valid | //
+ // | 105 | tied to 0 | //
+ // |106:111 | trace address when bank was switched in bank mode | //
+ // |112:127 | tied to 0 | //
+ // =============================================================== //
+ // //
+ //********************************************************************//
+
+ // look for CE/UE
+ error_found = false;
+ trace_index = P9_TRACEARRAY_NUM_ROWS; // the last entry in the array is the newest
+ FAPI_DBG("trace_index = %X", trace_index);
+
+ while( !error_found && (trace_index > 0) )
+ {
+ trace_index--;
- //build the indexable array and print out contents at the same time for debug
- for(uint8_t i = 0; i < P9_TRACEARRAY_NUM_ROWS; i++)
+ if (p9_tracearray_is_trace_start_marker(trace_array[trace_index]) ==
+ fapi2::FAPI2_RC_SUCCESS)
{
- trace_array[i].resize(P9_TRACEARRAY_BITS_PER_ROW);
- rc_ecmd |= i_ta_data.extract(trace_array[i], P9_TRACEARRAY_BITS_PER_ROW * i, P9_TRACEARRAY_BITS_PER_ROW);
- FAPI_DBG("%2X: 0x%016llX%016llX", i, trace_array[i].get<uint64_t>( 0 ), trace_array[i].get<uint64_t>( 1 ));
+ FAPI_DBG("Head found at trace index %i", trace_index);
+ FAPI_DBG("%2X: 0x%016llX%016llX",
+ trace_index,
+ trace_array[trace_index].get<uint64_t>( 0 ),
+ trace_array[trace_index].get<uint64_t>( 1 ));
+ error_found = false;
+ ce_ue = true;
+ break;
}
- FAPI_ASSERT(!rc_ecmd,
- fapi2::P9_L2ERR_EXTRACT_DATA_BUFFER_ERROR()
- .set_TARGET(i_target),
- "Error 0x%x extracting from trace array data buffer.",
- rc_ecmd);
-
-
- //********************************************************************//
- // L2 Trace (scom 0x10012000 & 0x10012001) //
- //********************************************************************//
- // The array has 2 parts. Both halves matter for this code. //
- // This code will handle both parts as a whole for simplicity. //
- // //
- // Three entry formats exist for bits 0:94: //
- // ============================================ //
- // | 0:87 | 88:94 | Format Type | //
- // |------+-------+---------------------------| //
- // | =0 | =0 | Compression start stamp | //
- // | !=0 | =0 | Compression stamp | //
- // | any | !=0 | Trace data (see below) | //
- // ============================================ //
- // //
- // Notes about compression: //
- // - The compression start stamp is set when compression is turned //
- // on, so it will probably never be in the trace. It represents //
- // no clock cycles so it can be ignored. //
- // - The compression stamp indicates a repeat count that should be //
- // added to the repeat count of the previous data entry. Since we //
- // only care about a 12 cycle window, we can ignore compression //
- // stamps, safe in the knowledge that the data entry itself will //
- // have a repeat count of more than 12 cycles. //
- // //
- // =============================================================== //
- // | Bits | Trace data format | //
- // |--------+----------------------------------------------------| //
- // | 0:55 | Don't Care (debug data) | //
- // | 56:63 | DW (Encoded, always 1 cycle back) | //
- // | 64 | CE Occurred | //
- // | 65 | UE Occurred | //
- // | 66 | back_of_2to1 bit (Determines # cycles after read) | //
- // | 67:69 | Member (2 cycles back) | //
- // | 70:71 | address 56:57 (56=bank, 4 cycles back) | //
- // | 72:79 | address 48:55 (4 cycles back) | //
- // | 80:87 | Syndrome for lowesti # DW | //
- // | 88:94 | LFSR (counts cycles) | //
- // | 95 | Error (FIR bit has been set) | //
- // | 96 | tied to 0 | //
- // | 97:103 | Trace array address (auto-increments on scom read) | //
- // | 104 | Which trace bank is valid in banked mode | //
- // | | 0 = addresses 0-63 are valid | //
- // | | 1 = addresses 64-127 are valid | //
- // | 105 | tied to 0 | //
- // |106:111 | trace address when bank was switched in bank mode | //
- // |112:127 | tied to 0 | //
- // =============================================================== //
- // //
- //********************************************************************//
-
- //look for CE/UE
- error_found = false;
- trace_index = P9_TRACEARRAY_NUM_ROWS; //the last entry in the array is the newest
- FAPI_DBG("trace_index = %X", trace_index);
-
- while( !error_found && (trace_index > 0) )
+ // Only look at data entries (ie ignore compression entries for now)
+ if( !trace_array[trace_index].isBitClear( 88, 7 ) )
{
- trace_index--;
-
- if (p9_tracearray_is_trace_start_marker(trace_array[trace_index]) == fapi2::FAPI2_RC_SUCCESS)
+ // Check for CE first if we are not explicitly looking for a UE
+ if ( trace_array[trace_index].isBitSet(64) &&
+ !(i_err_type == L2ERR_UE) )
{
-
- FAPI_DBG("Head found at trace index %i, no error is found!", trace_index);
- FAPI_DBG("%2X: 0x%016llX%016llX", trace_index, trace_array[trace_index].get<uint64_t>( 0 ),
+ FAPI_DBG("Found CE at trace index %i", trace_index);
+ FAPI_DBG("%2X: 0x%016llX%016llX",
+ trace_index,
+ trace_array[trace_index].get<uint64_t>( 0 ),
trace_array[trace_index].get<uint64_t>( 1 ));
- error_found = false;
+ error_found = true;
ce_ue = true;
break;
}
- //Only look at data entries (ie ignore compression entries for now)
- if( !trace_array[trace_index].isBitClear( 88, 7 ) )
+ // Check for UE second if we are not explicitly looking for a CE
+ if ( trace_array[trace_index].isBitSet(65) &&
+ !(i_err_type == L2ERR_CE) )
{
- //Check for CE first, don't check if we are explicitly looking for a UE
- if(trace_array[trace_index].isBitSet( 64 ) && !(i_err_type == L2ERR_UE))
- {
- FAPI_DBG("Found CE at trace index %i", trace_index);
- FAPI_DBG("%2X: 0x%016llX%016llX", trace_index, trace_array[trace_index].get<uint64_t>( 0 ),
- trace_array[trace_index].get<uint64_t>( 1 ));
- error_found = true;
- ce_ue = true;
- break;
- }
-
- //Check for UE second, don't check if we are explicitly looking for a CE
- if(trace_array[trace_index].isBitSet( 65 ) && !(i_err_type == L2ERR_CE))
- {
- FAPI_DBG("Found UE at trace index %i", trace_index);
- error_found = true;
- ce_ue = false;
- break;
- }
+ FAPI_DBG("Found UE at trace index %i", trace_index);
+ error_found = true;
+ ce_ue = false;
+ break;
}
- } //end loop looking for CE/UE
-
- FAPI_DBG("Found UE or CE: error_found = %i", error_found);
-
- o_error_found = error_found;
-
- // Don't panic if error is not found.
- if (!error_found)
- {
- FAPI_DBG("No error is found!");
- return fapi2::current_err;
}
- //generate compression indexes, we will use these to look back for data
- l_ce_trace_index = trace_index;
+ } //end loop looking for CE/UE
- while( (indexes_index < L2ERR_MAX_CYCLES_BACK) && (l_ce_trace_index >= 0) )
- {
- rc_ecmd |= trace_array[l_ce_trace_index].extractToRight( cycles, 88, 7 ); //LFSR
- FAPI_ASSERT(!rc_ecmd,
- fapi2::P9_L2ERR_EXTRACT_DATA_BUFFER_ERROR()
- .set_TARGET(i_target),
- "Error 0x%x extracting from trace array data buffer.",
- rc_ecmd);
-
- if( cycles != 0 )
- {
- //This is a data entry with LFSR data
- //convert LFSR to cycle count
- switch( cycles )
- {
- case 0x7F:
- cycles = 1;
- break;
-
- case 0x3F:
- cycles = 2;
- break;
-
- case 0x5F:
- cycles = 3;
- break;
-
- case 0x2F:
- cycles = 4;
- break;
-
- case 0x57:
- cycles = 5;
- break;
-
- //Only need to find a total of 4 cycles, so anything not above works
- default:
- cycles = 5;
- break;
- }
-
- FAPI_DBG("cycles = %x", cycles);
-
- //Put "trace_index" into "indexes" up to "cycles" number of times
- for( ; (cycles > 0) && (indexes_index < L2ERR_MAX_CYCLES_BACK); cycles-- )
- {
- indexes[indexes_index] = l_ce_trace_index;
- indexes_index++;
- }
- }
- else
- {
- //This is a compression stamp
- FAPI_DBG( "Skipping compression stamp\n" );
- }
+ FAPI_DBG("Found UE or CE: error_found = %i", error_found);
+ o_error_found = error_found;
+
+ // Return if error not found.
+ if (!error_found)
+ {
+ FAPI_DBG("No error is found!");
+ return fapi2::current_err;
+ }
- //Go look at the previous entry
- l_ce_trace_index--;
- } // while
+ // Generate compression indexes, we will use these to look back for data
+ l_ce_trace_index = trace_index;
+ while( (indexes_index < L2ERR_MAX_CYCLES_BACK) &&
+ (l_ce_trace_index >= 0) )
+ {
+ FAPI_TRY(trace_array[l_ce_trace_index].extractToRight( cycles, 88, 7 ), //LFSR
+ "buffer extractToRight() call returns an error.");
- for(int8_t i = L2ERR_MAX_CYCLES_BACK - 1; i >= 0; i--)
+ if( cycles != 0 )
{
- FAPI_DBG("uncomp %i cycles back: 0x%016llX%016llX", i, trace_array[indexes[i]].get<uint64_t>( 0 ),
- trace_array[indexes[i]].get<uint64_t>( 1 ));
- }
+ //This is a data entry with LFSR data
+ //convert LFSR to cycle count
+ switch( cycles )
+ {
+ case 0x7F:
+ cycles = 1;
+ break;
- //find what cycle the CE occured on and calculate location of DW data
- //p9 updated find the next cycle of back_of_2to1 CE/UE trigger
- back_of_2to1_nextcycle = trace_array[trace_index + 1].isBitSet( 66 );
+ case 0x3F:
+ cycles = 2;
+ break;
- //Get syndrome which is the cycle after the CE
- rc_ecmd = trace_array[ trace_index + 1 ].extractToRight( syndrome, 80, 8 );
+ case 0x5F:
+ cycles = 3;
+ break;
- FAPI_DBG("rc_ecmd: %#x", rc_ecmd);
- FAPI_ASSERT(!rc_ecmd,
- fapi2::P9_L2ERR_EXTRACT_SYNDROME_DATA()
- .set_TARGET(i_target),
- "Error 0x%x while extracting syndrome data.",
- rc_ecmd);
+ case 0x2F:
+ cycles = 4;
+ break;
- FAPI_ASSERT(!(ce_ue && (syndrome == 0)),
- fapi2::P9_L2ERR_EXTRACT_SYNDROME_NOT_FOUND()
- .set_TARGET(i_target)
- .set_TRACE_ARRAY_1(trace_array[ trace_index + 1 ].get<uint64_t>( 0 ))
- .set_TRACE_ARRAY_2(trace_array[ trace_index + 1 ].get<uint64_t>( 1 ))
- .set_TRACE_ARRAY_3(trace_array[ trace_index + 2 ].get<uint64_t>( 0 ))
- .set_TRACE_ARRAY_4(trace_array[ trace_index + 2 ].get<uint64_t>( 1 )),
- "Error: could not find syndrome.\nTrace cycle CE+1= 0x%016llX%016llX\nTrace cycle CE+2=%016llX%016llX",
- trace_array[ trace_index + 1 ].get<uint64_t>( 0 ),
- trace_array[ trace_index + 1 ].get<uint64_t>( 1 ),
- trace_array[ trace_index + 2 ].get<uint64_t>( 0 ),
- trace_array[ trace_index + 2 ].get<uint64_t>( 1 ));
-
- FAPI_DBG("Found syndrome: %2X", syndrome);
-
- //look up column from syndrome
- if( ce_ue )
- {
- //decodes the specified syndrome into a column offset
- bool found = false;
+ case 0x57:
+ cycles = 5;
+ break;
- //use the ECC lookup to find what column the error occured
- for( uint8_t i = 0; i < (uint8_t)(sizeof(P9_L2ERR_EXTRACT_ECC_PAT) / sizeof(uint8_t)); i++)
- {
- if( syndrome == P9_L2ERR_EXTRACT_ECC_PAT[i] )
- {
- syndrome_col = i;
- found = true;
+ // Only need to find a total of 4 cycles, so anything not above works
+ default:
+ cycles = 5;
break;
- }
}
- FAPI_ASSERT(found,
- fapi2::P9_L2ERR_EXTRACT_UNKNOWN_SYNDROME_ECC()
- .set_TARGET(i_target)
- .set_SYNDROME(syndrome),
- "Syndrome ECC is unknown. %2X", syndrome);
+ FAPI_DBG("cycles = %x", cycles);
- FAPI_DBG("syndrome_col = %u", syndrome_col);
+ // Put "trace_index" into "indexes" up to "cycles" number of times
+ for( ; (cycles > 0) && (indexes_index < L2ERR_MAX_CYCLES_BACK);
+ cycles-- )
+ {
+ indexes[indexes_index] = l_ce_trace_index;
+ indexes_index++;
+ }
}
else
{
- syndrome_col = 0;
+ //This is a compression stamp
+ FAPI_DBG( "Skipping compression stamp\n" );
}
- //get member and address data
- rc_ecmd = trace_array[ indexes[ 2 ]].extractToRight( member, 67, 3 ); // 2 cycles back
- rc_ecmd |= trace_array[ indexes[ 4 ]].extractToRight( addr48_55, 72, 8 ); // 4 cycles back
- rc_ecmd |= trace_array[ indexes[ 4 ]].extractToRight( addr56_57, 70, 2 ); // 4 cycles back
-
- rc_ecmd |= address.insertFromRight( addr48_55, 0, 8 );
- rc_ecmd |= address.insertFromRight( addr56_57, 8, 2 );
- rc_ecmd |= address.extractToRight( addr48_57, 0, 10 );
- rc_ecmd |= address.extractToRight( addr48_56, 0, 9 );
-
- // extract bank, cgc, addrBit2 from the address value
- bank = addr56_57 / 2;
- cgc = addr48_55;
- addrBit2 = ( cgc & 0x20) >> 5;
-
- FAPI_DBG("get member and address data: rc_ecmd = %i", rc_ecmd);
- FAPI_ASSERT(!rc_ecmd,
- fapi2::P9_L2ERR_EXTRACT_BUILDING_DATA_ERROR()
- .set_TARGET(i_target),
- "Error 0x%x while extracting/building address data.",
- rc_ecmd);
-
- FAPI_DBG("Found member: %i", member);
- FAPI_DBG("addr48_55=%X, addr56_57=%X, address48_57=%X", addr48_55, addr56_57, addr48_57);
- FAPI_DBG("bank = %i", bank);
-
- // calculate ow_select, determines which beat the error occurred on, first(0) or second(1)
-
- // then error occurred on second beat, otherwise first beat
- // ow_select is determined by next cycle back_of_2to1
- if(!back_of_2to1_nextcycle)
- {
- ow_select = !(addr56_57 % 2);
- }
- else
- {
- ow_select = (addr56_57 % 2);
- }
+ //Go look at the previous entry
+ l_ce_trace_index--;
+
+ } // while
- FAPI_DBG("addr56_57=%u", addr56_57);
- //find DW
- for( dw = 0; dw < L2ERR_NUM_DWS; dw++ )
+ for ( int8_t i = L2ERR_MAX_CYCLES_BACK - 1; i >= 0; i--)
+ {
+ FAPI_DBG("uncomp %i cycles back: 0x%016llX%016llX",
+ i, trace_array[indexes[i]].get<uint64_t>( 0 ),
+ trace_array[indexes[i]].get<uint64_t>( 1 ));
+ }
+
+ // Find what cycle the CE occured on and calculate location of DW data
+ // p9 updated find the next cycle of back_of_2to1 CE/UE trigger
+ back_of_2to1_nextcycle = trace_array[trace_index + 1].isBitSet( 66 );
+
+ //Get syndrome which is the cycle after the CE
+ FAPI_TRY(trace_array[ trace_index + 1 ].extractToRight( syndrome, 80, 8 ),
+ "extractToRight() Syndrome data call returns an error.");
+
+
+
+
+ FAPI_ASSERT(!(ce_ue && (syndrome == 0)),
+ fapi2::P9_L2ERR_EXTRACT_SYNDROME_NOT_FOUND()
+ .set_TARGET(i_target)
+ .set_TRACE_ARRAY_1(trace_array[ trace_index + 1 ].get<uint64_t>( 0 ))
+ .set_TRACE_ARRAY_2(trace_array[ trace_index + 1 ].get<uint64_t>( 1 ))
+ .set_TRACE_ARRAY_3(trace_array[ trace_index + 2 ].get<uint64_t>( 0 ))
+ .set_TRACE_ARRAY_4(trace_array[ trace_index + 2 ].get<uint64_t>( 1 )),
+ "Error: could not find syndrome. Trace cycle CE+1= 0x%016llX%016llX; "
+ "Trace cycle CE+2=%016llX%016llX",
+ trace_array[ trace_index + 1 ].get<uint64_t>( 0 ),
+ trace_array[ trace_index + 1 ].get<uint64_t>( 1 ),
+ trace_array[ trace_index + 2 ].get<uint64_t>( 0 ),
+ trace_array[ trace_index + 2 ].get<uint64_t>( 1 ));
+
+ FAPI_DBG("Found syndrome: %2X", syndrome);
+
+ // Look up column from syndrome
+ if ( ce_ue )
+ {
+ // Decodes the specified syndrome into a column offset
+ bool found = false;
+
+ // Use the ECC lookup to find what column the error occured
+ for( uint8_t i = 0;
+ i < (uint8_t)(sizeof(P9_L2ERR_EXTRACT_ECC_PAT) / sizeof(uint8_t));
+ i++)
{
- if((trace_array[ indexes[ 1 ] ].isBitSet( (56 + dw))))
+ if( syndrome == P9_L2ERR_EXTRACT_ECC_PAT[i] )
{
- found_dw = true;
+ syndrome_col = i;
+ found = true;
break;
}
}
- FAPI_ASSERT(found_dw,
- fapi2::P9_L2ERR_EXTRACT_DW_NOT_FOUND()
+ FAPI_ASSERT(found,
+ fapi2::P9_L2ERR_EXTRACT_UNKNOWN_SYNDROME_ECC()
.set_TARGET(i_target)
- .set_TRACE_ARRAY_1(trace_array[ indexes[ 1 ] ].get<uint64_t>( 0 ))
- .set_TRACE_ARRAY_2(trace_array[ indexes[ 1 ] ].get<uint64_t>( 1 )),
- "Error: could not find DW.\nTrace cycle CE 1 cycle back = 0x%016llX%016llX",
- trace_array[ indexes[ 1 ] ].get<uint64_t>( 0 ),
- trace_array[ indexes[ 1 ] ].get<uint64_t>( 1 ));
-
- FAPI_DBG("Found DW=%i", dw);
+ .set_SYNDROME(syndrome),
+ "Syndrome ECC is unknown. %2X", syndrome);
- //calculate macro
- if( syndrome_col <= 23 )
- {
- macro = 0;
- }
- else if( syndrome_col <= 47)
- {
- macro = 1;
- }
- else
- {
- macro = 2;
- }
-
- //calculate macro-specific column
- column = syndrome_col - ( macro * 24 );
+ FAPI_DBG("syndrome_col = %u", syndrome_col);
+ }
+ else
+ {
+ syndrome_col = 0;
+ }
+
+ // Get member and address data
+ FAPI_TRY(trace_array[ indexes[ 2 ]].extractToRight( member, 67, 3 ), // 2 cycles back
+ "extractToRight() - Member returns an error.");
+ FAPI_TRY(trace_array[ indexes[ 4 ]].extractToRight( addr48_55, 72, 8 ), // 4 cycles back
+ "extractToRight() - addr48_55 returns an error.");
+ FAPI_TRY(trace_array[ indexes[ 4 ]].extractToRight( addr56_57, 70, 2 ), // 4 cycles back
+ "extractToRight() - addr56_57 returns an error.");
+
+ FAPI_TRY(address.insertFromRight( addr48_55, 0, 8 ),
+ "insertFromRight() - addr48_55 returns an error.");
+ FAPI_TRY(address.insertFromRight( addr56_57, 8, 2 ),
+ "insertFromRight() - addr56_57 returns an error.");
+ FAPI_TRY(address.extractToRight( addr48_57, 0, 10 ),
+ "extractToRight() - addr48_57 returns an error.");
+ FAPI_TRY(address.extractToRight( addr48_56, 0, 9 ),
+ "extractToRight() - addr48_56 returns an error.");
+
+ // extract bank, cgc, addrBit2 from the address value
+ bank = addr56_57 / 2;
+ cgc = addr48_55;
+ addrBit2 = ( cgc & 0x20) >> 5;
+
+ FAPI_DBG("Found member: %i", member);
+ FAPI_DBG("addr48_55=%X, addr56_57=%X, address48_57=%X", addr48_55, addr56_57, addr48_57);
+ FAPI_DBG("bank = %i", bank);
+
+ // calculate ow_select, determines which beat the error occurred on, first(0) or second(1)
+
+ // then error occurred on second beat, otherwise first beat
+ // ow_select is determined by next cycle back_of_2to1
+ if(!back_of_2to1_nextcycle)
+ {
+ ow_select = !(addr56_57 % 2);
+ }
+ else
+ {
+ ow_select = (addr56_57 % 2);
+ }
- //calculate top/bottom subarray
- addr48 = addr48_57 >> 9; //bit 48, cgc0-127 is top, cgc128-255 is bottom
- addr49 = (addr48_57) >> 8 & 0x01;
- FAPI_DBG("addr49 = %u", addr49);
- FAPI_DBG("addr48 = %u", addr48);
+ FAPI_DBG("addr56_57=%u", addr56_57);
- // The submacros are named top_left, top_right, bottom_left, and bottom_right. A directory entry is spread across a left/right pair.
- // The top macros include congruence classes 0-127, the bottom include 128-255.
- // Parse addr48_49 to get the top/bottom, right/left information
- // Top_left = 0x00, top_right = 0x01, bottom_left = 0x10, bottom_right = 0x11. First bit is top/bottom, last bit is left/right
- if( addr48 == 0 )
- {
- is_top_sa = true;
- }
- else
+ //find DW
+ for( dw = 0; dw < L2ERR_NUM_DWS; dw++ )
+ {
+ if((trace_array[ indexes[ 1 ] ].isBitSet( (56 + dw))))
{
- is_top_sa = false;
+ found_dw = true;
+ break;
}
+ }
- if( addr49 == 0 )
- {
- is_left_sa = true;
- }
- else
- {
- is_left_sa = false;
- }
+ FAPI_ASSERT(found_dw,
+ fapi2::P9_L2ERR_EXTRACT_DW_NOT_FOUND()
+ .set_TARGET(i_target)
+ .set_TRACE_ARRAY_1(trace_array[ indexes[ 1 ] ].get<uint64_t>( 0 ))
+ .set_TRACE_ARRAY_2(trace_array[ indexes[ 1 ] ].get<uint64_t>( 1 )),
+ "Error: could not find DW.\nTrace cycle CE 1 cycle back = 0x%016llX%016llX",
+ trace_array[ indexes[ 1 ] ].get<uint64_t>( 0 ),
+ trace_array[ indexes[ 1 ] ].get<uint64_t>( 1 ));
- FAPI_DBG("L2 fail is from %s macro.", (is_top_sa) ? "top" : "bottom");
-
- // calculate bitline
- physical_offset = 2 + 4 * ( ow_select % 2) + addrBit2 + ((member & 0x1) << 1);
- bitline = physical_offset + 8 * column;
-
- FAPI_DBG("addrBit2=%u", addrBit2);
- FAPI_DBG("physical_offset=%u", physical_offset);
- FAPI_DBG("cgc=%u", cgc);
- FAPI_DBG("odd_way=%u", odd_way);
- FAPI_DBG("member=%u", member);
- FAPI_DBG("ow_select=%u", ow_select);
- FAPI_DBG("way_bitline_offset=%u", way_bitline_offset);
- FAPI_DBG("column=%u", column);
- FAPI_DBG("Found bitline=%u", bitline);
- FAPI_DBG("ce_ue value = %u", ce_ue);
-
- // print out error location information
- if( ce_ue )
- {
- FAPI_DBG("CE Location Information");
- }
- else
- {
- FAPI_DBG("UE Location Information");
- }
+ FAPI_DBG("Found DW=%i", dw);
- FAPI_DBG("\tDW = %u", dw);
- FAPI_DBG("\tBank = %u", bank);
- FAPI_DBG("\tMember = %u", member);
- FAPI_DBG("\tMacro = %u", macro);
- FAPI_DBG("\tOW_Sel = %u", ow_select);
- FAPI_DBG("\tTop SA = %s", is_top_sa ? "true" : "false");
- FAPI_DBG("\tLeft SA = %s", is_left_sa ? "true" : "false");
- FAPI_DBG("\tAddress = 0x%X", addr48_55);
- FAPI_DBG("\tBitline = %u", bitline);
- o_err_data.ce_ue = ce_ue ? L2ERR_CE : L2ERR_UE;
- o_err_data.member = member;
- o_err_data.dw = dw;
- o_err_data.macro = macro;
- o_err_data.bank = bank;
- o_err_data.ow_select = ow_select;
- o_err_data.is_top_sa = is_top_sa;
- o_err_data.is_left_sa = is_left_sa;
- o_err_data.bitline = bitline;
- o_err_data.address = addr48_55;
-
-
- // mark HWP exit
- fapi_try_exit:
- FAPI_INF("Exiting p9_l2err_extract...");
- return fapi2::current_err;
- } // p9_l2err_extract
+ //calculate macro
+ if( syndrome_col <= 23 )
+ {
+ macro = 0;
+ }
+ else if( syndrome_col <= 47)
+ {
+ macro = 1;
+ }
+ else
+ {
+ macro = 2;
+ }
+
+ //calculate macro-specific column
+ column = syndrome_col - ( macro * 24 );
+
+ //calculate top/bottom subarray
+ addr48 = addr48_57 >> 9; //bit 48, cgc0-127 is top, cgc128-255 is bottom
+ addr49 = (addr48_57) >> 8 & 0x01;
+ FAPI_DBG("addr49 = %u", addr49);
+ FAPI_DBG("addr48 = %u", addr48);
+
+ // The submacros are named top_left, top_right, bottom_left, and bottom_right. A directory entry is spread across a left/right pair.
+ // The top macros include congruence classes 0-127, the bottom include 128-255.
+ // Parse addr48_49 to get the top/bottom, right/left information
+ // Top_left = 0x00, top_right = 0x01, bottom_left = 0x10, bottom_right = 0x11. First bit is top/bottom, last bit is left/right
+ if( addr48 == 0 )
+ {
+ is_top_sa = true;
+ }
+ else
+ {
+ is_top_sa = false;
+ }
-} // extern "C"
+ if( addr49 == 0 )
+ {
+ is_left_sa = true;
+ }
+ else
+ {
+ is_left_sa = false;
+ }
+
+ FAPI_DBG("L2 fail is from %s macro.", (is_top_sa) ? "top" : "bottom");
+
+ // calculate bitline
+ physical_offset = 2 + 4 * ( ow_select % 2) + addrBit2 + ((member & 0x1) << 1);
+ bitline = physical_offset + 8 * column;
+
+ FAPI_DBG("addrBit2=%u", addrBit2);
+ FAPI_DBG("physical_offset=%u", physical_offset);
+ FAPI_DBG("cgc=%u", cgc);
+ FAPI_DBG("odd_way=%u", odd_way);
+ FAPI_DBG("member=%u", member);
+ FAPI_DBG("ow_select=%u", ow_select);
+ FAPI_DBG("way_bitline_offset=%u", way_bitline_offset);
+ FAPI_DBG("column=%u", column);
+ FAPI_DBG("Found bitline=%u", bitline);
+ FAPI_DBG("ce_ue value = %u", ce_ue);
+
+ // print out error location information
+ if( ce_ue )
+ {
+ FAPI_DBG("CE Location Information");
+ }
+ else
+ {
+ FAPI_DBG("UE Location Information");
+ }
+
+ FAPI_DBG("\tDW = %u", dw);
+ FAPI_DBG("\tBank = %u", bank);
+ FAPI_DBG("\tMember = %u", member);
+ FAPI_DBG("\tMacro = %u", macro);
+ FAPI_DBG("\tOW_Sel = %u", ow_select);
+ FAPI_DBG("\tTop SA = %s", is_top_sa ? "true" : "false");
+ FAPI_DBG("\tLeft SA = %s", is_left_sa ? "true" : "false");
+ FAPI_DBG("\tAddress = 0x%X", addr48_55);
+ FAPI_DBG("\tBitline = %u", bitline);
+ o_err_data.ce_ue = ce_ue ? L2ERR_CE : L2ERR_UE;
+ o_err_data.member = member;
+ o_err_data.dw = dw;
+ o_err_data.macro = macro;
+ o_err_data.bank = bank;
+ o_err_data.ow_select = ow_select;
+ o_err_data.is_top_sa = is_top_sa;
+ o_err_data.is_left_sa = is_left_sa;
+ o_err_data.bitline = bitline;
+ o_err_data.address = addr48_55;
+
+
+ // mark HWP exit
+fapi_try_exit:
+ FAPI_INF("Exiting p9_l2err_extract...");
+ return fapi2::current_err;
+} // p9_l2err_extract
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.H b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.H
index c40ce6a73..421dddfcd 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.H
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.H
@@ -22,29 +22,30 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-//------------------------------------------------------------------------------
-// *|
-// *! TITLE : p9_l2err_extract.H
-// *! DESCRIPTION : Parse and extract error information from L2 trace array (FAPI)
-// *!
-// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com
-// *!
-// *! ADDITIONAL COMMENTS :
-// *!
-// *! Parses the contents of the L2_T0 trace array for L2 error data.
-// *! Will look for occurances of an L2 CE or UE and capture associated data.
-// *!
-// *! Assume that the L2 trace array is set up to capture CEs/UEs, and
-// *! that it is NOT running in banked mode. Also trace must have been set to
-// *! stop on error.
-// *|
-// *! NOTE: Trace entries must be provided within data buffer from oldest->youngest entry.
-// *!
-// *! NOTE: This procedure only looks for the oldest error in the trace array. Other
-// *! errors can be present in the first or second beat of data, or for datawords
-// *! greater than the one with the first error.
-//------------------------------------------------------------------------------
-
+///----------------------------------------------------------------------------
+///
+/// @file p9_l2err_extract.H
+///
+/// @brief Parse and extract error information from L2 trace array (FAPI2)
+///
+/// Parses the contents of the L2_T0 trace array for L2 error data.
+/// Will look for occurances of an L2 CE or UE and capture associated data.
+///
+/// Assume that the L2 trace array is set up to capture CEs/UEs, and
+/// that it is NOT running in banked mode. Also trace must have been set to
+/// stop on error.
+///
+/// NOTE: Trace entries must be provided within data buffer from
+/// oldest->youngest entry. This procedure only looks for the oldest error
+/// in the trace array. Other errors can be present in the first or second
+/// beat of data, or for datawords greater than the one with the first error.
+///
+/// *HWP HWP Owner : Chen Qian <qianqc@cn.ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Quad
+/// *HWP Consumed by : PRDF
+/// *HWP Level : 3
+///----------------------------------------------------------------------------
#ifndef _P9_L2ERR_EXTRACT_H_
#define _P9_L2ERR_EXTRACT_H_
@@ -81,12 +82,12 @@ struct p9_l2err_extract_err_data
};
// function pointer typedef definition for HWP call support
-typedef fapi2::ReturnCode
-(*p9_l2err_extract_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_EX>&,
- const fapi2::variable_buffer&,
- p9_l2err_extract_err_type,
- p9_l2err_extract_err_data&,
- bool&);
+typedef fapi2::ReturnCode (*p9_l2err_extract_FP_t)
+(const fapi2::Target<fapi2::TARGET_TYPE_EX>&,
+ const fapi2::variable_buffer&,
+ p9_l2err_extract_err_type,
+ p9_l2err_extract_err_data&,
+ bool&);
extern "C"
{
@@ -94,21 +95,23 @@ extern "C"
//------------------------------------------------------------------------------
// Function prototype
//------------------------------------------------------------------------------
-
-// function: FAPI2 p9_l2err_extract HWP entry point
-// Parse and extract L2 error information from provided
-// L2_T0 trace array that has been stopped on an L2 CE or UE.
-// parameters: i_target => chiplet target for callouts
-// i_ta_data => ecmdDataBufferBase that contains the trace data
-// i_err_type => type of error that is to be extracted (CE,UE,both)
-// o_err_data => failing location information for CE or UE
-// o_error_found => error is found
-
- fapi2::ReturnCode p9_l2err_extract(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
- const fapi2::variable_buffer& i_ta_data,
- p9_l2err_extract_err_type i_err_type,
- p9_l2err_extract_err_data& o_err_data,
- bool& o_error_found);
+///
+/// @brief FAPI2 p9_l2err_extract HWP entry point
+/// Parse and extract L2 error information from provided
+/// L2_T0 trace array that has been stopped on an L2 CE or UE.
+///
+/// @param[in] i_target => EX chiplet target
+/// @param[in] i_ta_data => Input trace data buffer
+/// @param[in] i_err_type => Type of error that is to be extracted (CE,UE,both)
+/// @param[out] o_err_data => Failing location information for CE or UE
+/// @param[out] o_error_found => Error is found
+///
+ fapi2::ReturnCode p9_l2err_extract(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const fapi2::variable_buffer& i_ta_data,
+ p9_l2err_extract_err_type i_err_type,
+ p9_l2err_extract_err_data& o_err_data,
+ bool& o_error_found);
} // extern "C"
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.mk b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.mk
index db47f4b84..6e5c11817 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.mk
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.mk
@@ -23,5 +23,5 @@
#
# IBM_PROLOG_END_TAG
PROCEDURE=p9_l2err_extract
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/perv)
$(call BUILD_PROCEDURE)
-
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.C b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.C
index 520d0a51a..cbed86c4b 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.C
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.C
@@ -22,17 +22,21 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-//------------------------------------------------------------------------------
-// *|
-// *! TITLE : p9_l2err_linedelete.C
-// *! DESCRIPTION : Delete the L2 error cache line according to the error extraction information.
-// *!
-// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com
-// *!
-// *! ADDITIONAL COMMENTS :
-// *! See header file for additional comments.
-//------------------------------------------------------------------------------
+///----------------------------------------------------------------------------
+///
+/// @file p9_l2err_linedelete.C
+///
+/// @brief Delete the L2 error cache line according to the error extraction
+/// information.
+/// See more detailed description in header file.
+///
+/// *HWP HWP Owner : Chen Qian <qianqc@cn.ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Quad
+/// *HWP Consumed by : PRDF
+/// *HWP Level : 3
+///----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Includes
@@ -40,173 +44,158 @@
#include <p9_l2err_linedelete.H>
#include <p9_quad_scom_addresses.H>
#include <p9_quad_scom_addresses_fld.H>
+
//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
const uint32_t BUSY_POLL_DELAY_IN_NS = 10000000; // 10ms
const uint32_t BUSY_POLL_DELAY_IN_CYCLES = 20000000; // 10ms, assumming 2GHz
-extern "C"
-{
-
//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------
+///
+/// @brief Utility function to check for a purge operation to be completed.
+/// This function polls the EX_PRD_PURGE_CMD_REG_BUSY bit of
+/// EX_PRD_PURGE_CMD_REG.
+/// - If this bit is clear before the input loop threshold is
+/// reached, it returns FAPi2_RC_SUCCESS.
+/// - Otherwise, it returns an error code.
+///
+/// @param[in] i_target => EX chiplet target
+/// @param[in] i_busyCount => Max busy count waiting for PURGE to complete.
+/// @param[out] o_prdPurgeCmdReg => EX_PRD_PURGE_CMD_REG value.
+///
+fapi2::ReturnCode purgeCompleteCheck(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const uint64_t i_busyCount,
+ fapi2::buffer<uint64_t>& o_prdPurgeCmdReg)
+{
+ FAPI_DBG("Entering purgeCompleteCheck");
-//------------------------------------------------------------------------------
-// HWP entry point
-//------------------------------------------------------------------------------
- fapi2::ReturnCode p9_l2err_linedelete(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
- const p9_l2err_extract_err_data& i_err_data,
- const uint64_t p9_l2err_linedelete_TryBusyCounts)
- {
-
+ // Wait EX_PRD_PURGE_CMD_REG_BUSY bit for a max input counter time
+ uint64_t l_loopCount = 0;
+ do
+ {
+ FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_CMD_REG, o_prdPurgeCmdReg),
+ "Error from getScom EX_PRD_PURGE_CMD_REG");
- uint8_t member = 0;
- uint8_t bank = 0;
- uint16_t cgc = 0;
- uint64_t busy_reg_counter = 0;
- fapi2::buffer<uint64_t> l_l2_l2cerrs_prd_purge_cmd_reg;
-
- bool reg_busy = 0;
- bool prd_purge_busy = 1;
-
- // mark function entry
- FAPI_DBG("Entering p9_l2err_linedelete...");
-
- // +---------------------------+
- // | L2 Line Delete Scom |
- // +---------------------------+
- // |Bit(s)| Data |
- // +------+--------------------+
- // | 0 | Trigger |
- // +------+--------------------+
- // | 1:4 | Purge type (LD=0x2)|
- // +------+--------------------+
- // | 5:16 | Don't care |
- // +------+--------------------+
- // |17:19 | Member |
- // +------+--------------------+
- // |20:27 | CGC addr 48:55 |
- // +------+--------------------+
- // | 28 | Bank |
- // +------+--------------------+
- // |29:30 | Don't care |
- // +------+--------------------+
-
-
- member = i_err_data.member;
- bank = i_err_data.bank;
- cgc = i_err_data.address;
-
- // Write member, cgc address and bank into PRD Purge Engine Command Register
- // SCOM Addr: 0x000000001001080E
- // bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
- // bits 1:4 is ttype 0b0010 = line delete
- // bits 17:19 is the member
- // bits 20:27 is the cgc address
- // bit 28 is the bank
-
-
- FAPI_DBG("p9_l2err_linedelete_TryBusyCounts: %ld", p9_l2err_linedelete_TryBusyCounts);
-
- // wait reg_busy bit for a max counter time which is defined by user
- do
+ // Check the EX_PRD_PURGE_CMD_REG_BUSY bit from scom register
+ if ( !o_prdPurgeCmdReg.getBit(EX_PRD_PURGE_CMD_REG_BUSY) )
{
- FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_CMD_REG, l_l2_l2cerrs_prd_purge_cmd_reg),
- "Error from getScom (l_l2_l2cerrs_prd_purge_cmd_reg)");
- FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: %#lx", l_l2_l2cerrs_prd_purge_cmd_reg);
-
- // get the reg_busy bit from scom register
- l_l2_l2cerrs_prd_purge_cmd_reg.extractToRight<EX_PRD_PURGE_CMD_REG_BUSY, 1>(reg_busy);
-
- if (reg_busy == 0)
- {
- prd_purge_busy = 0;
- break;
- }
- else
- {
- busy_reg_counter = busy_reg_counter + 1;
- FAPI_DBG("reg_busy = %u, wait for 10ms and try again, remaining cout: %u!",
- reg_busy, busy_reg_counter);
- // Delay for 10ms
- fapi2::delay(BUSY_POLL_DELAY_IN_NS, BUSY_POLL_DELAY_IN_CYCLES);
- }
+ // PURGE is done, get out
+ break;
}
- while (busy_reg_counter < p9_l2err_linedelete_TryBusyCounts);
-
-
- // if the reg_busy is still 1 during the counter time
- // error occurs
- FAPI_ASSERT(!prd_purge_busy,
- fapi2::P9_L2ERR_LINE_DELETE_REG_BUSY().
- set_TARGET(i_target),
- "Error: PRD_PURGE_CMD_REG_BUSY indicats the ie completion bit was not set yet.");
-
- FAPI_DBG("reg_busy = %u", reg_busy);
-
-
- // if reg_busy is 0
- // write trigger, type, cgc address and bank into PRD Purge Engine Command Register
- if (reg_busy == 0)
+ else
{
+ l_loopCount++;
+ // Delay for 10ms
+ FAPI_TRY(fapi2::delay(BUSY_POLL_DELAY_IN_NS,
+ BUSY_POLL_DELAY_IN_CYCLES),
+ "Fapi Delay call failed.");
+ }
+ }
+ while (l_loopCount < i_busyCount);
- l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight<EX_PRD_PURGE_CMD_REG_MEM, EX_PRD_PURGE_CMD_REG_MEM_LEN>(member);
- l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight<EX_PRD_PURGE_CMD_REG_CGC, EX_PRD_PURGE_CMD_REG_CGC_LEN>(cgc);
- l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight<EX_PRD_PURGE_CMD_REG_BANK, 1>(bank);
-
- l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight<EX_PRD_PURGE_CMD_REG_TRIGGER, 1>(1);
- l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight<EX_PRD_PURGE_CMD_REG_TYPE, EX_PRD_PURGE_CMD_REG_TYPE_LEN>(0x2);
-
- FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: %#lx", l_l2_l2cerrs_prd_purge_cmd_reg);
- FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_CMD_REG, l_l2_l2cerrs_prd_purge_cmd_reg),
- "Error from putScom (l_l2_l2cerrs_prd_purge_cmd_reg)");
-
- // poll the busy bit again to ensure the purge completed
- do
- {
- FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_CMD_REG, l_l2_l2cerrs_prd_purge_cmd_reg),
- "Error from getScom (l_l2_l2cerrs_prd_purge_cmd_reg)");
- FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: %#lx", l_l2_l2cerrs_prd_purge_cmd_reg);
-
- // get the reg_busy bit from scom register
- l_l2_l2cerrs_prd_purge_cmd_reg.extractToRight<EX_PRD_PURGE_CMD_REG_BUSY, 1>(reg_busy);
-
- if (reg_busy == 0)
- {
- prd_purge_busy = 0;
- break;
- }
- else
- {
- busy_reg_counter = busy_reg_counter + 1;
- FAPI_DBG("reg_busy = %u, wait for 10ms and try again, remaining cout: %u!",
- reg_busy, busy_reg_counter);
- // Delay for 10ms
- fapi2::delay(BUSY_POLL_DELAY_IN_NS, BUSY_POLL_DELAY_IN_CYCLES);
- }
- }
- while (busy_reg_counter < p9_l2err_linedelete_TryBusyCounts);
-
- // if the reg_busy is still 1 during the counter time
- // error occurs
- FAPI_ASSERT(!prd_purge_busy,
- fapi2::P9_L2ERR_LINE_DELETE_REG_BUSY().
- set_TARGET(i_target),
- "Error: PRD_PURGE_CMD_REG_BUSY indicats the ie completion bit was not set yet, the PRD Purge Engine Command Register written failed.");
-
- FAPI_DBG("Writing PRD Purge Engine Command Register busy bit status, reg_busy = %u", reg_busy);
- //poll the busy bit completed
-
+ // Error out if still busy
+ FAPI_ASSERT(l_loopCount < i_busyCount,
+ fapi2::P9_L2ERR_LINE_DELETE_REG_BUSY()
+ .set_TARGET(i_target)
+ .set_COUNT_THRESHOLD(i_busyCount)
+ .set_PRD_PURGE_CMD_REG(o_prdPurgeCmdReg),
+ "Error: PRD_PURGE_CMD_REG_BUSY exceeds limit count of %d.",
+ i_busyCount);
- }
+fapi_try_exit:
+ FAPI_DBG("Exiting purgeCompleteCheck - Counter: %d; prdPurgeCmdReg: 0x%.16llX",
+ l_loopCount, o_prdPurgeCmdReg);
+ return fapi2::current_err;
+}
- // mark HWP exit
- fapi_try_exit:
- FAPI_INF("Exiting p9_l2err_linedelete...");
- return fapi2::current_err;
- } // p9_l2err_extract
-} // extern "C
+//------------------------------------------------------------------------------
+// HWP entry point
+//------------------------------------------------------------------------------
+// See doxygen in header file
+// TODO: RTC 178071
+// See if with some small refactoring we could just call/share the p9_l2_flush
+// HWP code/errors to implement this routine?
+fapi2::ReturnCode p9_l2err_linedelete(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const p9_l2err_extract_err_data& i_err_data,
+ const uint64_t i_busyCount)
+{
+ fapi2::buffer<uint64_t> l_l2_l2cerrs_prd_purge_cmd_reg;
+
+ // mark function entry
+ FAPI_DBG("Entering p9_l2err_linedelete. BusyCount %d", i_busyCount);
+
+ // +---------------------------+
+ // | L2 Line Delete Scom |
+ // +---------------------------+
+ // |Bit(s)| Data |
+ // +------+--------------------+
+ // | 0 | Trigger |
+ // +------+--------------------+
+ // | 1:4 | Purge type (LD=0x2)|
+ // +------+--------------------+
+ // | 5:16 | Don't care |
+ // +------+--------------------+
+ // |17:19 | Member |
+ // +------+--------------------+
+ // |20:27 | CGC addr 48:55 |
+ // +------+--------------------+
+ // | 28 | Bank |
+ // +------+--------------------+
+ // |29:30 | Don't care |
+ // +------+--------------------+
+
+ // Write member, address and bank into PRD Purge Engine Command Register
+ // SCOM Addr: 0x000000001001080E
+ // bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
+ // bits 1:4 is ttype 0b0010 = line delete
+ // bits 17:19 is the member
+ // bits 20:27 is the cgc address
+ // bit 28 is the bank
+
+ // Make sure there's no current purge is in progress
+ FAPI_TRY(purgeCompleteCheck(i_target, i_busyCount,
+ l_l2_l2cerrs_prd_purge_cmd_reg),
+ "Error returned from purgeCompleteCheck()");
+ FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: 0x%.16llX",
+ l_l2_l2cerrs_prd_purge_cmd_reg);
+
+ // write trigger, type, cgc address and bank into PRD Purge Engine Command Register
+ l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight
+ <EX_PRD_PURGE_CMD_REG_MEM, EX_PRD_PURGE_CMD_REG_MEM_LEN>
+ (i_err_data.member);
+ l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight
+ <EX_PRD_PURGE_CMD_REG_CGC, EX_PRD_PURGE_CMD_REG_CGC_LEN>
+ (i_err_data.address);
+ l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight
+ <EX_PRD_PURGE_CMD_REG_BANK, 1>(i_err_data.bank);
+
+ l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight
+ <EX_PRD_PURGE_CMD_REG_TRIGGER, 1>(1);
+ l_l2_l2cerrs_prd_purge_cmd_reg.insertFromRight
+ <EX_PRD_PURGE_CMD_REG_TYPE, EX_PRD_PURGE_CMD_REG_TYPE_LEN>(0x2);
+
+ FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: %#lx",
+ l_l2_l2cerrs_prd_purge_cmd_reg);
+ FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_CMD_REG,
+ l_l2_l2cerrs_prd_purge_cmd_reg),
+ "Error from putScom EX_PRD_PURGE_CMD_REG");
+
+
+ // Verify purge operation is complete
+ FAPI_TRY(purgeCompleteCheck(i_target, i_busyCount,
+ l_l2_l2cerrs_prd_purge_cmd_reg),
+ "Error returned from purgeCompleteCheck()");
+ FAPI_DBG("l_l2_l2cerrs_prd_purge_cmd_reg_data: 0x%.16llX",
+ l_l2_l2cerrs_prd_purge_cmd_reg);
+
+fapi_try_exit:
+ FAPI_INF("Exiting p9_l2err_linedelete...");
+ return fapi2::current_err;
+} // p9_l2err_extract
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.H b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.H
index f6ef3071b..64550e7c0 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.H
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l2err_linedelete.H
@@ -22,27 +22,31 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-//------------------------------------------------------------------------------
-// *|
-// *! TITLE : p9_l2err_linedelete.H
-// *! DESCRIPTION : Delete the L2 error cache line according to the error extraction information
-// *!
-// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com
-// *!
-// *! ADDITIONAL COMMENTS :
-// *!
-// *! Write member, cgc address and bank into PRD Purge Engine Command Register
-// *! SCOM Addr: 0x000000001001080E
-// *! bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
-// *! bits 1:4 is the ttype 0b0010 = line delete
-// *! bits 17:19 is the member
-// *| bits 20:27 is the cgc address
-// *| bit 28 is the bank
-// *|
-// *! NOTE: The error information is extracted by the HWP p9_l2err_extract.
-// *| An output data structure is dumped to this proceder and wrapped
-//------------------------------------------------------------------------------
+///----------------------------------------------------------------------------
+///
+/// @file p9_l2err_linedelete.H
+///
+/// @brief Delete the L2 error cache line according to the error extraction
+/// information.
+///
+/// Write member, cgc address and bank into PRD Purge Engine Command Register
+/// SCOM Addr: 0x000000001001080E
+/// bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
+/// bits 1:4 is the ttype 0b0010 = line delete
+/// bits 17:19 is the member
+/// bits 20:27 is the cgc address
+/// bit 28 is the bank
+///
+/// NOTE: The error information is extracted by the HWP p9_l2err_extract.
+/// An output data structure is dumped to this proceder and wrapped
+///
+/// *HWP HWP Owner : Chen Qian <qianqc@cn.ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Quad
+/// *HWP Consumed by : PRDF
+/// *HWP Level : 3
+///----------------------------------------------------------------------------
#ifndef _P9_L2ERR_LINEDELETE_H_
#define _P9_L2ERR_LINEDELETE_H_
@@ -57,19 +61,29 @@
//------------------------------------------------------------------------------
// function pointer typedef definition for HWP call support
-typedef fapi2::ReturnCode
-(*p9_l2err_linedelete_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_EX>&,
- const p9_l2err_extract_err_data&,
- const uint64_t p9_l2err_linedelete_TryBusyCounts);
+typedef fapi2::ReturnCode (*p9_l2err_linedelete_FP_t)
+(const fapi2::Target<fapi2::TARGET_TYPE_EX>&,
+ const p9_l2err_extract_err_data&,
+ const uint64_t p9_l2err_linedelete_TryBusyCounts);
extern "C"
{
-
-
- fapi2::ReturnCode p9_l2err_linedelete(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
- const p9_l2err_extract_err_data& i_err_data,
- const uint64_t p9_l2err_linedelete_TryBusyCounts);
+//------------------------------------------------------------------------------
+// Function prototype
+//------------------------------------------------------------------------------
+///
+/// @brief Perform L2 Line Delete on an EX target using input L2
+/// error data information.
+///
+/// @param[in] i_target => EX chiplet target
+/// @param[in] i_err_data => L2 error data
+/// @param[in] i_busyCount => Max busy count waiting for PURGE to complete.
+///
+ fapi2::ReturnCode p9_l2err_linedelete(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const p9_l2err_extract_err_data& i_err_data,
+ const uint64_t i_busyCount);
} // extern "C"
OpenPOWER on IntegriCloud