diff options
author | Thi Tran <thi@us.ibm.com> | 2017-07-19 14:43:43 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-08-07 23:31:32 -0400 |
commit | acf80c098f6e3761cabc16e5ec7201625fa20319 (patch) | |
tree | 976b6a3302350462ab3a84ac3d823713084e607f /src/import/chips/p9 | |
parent | f68043cd75406819352d39ca247879f04a1c9238 (diff) | |
download | talos-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')
6 files changed, 732 insertions, 737 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" diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_l2err_extract_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_l2err_extract_errors.xml index bcec46fa0..a2974fdbd 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_l2err_extract_errors.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_l2err_extract_errors.xml @@ -30,9 +30,13 @@ Procedure: p9_l2err_extract Specified trace array length does not match expected length </description> - <ffdc>TARGET</ffdc> - <ffdc>TA_DATA_SIZE</ffdc> - <ffdc>EXP_TA_DATA_SIZE</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>TA_DATA_SIZE</ffdc> + <ffdc>EXP_TA_DATA_SIZE</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> </hwpError> <!-- ******************************************************************** --> <hwpError> @@ -41,9 +45,13 @@ Procedure: p9_l2err_extract Could not find DW </description> - <ffdc>TARGET</ffdc> - <ffdc>TRACE_ARRAY_1</ffdc> - <ffdc>TRACE_ARRAY_2</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>TRACE_ARRAY_1</ffdc> + <ffdc>TRACE_ARRAY_2</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> </hwpError> <!-- ******************************************************************** --> <hwpError> @@ -52,68 +60,48 @@ Procedure: p9_l2err_extract Syndrome ECC is unknown </description> - <ffdc>TARGET</ffdc> - <ffdc>SYNDROME</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>SYNDROME</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> </hwpError> <!-- ******************************************************************** --> <hwpError> - <rc>RC_P9_L2ERR_EXTRACT_BUILDING_DATA_ERROR</rc> - <description> - Procedure: p9_l2err_extract - Error while extracting/building address data - </description> - <ffdc>TARGET</ffdc> - </hwpError> - <!-- ******************************************************************** --> - <hwpError> - <rc>RC_P9_L2ERR_EXTRACT_DATA_BUFFER_ERROR</rc> - <description> - Procedure: p9_l2err_extract - Error while extracting from trace array data buffer - </description> - <ffdc>TARGET</ffdc> - </hwpError> - <!-- ******************************************************************** --> - <hwpError> - <rc>RC_P9_L2ERR_EXTRACT_NO_CEUE_FOUND</rc> - <description> - Procedure: p9_l2err_extract - No CE or UE found in trace array - </description> - <ffdc>TARGET</ffdc> - <ffdc>TA_DATA</ffdc> - <ffdc>ERR_REQ_TYPE</ffdc> - </hwpError> - <!-- ******************************************************************** --> - <hwpError> <rc>RC_P9_L2ERR_EXTRACT_SYNDROME_NOT_FOUND</rc> <description> Procedure: p9_l2err_extract Could not find syndrome </description> - <ffdc>TARGET</ffdc> - <ffdc>TRACE_ARRAY_1</ffdc> - <ffdc>TRACE_ARRAY_2</ffdc> - <ffdc>TRACE_ARRAY_3</ffdc> - <ffdc>TRACE_ARRAY_4</ffdc> - </hwpError> - <!-- ******************************************************************** --> - <hwpError> - <rc>RC_P9_L2ERR_EXTRACT_SYNDROME_DATA</rc> - <description> - Procedure: p9_l2err_extract - Error while extracting syndrome data - </description> - <ffdc>TARGET</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>TRACE_ARRAY_1</ffdc> + <ffdc>TRACE_ARRAY_2</ffdc> + <ffdc>TRACE_ARRAY_3</ffdc> + <ffdc>TRACE_ARRAY_4</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> </hwpError> <!-- ******************************************************************** --> <hwpError> <rc>RC_P9_L2ERR_LINE_DELETE_REG_BUSY</rc> <description> Procedure: p9_l2err_linedelete - Error while try to update PRD Purge Engine Command Register + Time out waiting for PRD L2 Purge engine busy bit. </description> - <ffdc>TARGET</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>COUNT_THRESHOLD</ffdc> + <ffdc>PRD_PURGE_CMD_REG</ffdc> + <callout> + <target>TARGET</target> + <priority>HIGH</priority> + </callout> + <callout> + <procedure>CODE</procedure> + <priority>LOW</priority> + </callout> </hwpError> <!-- ******************************************************************** --> </hwpErrors> |