summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l2err_extract.C899
1 files changed, 450 insertions, 449 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
OpenPOWER on IntegriCloud