From 75333b1d93a30e2337fb5580357ff32733d28db3 Mon Sep 17 00:00:00 2001 From: Thi Tran Date: Wed, 19 Jul 2017 16:07:56 -0500 Subject: L3 Update - p9_l3err_extract/linedelete HWPs Change-Id: I89326a036291b5d298f1e4ce0936965e6dbdbd07 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43348 Tested-by: Jenkins Server Tested-by: Hostboot CI Reviewed-by: Joseph J. McGill Reviewed-by: Jenny Huynh Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43350 Reviewed-by: Hostboot Team Tested-by: Jenkins OP Build CI Tested-by: FSP CI Jenkins Tested-by: Jenkins OP HW Reviewed-by: Daniel M. Crowell --- .../p9/procedures/hwp/cache/p9_l3err_extract.C | 510 +++++++++++---------- .../p9/procedures/hwp/cache/p9_l3err_extract.H | 51 ++- .../p9/procedures/hwp/cache/p9_l3err_linedelete.C | 300 ++++++------ .../p9/procedures/hwp/cache/p9_l3err_linedelete.H | 68 +-- 4 files changed, 473 insertions(+), 456 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/cache') diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.C b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.C index aa118a1f0..f245c3166 100644 --- a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.C +++ b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.C @@ -22,17 +22,19 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -//------------------------------------------------------------------------------ -// *| -// *! TITLE : p9_l3err_extract.C -// *! DESCRIPTION : Parse and extract error information from Scom Registers (FAPI2) -// *! -// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com -// *! -// *! ADDITIONAL COMMENTS : -// *! See header file for additional comments. -//------------------------------------------------------------------------------ +///---------------------------------------------------------------------------- +/// +/// @file p9_l3err_extract.C +/// +/// @brief Parse and extract error information from L3 Scom Registers (FAPI2) +/// +/// *HWP HWP Owner : Chen Qian +/// *HWP FW Owner : Thi Tran +/// *HWP Team : Quad +/// *HWP Consumed by : HB +/// *HWP Level : 3 +///---------------------------------------------------------------------------- //------------------------------------------------------------------------------ // Includes @@ -45,310 +47,316 @@ // Constant definitions //------------------------------------------------------------------------------ const uint8_t P9_L3_HALF_MACRO_INDEX = 73; -const uint8_t P9_L3ERR_EXTRACT_ECC_PAT[P9_L3_HALF_MACRO_INDEX] = { 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_L3ERR_EXTRACT_ECC_PAT[P9_L3_HALF_MACRO_INDEX] = +{ + 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 L3ERR_MAX_CYCLES_BACK = 13; const uint8_t L3ERR_NUM_DWS = 8; -extern "C" -{ - //------------------------------------------------------------------------------ // Function definitions //------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// HWP entry point -//------------------------------------------------------------------------------ - fapi2::ReturnCode p9_l3err_extract(const fapi2::Target& i_target, - p9_l3err_extract_err_data& o_err_data, - bool& o_error_found) - { +// See doxygen in header file +fapi2::ReturnCode p9_l3err_extract( + const fapi2::Target& i_target, + p9_l3err_extract_err_data& o_err_data, + bool& o_error_found) +{ - fapi2::buffer l_l3eDRAM_rd_err_stat_data0; - fapi2::buffer l_l3eDRAM_rd_err_stat_data1; + fapi2::buffer l_l3eDRAM_rd_err_stat_data0; + fapi2::buffer l_l3eDRAM_rd_err_stat_data1; - uint8_t err_1st_beat_syndrome = 0; - uint8_t err_2nd_beat_syndrome = 0; - uint8_t syndrome = 0; - bool err_in_first_beat = 0; - uint8_t even_odd = 0; + uint8_t err_1st_beat_syndrome = 0; + uint8_t err_2nd_beat_syndrome = 0; + uint8_t syndrome = 0; + bool err_in_first_beat = 0; + uint8_t even_odd = 0; - bool err_stat_val = 0; - bool err_stat_1st_beat_UE = 0; - bool err_stat_2nd_beat_UE = 0; - uint8_t err_stat_dw = 0; - uint8_t err_stat_dw_odd = 0; - uint8_t dw = 0; - uint16_t err_stat_ra = 0; - uint8_t err_stat_bank = 0; + bool err_stat_val = 0; + bool err_stat_1st_beat_UE = 0; + bool err_stat_2nd_beat_UE = 0; + uint8_t err_stat_dw = 0; + uint8_t err_stat_dw_odd = 0; + uint8_t dw = 0; + uint16_t err_stat_ra = 0; + uint8_t err_stat_bank = 0; - uint8_t dataout = 0; - uint8_t syndrome_col = 0; - uint8_t member = 0; - uint8_t member_select = 0; - uint8_t read_select = 0; - bool ce_ue = true; - bool sue = false; + uint8_t dataout = 0; + uint8_t syndrome_col = 0; + uint8_t member = 0; + uint8_t member_select = 0; + uint8_t read_select = 0; + bool ce_ue = true; + bool sue = false; - uint16_t real_address45_52 = 0; - uint16_t real_address53_54 = 0; - uint16_t real_address55 = 0; - uint16_t real_address56 = 0; - uint16_t real_address45_56 = 0; + uint16_t real_address45_52 = 0; + uint16_t real_address53_54 = 0; + uint16_t real_address55 = 0; + uint16_t real_address56 = 0; + uint16_t real_address45_56 = 0; - // mark function entry - FAPI_DBG("Entering ..."); + // mark function entry + FAPI_DBG("Entering ..."); - // Get the values of l3eDRAM_rd_err_stat_register_0 & l3eDRAM_rd_err_stat_register_1 - FAPI_TRY(fapi2::getScom(i_target, EX_ED_RD_ERR_STAT_REG0, l_l3eDRAM_rd_err_stat_data0), - "Error from getScom (L3_eDRAM_RD_ERR_STAT_Register_0)"); + // Get the values of l3eDRAM_rd_err_stat_register_0 & l3eDRAM_rd_err_stat_register_1 + FAPI_TRY(fapi2::getScom(i_target, EX_ED_RD_ERR_STAT_REG0, l_l3eDRAM_rd_err_stat_data0), + "Error from getScom (L3_eDRAM_RD_ERR_STAT_Register_0)"); - FAPI_TRY(fapi2::getScom(i_target, EX_L3_ED_RD_ERR_STAT_REG1, l_l3eDRAM_rd_err_stat_data1), - "Error from getScom (L3_eDRAM_RD_ERR_STAT_Register_1)"); + FAPI_TRY(fapi2::getScom(i_target, EX_L3_ED_RD_ERR_STAT_REG1, l_l3eDRAM_rd_err_stat_data1), + "Error from getScom (L3_eDRAM_RD_ERR_STAT_Register_1)"); - FAPI_DBG("l_l3eDRAM_rd_err_stat_data0: %#lx", l_l3eDRAM_rd_err_stat_data0); - FAPI_DBG("l_l3eDRAM_rd_err_stat_data1: %#lx", l_l3eDRAM_rd_err_stat_data1); + FAPI_DBG("l_l3eDRAM_rd_err_stat_data0: %#lx", l_l3eDRAM_rd_err_stat_data0); + FAPI_DBG("l_l3eDRAM_rd_err_stat_data1: %#lx", l_l3eDRAM_rd_err_stat_data1); - // err_stat_val, err_stat_1st_beat_UE, err_stat_2nd_beat_UE - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_stat_val); + // err_stat_val, err_stat_1st_beat_UE, err_stat_2nd_beat_UE + l_l3eDRAM_rd_err_stat_data0.extractToRight + (err_stat_val); - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_stat_1st_beat_UE); + l_l3eDRAM_rd_err_stat_data0.extractToRight + (err_stat_1st_beat_UE); - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_stat_2nd_beat_UE); + l_l3eDRAM_rd_err_stat_data0.extractToRight + (err_stat_2nd_beat_UE); - FAPI_DBG("err_stat_val = %x", err_stat_val); + FAPI_DBG("err_stat_val = %x", err_stat_val); + o_error_found = err_stat_val; - o_error_found = err_stat_val; + // Return if no CE or UE error found by Scom registers + if (!err_stat_val) + { + FAPI_DBG ("No error is found!"); + return fapi2::current_err; + } - // Dont's panic if no CE or UE error found by Scom registers - if (!err_stat_val) - { - FAPI_DBG ("No error is found!"); - return fapi2::current_err; - } + // syndrome value + l_l3eDRAM_rd_err_stat_data0.extractToRight + + (err_1st_beat_syndrome); - // syndrome value - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_1st_beat_syndrome); + l_l3eDRAM_rd_err_stat_data0.extractToRight + + (err_2nd_beat_syndrome); - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_2nd_beat_syndrome); + //check the first beat of data for bad syndrome + FAPI_DBG("Checking first beat for syndrome data."); - //check the first beat of data for bad syndrome - FAPI_DBG("Checking first beat for syndrome data."); + if( err_1st_beat_syndrome == 0) + { + FAPI_DBG("Checking second beat for syndrome data."); + syndrome = err_2nd_beat_syndrome; + ce_ue = !(err_stat_2nd_beat_UE); - if( err_1st_beat_syndrome == 0) + if (ce_ue == false) { - FAPI_DBG("Checking second beat for syndrome data."); - syndrome = err_2nd_beat_syndrome; - ce_ue = !(err_stat_2nd_beat_UE); - - if (ce_ue == false) + if (err_2nd_beat_syndrome == 0xFE) { - if (err_2nd_beat_syndrome == 0xFE) - { - sue = true; - } - else - { - sue = false; - } + sue = true; + } + else + { + sue = false; } - } - else - { - syndrome = err_1st_beat_syndrome; - err_in_first_beat = 1; - ce_ue = !(err_stat_1st_beat_UE); - if (ce_ue == false) + } + else + { + syndrome = err_1st_beat_syndrome; + err_in_first_beat = 1; + ce_ue = !(err_stat_1st_beat_UE); + + if (ce_ue == false) + { + if (err_1st_beat_syndrome == 0xFE) + { + sue = true; + } + else { - if (err_1st_beat_syndrome == 0xFE) - { - sue = true; - } - else - { - sue = false; - } + sue = false; } } + } - // if could not find syndrome - FAPI_ASSERT(!(syndrome == 0), - fapi2::P9_L3ERR_EXTRACT_SYNDROME_NOT_FOUND(). - set_TARGET(i_target), - "Error: could not find syndrome"); + // if could not find syndrome + FAPI_ASSERT(syndrome, + fapi2::P9_L3ERR_EXTRACT_SYNDROME_NOT_FOUND() + .set_TARGET(i_target) + .set_FIRST_BEAT_SYNDROME(err_1st_beat_syndrome) + .set_SECOND_BEAT_SYNDROME(err_2nd_beat_syndrome), + "Error: could not find syndrome. " + "1st beat syndrome 0x%.8X, 2nd beat syndrome 0x%.8X", + err_1st_beat_syndrome, err_2nd_beat_syndrome); - FAPI_DBG("Found syndrome: %2X", syndrome); + FAPI_DBG("Found syndrome: %2X", syndrome); - // read_select value - l_l3eDRAM_rd_err_stat_data1.extractToRight<13, 1> - (read_select); + // read_select value + l_l3eDRAM_rd_err_stat_data1.extractToRight<13, 1>(read_select); - //calculate dataout (column) - if( err_in_first_beat ) - { - even_odd = read_select; - } - else - { - even_odd = !read_select; - } + //calculate dataout (column) + if( err_in_first_beat ) + { + even_odd = read_select; + } + else + { + even_odd = !read_select; + } - FAPI_DBG("readselect=%u,err_in_first_beat=%s,even_odd=%u", read_select, err_in_first_beat ? "true" : "false", even_odd); + FAPI_DBG("readselect=%u,err_in_first_beat=%s,even_odd=%u", + read_select, err_in_first_beat ? "true" : "false", even_odd); - //if a CE occurred, process the syndrome - if( ce_ue ) - { - //decodes the specified syndrome into a column offset - bool found = false; + //if a CE occurred, process the 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_L3ERR_EXTRACT_ECC_PAT) / sizeof(uint8_t)); i++) + //use the ECC lookup to find what column the error occured + for( uint8_t i = 0; + i < (uint8_t)(sizeof(P9_L3ERR_EXTRACT_ECC_PAT) / sizeof(uint8_t)); + i++) + { + if( syndrome == P9_L3ERR_EXTRACT_ECC_PAT[i] ) { - if( syndrome == P9_L3ERR_EXTRACT_ECC_PAT[i] ) - { - syndrome_col = i; - found = true; - break; - } + syndrome_col = i; + found = true; + break; } - - // if the syndrome_col value can not found in the P9_L3ERR_EXTRACT_ECC_PAT - FAPI_ASSERT(found, - fapi2::P9_L3ERR_EXTRACT_UNKNOWN_SYNDROME_ECC(). - set_TARGET(i_target). - set_SYNDROME(syndrome), - "Syndrome ECC is unknown. %2X", syndrome); - - FAPI_DBG("syndrome_col = %u", syndrome_col); - // caculate the dataout - dataout = ( syndrome_col * 2 ) + even_odd; - } - else - { - dataout = 0; } - // dw, ra and member_select - // l_l3eDRAM_rd_err_stat_register0[20] says whether dw is even/odd - // l_l3eDRAM_rd_err_stat_register0[21:22] encode which of the 4 DW's on an even/odd side - l_l3eDRAM_rd_err_stat_data0.extractToRight < EX_ED_RD_ERR_STAT_REG0_L3_DW + 1, 2 > - (err_stat_dw); - l_l3eDRAM_rd_err_stat_data0.extractToRight - (err_stat_dw_odd); + // if the syndrome_col value can not found in the P9_L3ERR_EXTRACT_ECC_PAT + FAPI_ASSERT(found, + fapi2::P9_L3ERR_EXTRACT_UNKNOWN_SYNDROME_ECC(). + set_TARGET(i_target). + set_SYNDROME(syndrome), + "Syndrome ECC is unknown. %2X", syndrome); + + FAPI_DBG("syndrome_col = %u", syndrome_col); + // caculate the dataout + dataout = ( syndrome_col * 2 ) + even_odd; + } + else + { + dataout = 0; + } + + // dw, ra and member_select + // l_l3eDRAM_rd_err_stat_register0[20] says whether dw is even/odd + // l_l3eDRAM_rd_err_stat_register0[21:22] encode which of the 4 DW's on an even/odd side + l_l3eDRAM_rd_err_stat_data0.extractToRight < EX_ED_RD_ERR_STAT_REG0_L3_DW + 1, 2 > + (err_stat_dw); + l_l3eDRAM_rd_err_stat_data0.extractToRight + (err_stat_dw_odd); + + if( err_stat_dw_odd == 1) + { + dw = err_stat_dw * 2 + 1; // odd side + } + else + { + dw = err_stat_dw * 2; // even side + } - if( err_stat_dw_odd == 1) - { - dw = err_stat_dw * 2 + 1; // odd side - } - else - { - dw = err_stat_dw * 2; // even side - } + l_l3eDRAM_rd_err_stat_data1.extractToRight + (err_stat_ra); - l_l3eDRAM_rd_err_stat_data1.extractToRight - (err_stat_ra); + l_l3eDRAM_rd_err_stat_data1.extractToRight + (err_stat_bank); - l_l3eDRAM_rd_err_stat_data1.extractToRight - (err_stat_bank); - l_l3eDRAM_rd_err_stat_data1.extractToRight<12, 1> - (member_select); + l_l3eDRAM_rd_err_stat_data1.extractToRight<12, 1>(member_select); - if(member_select) - { - member = err_stat_bank + 10; - } - else + if(member_select) + { + member = err_stat_bank + 10; + } + else + { + member = err_stat_bank; + } + + // Translate cache read address to real address first + // The EDRAM read-address is made up of edram_ra(0:9) & edram_ca(0:2) & edram_rs. + // Edram_ra(0:9) are taken from hashed address(56, 55, 45:52) + // Edram_ca(0:2) are taken from hashed address(53:54)& memberGroup (member 0-9 vs.10-19) + // Edram_rs is taken from address(57) + real_address45_52 = err_stat_ra & (0x0FF0); + real_address53_54 = err_stat_ra & (0x000C); + real_address55 = (err_stat_ra & (0x1000)) >> 11; + real_address56 = (err_stat_ra & (0x2000)) >> 13; + real_address45_56 = real_address45_52 | real_address53_54 | real_address55 | real_address56; + + //print out error location information + if( ce_ue ) + { + FAPI_DBG("CE Location Information"); + } + else + { + if(!sue) { - member = err_stat_bank; - } - // Translate cache read address to real address first - // The EDRAM read-address is made up of edram_ra(0:9) & edram_ca(0:2) & edram_rs. - // Edram_ra(0:9) are taken from hashed address(56, 55, 45:52) - // Edram_ca(0:2) are taken from hashed address(53:54)& memberGroup (member 0-9 vs.10-19) - // Edram_rs is taken from address(57) - real_address45_52 = err_stat_ra & (0x0FF0); - real_address53_54 = err_stat_ra & (0x000C); - real_address55 = (err_stat_ra & (0x1000)) >> 11; - real_address56 = (err_stat_ra & (0x2000)) >> 13; - real_address45_56 = real_address45_52 | real_address53_54 | real_address55 | real_address56; - - //print out error location information - if( ce_ue ) - { - FAPI_DBG("CE Location Information"); + FAPI_DBG("UE Location Information"); } else { - if(!sue) - { - - FAPI_DBG("UE Location Information"); - } - else - { - FAPI_DBG("SUE Location Information"); - } - + FAPI_DBG("SUE Location Information"); } - FAPI_DBG("\tDW = %u", dw); - FAPI_DBG("\tBank = %u", err_stat_bank); - FAPI_DBG("\tMember = %u", member); - FAPI_DBG("\tCache Read Address = 0x%X", err_stat_ra); - FAPI_DBG("\tHashed Real Address (45:56) = 0x%X", real_address45_56); - FAPI_DBG("\tDataout = 0x%X", dataout); + } + + FAPI_DBG("DW = %u", dw); + FAPI_DBG("Bank = %u", err_stat_bank); + FAPI_DBG("Member = %u", member); + FAPI_DBG("Cache Read Address = 0x%X", err_stat_ra); + FAPI_DBG("Hashed Real Address (45:56) = 0x%X", real_address45_56); + FAPI_DBG("Dataout = 0x%X", dataout); - // output error data - //o_err_data.ce_ue = ce_ue ? L3ERR_CE : L3ERR_UE; - if (ce_ue) + // output error data + //o_err_data.ce_ue = ce_ue ? L3ERR_CE : L3ERR_UE; + if (ce_ue) + { + o_err_data.ce_ue = L3ERR_CE; + } + else + { + if(!sue) { - o_err_data.ce_ue = L3ERR_CE; + o_err_data.ce_ue = L3ERR_UE; } else { - if(!sue) - { - o_err_data.ce_ue = L3ERR_UE; - } - else - { - o_err_data.ce_ue = L3ERR_SUE; - } + o_err_data.ce_ue = L3ERR_SUE; } - - o_err_data.member = member; - o_err_data.dw = dw; - o_err_data.bank = err_stat_bank; - o_err_data.dataout = dataout; - o_err_data.hashed_real_address_45_56 = real_address45_56; - o_err_data.cache_read_address = err_stat_ra; - - fapi_try_exit: - // mark HWP exit - FAPI_DBG("Exiting ..."); - return fapi2::current_err; - } // p9_l3err_extract - -} // extern "C" - + } + + o_err_data.member = member; + o_err_data.dw = dw; + o_err_data.bank = err_stat_bank; + o_err_data.dataout = dataout; + o_err_data.hashed_real_address_45_56 = real_address45_56; + o_err_data.cache_read_address = err_stat_ra; + +fapi_try_exit: + // mark HWP exit + FAPI_DBG("Exiting ..."); + return fapi2::current_err; +} // p9_l3err_extract diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.H b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.H index 823c3463b..3f03919d3 100644 --- a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.H +++ b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_extract.H @@ -22,17 +22,19 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -//------------------------------------------------------------------------------ -// *| -// *! TITLE : p3_l3err_extract.H -// *! DESCRIPTION : Parse and extract error information from L3 Scom Register (FAPI2) -// *! -// *! OWNER NAME : Chen Qian Email: qianqc@cn.ibm.com -// *! -// *! ADDITIONAL COMMENTS : -// *! -//------------------------------------------------------------------------------ +///---------------------------------------------------------------------------- +/// +/// @file p9_l3err_extract.H +/// +/// @brief Parse and extract error information from L3 Scom Registers (FAPI2) +/// +/// *HWP HWP Owner : Chen Qian +/// *HWP FW Owner : Thi Tran +/// *HWP Team : Quad +/// *HWP Consumed by : HB +/// *HWP Level : 3 +///---------------------------------------------------------------------------- #ifndef _P9_L3ERR_EXTRACT_H_ #define _P9_L3ERR_EXTRACT_H_ @@ -67,9 +69,10 @@ struct p9_l3err_extract_err_data }; // function pointer typedef definition for HWP call support -typedef fapi2::ReturnCode (*p9_l3err_extract_FP_t)( const fapi2::Target& i_target, - p9_l3err_extract_err_data& o_err_data, - bool& o_err_found); +typedef fapi2::ReturnCode (*p9_l3err_extract_FP_t)( + const fapi2::Target& i_target, + p9_l3err_extract_err_data& o_err_data, + bool& o_err_found); extern "C" { @@ -78,16 +81,18 @@ extern "C" // Function prototype //------------------------------------------------------------------------------ -// function: FAPI p9_l3err_extract HWP entry point -// Parse and extract L3 error information from provided -// parameters: i_ex_chiplet => chiplet target used for callouts -// 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_err_found => error is found - - fapi2::ReturnCode p9_l3err_extract(const fapi2::Target& i_target, - p9_l3err_extract_err_data& o_err_data, - bool& o_error_found); +/// +/// @brief FAPI p9_l3err_extract HWP entry point +/// Parse and extract L3 error information from provided +/// +/// @param[in] i_target => EX chiplet target +/// @param[out] o_err_data => Failing location information for CE or UE +/// @param[out] o_error_found => Error is found +/// + fapi2::ReturnCode p9_l3err_extract( + const fapi2::Target& i_target, + p9_l3err_extract_err_data& o_err_data, + bool& o_error_found); } // extern "C" diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C index ba2240e8a..7409c41db 100644 --- a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C +++ b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C @@ -22,17 +22,21 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -//------------------------------------------------------------------------------ -// *| -// *! TITLE : p9_l3err_linedelete.C -// *! DESCRIPTION : Delete the L3 error cache line according to the error extraction information. -// *! -// *! OWNER NAME : Alex Taft Email: amtaft@us.ibm.com -// *! -// *! ADDITIONAL COMMENTS : -// *! See header file for additional comments. -//------------------------------------------------------------------------------ +///---------------------------------------------------------------------------- +/// +/// @file p9_l3err_linedelete.H +/// +/// @brief Delete the L3 error cache line according to the error extraction +/// information. +/// See header file for detailed description. +/// +/// *HWP HWP Owner : Alex Taft +/// *HWP FW Owner : Thi Tran +/// *HWP Team : Quad +/// *HWP Consumed by : PRDF +/// *HWP Level : 3 +///---------------------------------------------------------------------------- //------------------------------------------------------------------------------ // Includes @@ -46,161 +50,145 @@ 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 L3 purge operation to be completed. +/// This function polls the EX_PRD_PURGE_REG_L3_REQ bit of +/// EX_PRD_PURGE_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_prdPurgeReg => EX_PRD_PURGE_CMD_REG value. +/// +fapi2::ReturnCode l3PurgeCompleteCheck( + const fapi2::Target& i_target, + const uint64_t i_busyCount, + fapi2::buffer& o_prdPurgeReg) +{ + FAPI_DBG("Entering l3PurgeCompleteCheck"); -//------------------------------------------------------------------------------ -// HWP entry point -//------------------------------------------------------------------------------ - fapi2::ReturnCode p9_l3err_linedelete(const fapi2::Target& i_target, - const p9_l3err_extract_err_data& i_err_data, - const uint64_t p9_l3err_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_REG, o_prdPurgeReg), + "Error from getScom EX_PRD_PURGE_REG"); - uint8_t member = 0; - uint16_t cgc = 0; - uint64_t busy_reg_counter = 0; - fapi2::buffer l_l3_l3cerrs_prd_purge_reg; - - bool reg_busy = 0; - bool prd_purge_busy = 1; - - // mark function entry - FAPI_DBG("Entering p9_l3err_linedelete..."); - - - // +---------------------------+ - // | L3 Line Delete Scom | - // +---------------------------+ - // |Bit(s)| Data | - // +------+--------------------+ - // | 0 | Trigger | - // +------+--------------------+ - // | 1:4 | Purge type (ld=0x2)| - // +------+--------------------+ - // | 5:8 | Don't care | - // +------+--------------------+ - // | 9 | Busy Error | - // +------+--------------------+ - // |12:16 | Member (1 of 20) | - // +------+--------------------+ - // |17:28 | CGC (addr 45:56) | - // +------+--------------------+ - // |29:63 | Don't care | - // +------+--------------------+ - - - member = i_err_data.member; - cgc = i_err_data.hashed_real_address_45_56; - - // EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG - // Write member, cgc address into PRD Purge Engine Command Register - // SCOM Addr: 0x000000001001180E - // 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 12:16 is the member - // bits 17:28 is the cgc address - - - FAPI_DBG("p9_l3err_linedelete_TryBusyCounts: %ld", p9_l3err_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_prdPurgeReg.getBit(EX_PRD_PURGE_REG_L3_REQ) ) { - FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg), - "Error from getScom (l_l3_l3cerrs_prd_purge_reg)"); - FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg); - - // get the reg_busy bit from scom register - l_l3_l3cerrs_prd_purge_reg.extractToRight(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_l3err_linedelete_TryBusyCounts); - - - // if the reg_busy is still 1 during the counter time - // error occurs - FAPI_ASSERT(!prd_purge_busy, - fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY(). - set_TARGET(i_target), - "Error: hit timeout. PRD_PURGE_REG still working on a previous purge."); - - FAPI_DBG("reg_busy = %u", reg_busy); - - - // if reg_busy is 0 - // write trigger, type, cgc address, member into PRD Purge Engine Command Register - if (reg_busy == 0) + else { - - l_l3_l3cerrs_prd_purge_reg.insertFromRight(member); - l_l3_l3cerrs_prd_purge_reg.insertFromRight(cgc); - - l_l3_l3cerrs_prd_purge_reg.insertFromRight(1); - l_l3_l3cerrs_prd_purge_reg.insertFromRight(0x2); - - FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg); - FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg), - "Error from putScom (l_l3_l3cerrs_prd_purge_reg)"); - - do - { - FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg), - "Error from getScom (l_l3_l3cerrs_prd_purge_reg)"); - FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg); - - // get the reg_busy bit from scom register - l_l3_l3cerrs_prd_purge_reg.extractToRight(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_l3err_linedelete_TryBusyCounts); - - // if the reg_busy is still 1 during the counter time - // error occurs - FAPI_ASSERT(!prd_purge_busy, - fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY(). - set_TARGET(i_target), - "Error: PRD_PURGE_REG indicates the ie compelteion bit was not set yet, the PRD Purge Engine Command Regiter write failed."); - - FAPI_DBG("Writing PRD Purge Engine Command Register busy bit status, reg_busy = %u", reg_busy); - // poll the busy bit completed - + 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); + + // Error out if still busy + FAPI_ASSERT(l_loopCount < i_busyCount, + fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY() + .set_TARGET(i_target) + .set_COUNT_THRESHOLD(i_busyCount) + .set_PRD_PURGE_REG(o_prdPurgeReg), + "Error: PRD_PURGE_CMD_REG_BUSY exceeds limit count of %d.", + i_busyCount); + +fapi_try_exit: + FAPI_DBG("Exiting l3PurgeCompleteCheck - Counter: %d; prdPurgeReg: 0x%.16llX", + l_loopCount, o_prdPurgeReg); + return fapi2::current_err; +} - // mark HWP exit - fapi_try_exit: - FAPI_INF("Exiting p9_l3err_linedelete..."); - return fapi2::current_err; - } // p9_l3err_extract +//------------------------------------------------------------------------------ +// HWP entry point +//------------------------------------------------------------------------------ +// See doxygen in header file +// TODO: RTC 178071 +// See if with some small refactoring we could just call/share the p9_l3_flush +// HWP code/errors to implement this routine? +fapi2::ReturnCode p9_l3err_linedelete( + const fapi2::Target& i_target, + const p9_l3err_extract_err_data& i_err_data, + const uint64_t i_busyCount) +{ -} // extern "C + // mark function entry + FAPI_DBG("Entering p9_l3err_linedelete: i_busyCount: %ld", i_busyCount); + + fapi2::buffer l_l3_l3cerrs_prd_purge_reg; + + // +---------------------------+ + // | L3 Line Delete Scom | + // +---------------------------+ + // |Bit(s)| Data | + // +------+--------------------+ + // | 0 | Trigger | + // +------+--------------------+ + // | 1:4 | Purge type (ld=0x2)| + // +------+--------------------+ + // | 5:8 | Don't care | + // +------+--------------------+ + // | 9 | Busy Error | + // +------+--------------------+ + // |12:16 | Member (1 of 20) | + // +------+--------------------+ + // |17:28 | CGC (addr 45:56) | + // +------+--------------------+ + // |29:63 | Don't care | + // +------+--------------------+ + + // EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG + // Write member, cgc address into PRD Purge Engine Command Register + // SCOM Addr: 0x000000001001180E + // 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 12:16 is the member + // bits 17:28 is the cgc address + + // Make sure there's no current purge is in progress + FAPI_TRY(l3PurgeCompleteCheck(i_target, i_busyCount, + l_l3_l3cerrs_prd_purge_reg), + "Error returned from l3PurgeCompleteCheck()"); + FAPI_DBG("l_l3_l3cerrs_prd_purge_reg: 0x%.16llX", + l_l3_l3cerrs_prd_purge_reg); + + + l_l3_l3cerrs_prd_purge_reg.insertFromRight + + (i_err_data.member); + l_l3_l3cerrs_prd_purge_reg.insertFromRight + + (i_err_data.hashed_real_address_45_56); + l_l3_l3cerrs_prd_purge_reg.insertFromRight(1); + l_l3_l3cerrs_prd_purge_reg.insertFromRight + (0x2); + + FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg); + FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg), + "Error from putScom (l_l3_l3cerrs_prd_purge_reg)"); + + // Verify purge operation is complete + FAPI_TRY(l3PurgeCompleteCheck(i_target, i_busyCount, + l_l3_l3cerrs_prd_purge_reg), + "Error returned from l3PurgeCompleteCheck()"); + FAPI_DBG("l_l3_l3cerrs_prd_purge_reg: 0x%.16llX", + l_l3_l3cerrs_prd_purge_reg); + + // mark HWP exit +fapi_try_exit: + FAPI_INF("Exiting p9_l3err_linedelete..."); + return fapi2::current_err; +} // p9_l3err_extract diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.H b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.H index 108a3360b..57316a758 100644 --- a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.H +++ b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.H @@ -22,26 +22,30 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -//------------------------------------------------------------------------------ -// *| -// *! TITLE : p9_l3err_linedelete.H -// *! DESCRIPTION : Delete the L3 error cache line according to the error extraction information -// *! -// *! OWNER NAME : Alex Taft Email: amtaft@us.ibm.com -// *! -// *! ADDITIONAL COMMENTS : -// *! -// *! EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG -// *! Write member, cgc address into PRD Purge Engine Command Register -// *! SCOM Addr: 0x000000001001180E -// *| 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 12:16 is the member -// *| bits 17:28 is the cgc address -// *! NOTE: The error information is extracted by the HWP p9_l3err_extract. -// *| An output data structure is dumped to this proceder and wrapped -//------------------------------------------------------------------------------ +///---------------------------------------------------------------------------- +/// +/// @file p9_l3err_linedelete.H +/// +/// @brief Delete the L3 error cache line according to the error extraction +/// information. +/// +/// EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG +/// Write member, cgc address into PRD Purge Engine Command Register +/// SCOM Addr: 0x000000001001180E +/// 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 12:16 is the member +/// bits 17:28 is the cgc address +/// NOTE: The error information is extracted by the HWP p9_l3err_extract. +/// An output data structure is dumped to this proceder and wrapped +/// +/// *HWP HWP Owner : Alex Taft +/// *HWP FW Owner : Thi Tran +/// *HWP Team : Quad +/// *HWP Consumed by : PRDF +/// *HWP Level : 3 +///---------------------------------------------------------------------------- #ifndef _P9_L3ERR_LINEDELETE_H_ #define _P9_L3ERR_LINEDELETE_H_ @@ -56,18 +60,30 @@ //------------------------------------------------------------------------------ // function pointer typedef definition for HWP call support -typedef fapi2::ReturnCode -(*p9_l3err_linedelete_FP_t) (const fapi2::Target&, - const p9_l3err_extract_err_data&, - const uint64_t p9_l3err_linedelete_TryBusyCounts); +typedef fapi2::ReturnCode(*p9_l3err_linedelete_FP_t) +(const fapi2::Target&, + const p9_l3err_extract_err_data&, + const uint64_t p9_l3err_linedelete_TryBusyCounts); extern "C" { - fapi2::ReturnCode p9_l3err_linedelete(const fapi2::Target& i_target, - const p9_l3err_extract_err_data& i_err_data, - const uint64_t p9_l3err_linedelete_TryBusyCounts); +//------------------------------------------------------------------------------ +// Function prototype +//------------------------------------------------------------------------------ +/// +/// @brief Perform L3 Line Delete on an EX target using input L3 +/// 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_l3err_linedelete( + const fapi2::Target& i_target, + const p9_l3err_extract_err_data& i_err_data, + const uint64_t i_busyCount); } // extern "C" -- cgit v1.2.1