summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-03-13 08:08:22 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-04-01 21:26:31 -0400
commit74c4c141b1d8d8dbb3a1e40f493840f0551cf97c (patch)
tree63d044e94d62e80d0793ae1f3ed28145ff6d252b
parenteb2c125d254f84866db4b698f7acd1afe6570ac4 (diff)
downloadblackbird-hostboot-74c4c141b1d8d8dbb3a1e40f493840f0551cf97c.tar.gz
blackbird-hostboot-74c4c141b1d8d8dbb3a1e40f493840f0551cf97c.zip
Add initial FIR checking for APB interface
Change-Id: I6ca9ea84f6f5f34c8e766fe42e8cfa7d668d7a3e Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21994 Tested-by: Jenkins Server Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22779 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.C109
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.H286
2 files changed, 395 insertions, 0 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.C
new file mode 100644
index 000000000..0d1d19b91
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.C
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/memory/lib/phy/apb.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file apb.C
+/// @brief Subroutines for the PHY APB registers
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include "apb.H"
+#include "../lib/utils/scom.H"
+#include "../lib/utils/c_str.H"
+#include "../lib/utils/index.H"
+
+namespace mss
+{
+///
+/// @brief APB block FIR check, MCA style
+/// @param[in] i_target fapi2 target of the port
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if no FIR
+///
+template<>
+fapi2::ReturnCode apb_class<fapi2::TARGET_TYPE_MCA>::fir_check(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
+{
+ typedef apbTraits<fapi2::TARGET_TYPE_MCA> TT;
+
+ fapi2::buffer<uint64_t> l_data;
+
+ // Check with f/w - do they want the first, or should we be logging these and returning ... the last? BRS
+ {
+ FAPI_TRY( read_error_status0(i_target, l_data) );
+
+ FAPI_ASSERT( l_data.getBit<TT::INVALID_ADDRESS>() == false,
+ fapi2::MSS_APB_INVALID_ADDRESS().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting an invalid address on %s", mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::WRITE_PARITY_ERR>() == false,
+ fapi2::MSS_APB_WR_PAR_ERR().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a read/write parity error on %s", mss::c_str(i_target) );
+ }
+
+ {
+ uint64_t l_dp16 = 0;
+
+ FAPI_TRY( read_fir_err0(i_target, l_data) );
+
+ FAPI_ASSERT( l_data.getBit<TT::FATAL_FSM>() == false,
+ fapi2::MSS_FATAL_FSM_PHYTOP().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a fatal FSM error in PHYTOP %s", mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::FATAL_PARITY>() == false,
+ fapi2::MSS_FATAL_PARITY_PHYTOP().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a fatal parity error in PHYTOP %s", mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::FSM>() == false,
+ fapi2::MSS_FSM_PHYTOP().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a recoverable FSM error in PHYTOP %s", mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::PARITY>() == false,
+ fapi2::MSS_PARITY_PHYTOP().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a recoverable parity error in PHYTOP %s", mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::FATAL_ADR52_MASTER>() == false,
+ fapi2::MSS_FATAL_ADR52_MASTER().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a fatal register parity error in ADR52 master side logic %s",
+ mss::c_str(i_target) );
+
+ FAPI_ASSERT( l_data.getBit<TT::FATAL_ADR52_SLAVE>() == false,
+ fapi2::MSS_FATAL_ADR52_SLAVE().set_PORT_POSITION(mss::pos(i_target)).set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a fatal register parity error in ADR52 slave side logic %s",
+ mss::c_str(i_target) );
+
+ l_data.extractToRight<TT::FSM_DP16, TT::FSM_DP16_LEN>(l_dp16);
+ FAPI_ASSERT( l_dp16 == 0,
+ fapi2::MSS_FSM_DP16()
+ .set_PORT_POSITION(mss::pos(i_target))
+ .set_DP16_POSITION(l_dp16)
+ .set_TARGET_IN_ERROR(i_target),
+ "APB interface is reporting a recoverable FSM state checker error in DP16 %s 0x%x",
+ mss::c_str(i_target), l_dp16 );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.H
new file mode 100644
index 000000000..0366c66c0
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.H
@@ -0,0 +1,286 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/memory/lib/phy/apb.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file apb.H
+/// @brief Subroutines for the PHY APB registers
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_APB_H_
+#define _MSS_APB_H_
+
+#include <fapi2.H>
+#include "p9_mc_scom_addresses.H"
+#include "p9_mc_scom_addresses_fld.H"
+#include "../lib/utils/scom.H"
+
+namespace mss
+{
+
+// I have a dream that the PHY code can be shared among controllers. So, I drive the
+// engine from a set of traits. This might be folly. Allow me to dream. BRS
+
+///
+/// @class apbTraits
+/// @brief a collection of traits associated with the PHY APB interface
+/// @tparam T fapi2::TargetType representing the PHY
+///
+template< fapi2::TargetType T >
+class apbTraits;
+
+///
+/// @class apbTraits
+/// @brief a collection of traits associated with the Centaur PHY APB interface
+///
+template<>
+class apbTraits<fapi2::TARGET_TYPE_MBA>
+{
+};
+
+///
+/// @class apbTraits
+/// @brief a collection of traits associated with the Nimbus PHY APB
+///
+template<>
+class apbTraits<fapi2::TARGET_TYPE_MCA>
+{
+ public:
+ // MCA APB control registers - must be 64 bits.
+ static const uint64_t APB_CONFIG0_REG = MCA_DDRPHY_APB_CONFIG0_P0;
+ static const uint64_t APB_ERROR_STATUS0_REG = MCA_DDRPHY_APB_ERROR_STATUS0_P0;
+ static const uint64_t APB_FIR_ERR0_REG = MCA_DDRPHY_APB_FIR_ERR0_P0;
+ static const uint64_t APB_FIR_ERR1_REG = MCA_DDRPHY_APB_FIR_ERR1_P0;
+ static const uint64_t APB_FIR_ERR2_REG = MCA_DDRPHY_APB_FIR_ERR2_P0;
+ static const uint64_t APB_FIR_ERR3_REG = MCA_DDRPHY_APB_FIR_ERR3_P0;
+
+ // Fields, can be any size.
+ enum
+ {
+ RESET_ERR_RPT = MCA_DDRPHY_APB_CONFIG0_P0_RESET_ERR_RPT,
+
+ INVALID_ADDRESS = MCA_DDRPHY_APB_ERROR_STATUS0_P0_INVALID_ADDRESS,
+ WRITE_PARITY_ERR = MCA_DDRPHY_APB_ERROR_STATUS0_P0_WR_PAR_ERR,
+
+ FATAL_FSM = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET0,
+ FATAL_PARITY = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET1,
+ FSM = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET2,
+ PARITY = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET3,
+ FATAL_ADR52_MASTER = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET4,
+ FATAL_ADR52_SLAVE = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_SET5,
+ FSM_DP16 = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_FSM_DP16,
+ FSM_DP16_LEN = MCA_DDRPHY_APB_FIR_ERR0_P0_ERR_FSM_DP16_LEN,
+
+ };
+
+};
+
+///
+/// @class mss::apb
+/// @brief APB class
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to apbTraits<T>
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = apbTraits<T> >
+class apb_class
+{
+ public:
+
+ ///
+ /// @brief Read APB_CONFIG0
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_config0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_CONFIG0_REG, o_data) );
+ FAPI_DBG("apb_config0: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Write APB_CONFIG0
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[in] i_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode write_config0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+ {
+ FAPI_DBG("apb_config0: 0x%016lx", i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::APB_CONFIG0_REG, i_data) );
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Read APB_ERROR_STATUS0
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_error_status0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_ERROR_STATUS0_REG, o_data) );
+ FAPI_DBG("apb_error_status0: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Write APB_ERROR_STATUS0
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[in] i_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode write_error_status0( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data )
+ {
+ FAPI_DBG("apb_error_status0: 0x%016lx", i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::APB_ERROR_STATUS0_REG, i_data) );
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Read APB_FIR_ERR0_REG
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_fir_err0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_FIR_ERR0_REG, o_data) );
+ FAPI_DBG("apb_fir_err0: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Read APB_FIR_ERR1_REG
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_fir_err1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_FIR_ERR1_REG, o_data) );
+ FAPI_DBG("apb_fir_err1: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Read APB_FIR_ERR2_REG
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_fir_err2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_FIR_ERR2_REG, o_data) );
+ FAPI_DBG("apb_fir_err2: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Read APB_FIR_ERR3_REG
+ /// @param[in] i_target the fapi2 target of the port
+ /// @param[out] o_data the value of the register
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode read_fir_err3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+ {
+ FAPI_TRY( mss::getScom(i_target, TT::APB_FIR_ERR3_REG, o_data) );
+ FAPI_DBG("apb_fir_err3: 0x%016lx", o_data);
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Reset the error state of the APB block
+ /// @param[in] i_target the fapi2 target of the port
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode reset_err( const fapi2::Target<T>& i_target )
+ {
+ // DDRPHY_APB_CONFIG0_P0_RESET_ERR_RPT
+ // Write this bit to '1'b then write this bit to '0'b (toggle) to reset the
+ // APB error registers.
+ // Does this cover all of them? BRS
+ fapi2::buffer<uint64_t> l_data;
+ FAPI_TRY( read_config0(i_target, l_data) );
+ l_data.setBit<TT::RESET_ERR_RPT>();
+ FAPI_TRY( write_config0(i_target, l_data) );
+ l_data.clearBit<TT::RESET_ERR_RPT>();
+ FAPI_TRY( write_config0(i_target, l_data) );
+
+ // We have to read ERR_STATUS0. It resets when read.
+ FAPI_TRY( read_error_status0(i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief reset apb_config0
+ /// @param[in] i_target fapi2 target of the port
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode reset_config0( const fapi2::Target<T>& i_target )
+ {
+ FAPI_TRY( reset_err(i_target) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief reset rc
+ /// @param[in] i_target fapi2 target of the port
+ /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok
+ ///
+ static inline fapi2::ReturnCode reset( const fapi2::Target<T>& i_target )
+ {
+ FAPI_TRY( reset_config0(i_target) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief APB block FIR check
+ /// @param[in] i_target fapi2 target of the port
+ /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if no FIR
+ ///
+ fapi2::ReturnCode fir_check( const fapi2::Target<T>& i_target );
+
+};
+
+using apb = apb_class<fapi2::TARGET_TYPE_MCA>;
+
+}
+
+#endif
OpenPOWER on IntegriCloud