From 9beca538b91975afa969bf53215b294f6d06a138 Mon Sep 17 00:00:00 2001 From: Louis Stermole Date: Thu, 9 May 2019 15:54:50 -0400 Subject: Add retry of EXP_FW_STATUS when status is FW_BUSY Change-Id: Ic6b962fd4afdcce617ebb893b307ad5cc95086b8 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77203 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Reviewed-by: Glenn Miles Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: Mark Pizzutillo Reviewed-by: STEPHEN GLANCY Reviewed-by: Thi N. Tran Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77505 Reviewed-by: RAJA DAS --- .../procedures/hwp/memory/lib/i2c/exp_i2c.H | 50 +++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src/import/chips') diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H index fc191b8d..9bbaa4f9 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H @@ -59,15 +59,27 @@ namespace check /// @param[in] i_target the OCMB target /// @param[in] i_cmd_id the command ID /// @param[in] i_data data to check from EXP_FW_STATUS +/// @param[out] o_busy true if explorer returns FW_BUSY status, false otherwise /// inline fapi2::ReturnCode status_code( const fapi2::Target& i_target, const uint8_t i_cmd_id, - const std::vector& i_data ) + const std::vector& i_data, + bool& o_busy ) { + // Set o_busy to false just in case we don't make it to where we check it + o_busy = false; + // Set to a high number to make sure check for SUCCESS (== 0) isn't a fluke uint8_t l_status = ~(0); FAPI_TRY( status::get_status_code(i_target, i_data, l_status) ); + // We need to try again if we get a FW_BUSY status, so set the flag + if (l_status == status_codes::FW_BUSY) + { + o_busy = true; + return fapi2::FAPI2_RC_SUCCESS; + } + // Technically many cmds have their own status code decoding..but SUCCESS is always 0. // If it's anything else we can just look up the status code FAPI_ASSERT( l_status == status_codes::SUCCESS, @@ -127,11 +139,37 @@ fapi_try_exit: /// inline fapi2::ReturnCode fw_status(const fapi2::Target& i_target) { - std::vector l_data; - - // Get data and check for errors - FAPI_TRY(get_fw_status(i_target, l_data)); - FAPI_TRY( check::status_code(i_target, FW_STATUS, l_data) ); + constexpr uint64_t NUM_LOOPS = 50; + // So, why aren't we using the memory team's polling API? + // This is a base function that will be utilized by the platform code + // As such, we don't want to pull in more libraries than we need to: it would cause extra dependencies + // So, we're decomposing the polling library below + bool l_busy = true; + uint64_t l_loop = 0; + + // Loop until we max our our loop count or get a doorbell response + for(; l_loop < NUM_LOOPS && l_busy; ++l_loop) + { + std::vector l_data; + FAPI_TRY(get_fw_status(i_target, l_data)); + FAPI_TRY( check::status_code(i_target, FW_STATUS, l_data, l_busy) ); + + if (l_busy) + { + FAPI_INF( "%s reutrned FW_BUSY status. Retrying...", mss::c_str(i_target) ); + FAPI_TRY( fapi2::delay( DELAY_100NS, 200) ); + } + } + + FAPI_DBG("%s stopped on loop%u/%u. %s", + mss::c_str(i_target), l_loop, NUM_LOOPS, (l_busy ? "FW_BUSY" : "SUCCESS")); + + // Check that Explorer is not still in FW_BUSY state + FAPI_ASSERT( !l_busy, + fapi2::MSS_EXP_I2C_FW_STATUS_BUSY(). + set_TARGET(i_target), + "Polling timeout on FW_STATUS command (still FW_BUSY) for %s", + mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; -- cgit v1.2.1