summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/hwpf/include/plat/plat_hw_access.H26
-rw-r--r--src/hwpf/src/plat/plat_hw_access.C61
2 files changed, 87 insertions, 0 deletions
diff --git a/src/hwpf/include/plat/plat_hw_access.H b/src/hwpf/include/plat/plat_hw_access.H
index 89c02f2a..c7c73325 100644
--- a/src/hwpf/include/plat/plat_hw_access.H
+++ b/src/hwpf/include/plat/plat_hw_access.H
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -34,6 +35,18 @@
#include "hw_access_def.H"
#include <return_code.H>
+// PIB errors
+enum PCB_ERRORS
+{
+ PIB_NO_ERROR = 0x0,
+ PIB_XSCOM_ERROR = 0x1,
+ PIB_OFFLINE_ERROR = 0x2,
+ PIB_PARTIAL_ERROR = 0x3,
+ PIB_ADDRESS_ERROR = 0x4,
+ PIB_CLOCK_ERROR = 0x5,
+ PIB_PARITY_ERROR = 0x6,
+ PIB_TIMEOUT_ERROR = 0x7
+};
/// PIB Error Mask
@@ -141,6 +154,19 @@ namespace fapi2
/// @return PCB-PIB return code
///
uint32_t putscom_abs_wrap(const uint32_t i_addr, uint64_t i_data);
+
+ ///
+ /// @brief Platform wrapper to retry scom for parity/timeout errors
+ ///
+ /// @param [in] i_addr The SCOM address
+ /// @param [io] io_data The data pointer
+ /// @param [in] i_pibErr PIB error code
+ /// @param [in] i_isRead True if read operation, false otherwise
+ ///
+ /// @return PCB-PIB return code
+ ///
+ uint32_t p9_pibErrRetry( const uint32_t i_addr, uint64_t *io_data,
+ const uint8_t i_pibErr, const bool i_isRead);
}
diff --git a/src/hwpf/src/plat/plat_hw_access.C b/src/hwpf/src/plat/plat_hw_access.C
index 5c2af1a8..01fedc96 100644
--- a/src/hwpf/src/plat/plat_hw_access.C
+++ b/src/hwpf/src/plat/plat_hw_access.C
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -24,6 +25,7 @@
#include <fapi2.H>
#include "plat_hw_access.H"
+#include "p9_perv_scom_addresses.H"
namespace fapi2
{
@@ -53,6 +55,10 @@ namespace fapi2
uint32_t l_rc = 0;
FAPI_INF("getScom: address: 0x%08X", i_addr);
l_rc = getscom_abs(i_addr, o_data);
+ if( PIB_NO_ERROR != l_rc )
+ {
+ l_rc = p9_pibErrRetry( i_addr, o_data, l_rc, true);
+ }
FAPI_INF("getScom: returned rc: 0x%08X, data HI: 0x%08X, "
"data LO: 0x%08X", l_rc, (*o_data >> 32),
static_cast<uint32_t>(*o_data & 0xFFFFFFFF));
@@ -66,7 +72,62 @@ namespace fapi2
i_addr, (i_data >> 32),
static_cast<uint32_t>(i_data & 0xFFFFFFFF));
l_rc = putscom_abs(i_addr, i_data);
+ if( PIB_NO_ERROR != l_rc )
+ {
+ l_rc = p9_pibErrRetry( i_addr, &i_data, l_rc, false);
+ }
FAPI_INF("putScom: returned rc: 0x%08X", l_rc);
return l_rc;
}
+
+uint32_t p9_pibErrRetry( const uint32_t i_addr, uint64_t *io_data,
+ const uint8_t i_pibErr, const bool i_isRead)
+{
+ FAPI_INF("Entering p9_pibErrRetry");
+ static const uint8_t MAX_RETRIES = 2;
+ static const uint64_t REG_BIT0 = (uint64_t)(0x1)<<63;
+ uint8_t l_retryCount = 0;
+ uint32_t pibErr = i_pibErr;
+
+ do
+ {
+ // Only retry for parity and timeout errors
+ if (( i_pibErr != PIB_PARITY_ERROR )
+ && ( i_pibErr != PIB_TIMEOUT_ERROR ))
+ {
+ break;
+ }
+ for(l_retryCount = 0; l_retryCount < MAX_RETRIES; l_retryCount++)
+ {
+ // RESET_PCB: Reset all PCB elements outside of the standby domain
+ pibErr = putscom_abs( PERV_PIB_RESET_REG, REG_BIT0 );
+ if( pibErr ) break;
+ // RESET_PCB: clear it again
+ pibErr = putscom_abs( PERV_PIB_RESET_REG, 0);
+ if( pibErr ) break;
+
+ FAPI_DBG( "*** Retry %i ***", l_retryCount );
+
+ if ( i_isRead )
+ {
+ pibErr = getscom_abs(i_addr, io_data);
+ }
+ else
+ {
+ pibErr = putscom_abs(i_addr, *io_data);
+ }
+
+ if( PIB_NO_ERROR == pibErr )
+ {
+ FAPI_INF("Read/Write Retry Successful");
+ break;
+ }
+ if ( pibErr != i_pibErr ) break;
+ }
+ }while(0);
+ FAPI_INF("Exiting p9_pibErrRetry");
+ return pibErr;
+}
+
+
};
OpenPOWER on IntegriCloud