diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-03-13 08:08:22 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-04-01 21:26:31 -0400 |
commit | 74c4c141b1d8d8dbb3a1e40f493840f0551cf97c (patch) | |
tree | 63d044e94d62e80d0793ae1f3ed28145ff6d252b | |
parent | eb2c125d254f84866db4b698f7acd1afe6570ac4 (diff) | |
download | blackbird-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.C | 109 | ||||
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/phy/apb.H | 286 |
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 |