/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ /// /// @file unmask.C /// @brief Subroutines for unmasking and setting up MSS FIR /// // *HWP HWP Owner: Stephen Glancy // *HWP HWP Backup: Marc Gollub // *HWP Team: Memory // *HWP Level: 3 // *HWP Consumed by: FSP:HB #include #include #include #include #include #include #include #include #include using fapi2::TARGET_TYPE_MCBIST; using fapi2::TARGET_TYPE_MCA; namespace mss { namespace unmask { /// /// @brief Unmask and setup actions performed after draminit_mc /// @param[in] i_target the fapi2::Target of the MCBIST /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template<> fapi2::ReturnCode after_draminit_mc( const fapi2::Target& i_target ) { FAPI_INF("unmask mss fir after draminit_mc"); fapi2::ReturnCode l_rc; // TK - unclear right now if these can become generic per MCBIST or whether these are specific // to Nimbus. If they can be generic,this whole thing can go back in the H file and the specifics // of the registers and bits can be handled generically. fir::reg l_mcbist_fir_reg(i_target, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ); // Setup mcbist fir. All mcbist attentions are already special attentions // Write this out before the work-around as it will read and write. l_mcbist_fir_reg.attention(); FAPI_TRY(l_mcbist_fir_reg.write(), "unable to write fir::reg %d", MCBIST_MCBISTFIRQ); // Broadcast mode workaround for UEs causing out of sync FAPI_TRY(mss::workarounds::mcbist::broadcast_out_of_sync(i_target, mss::OFF)); FAPI_TRY(mss::workarounds::mcbist::wat_debug_attention(i_target)); for (const auto& p : mss::find_targets(i_target)) { fir::reg l_mca_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_FIR); l_mca_fir_reg.recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error() .checkstop() .checkstop() .recoverable_error() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop() .checkstop(); FAPI_TRY(l_mca_fir_reg.write(), "unable to write fir::reg %d", MCA_FIR); } fapi_try_exit: return fapi2::current_err; } /// /// @brief Unmask and setup actions performed after draminit_training /// @param[in] i_target the fapi2::Target of the MCBIST /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template<> fapi2::ReturnCode after_draminit_training( const fapi2::Target& i_target ) { FAPI_INF("unmask mss fir after draminit_training"); fapi2::ReturnCode l_rc; // TK - unclear right now if these can become generic per MCBIST or whether these are specific // to Nimbus. If they can be generic,this whole thing can go back in the H file and the specifics // of the registers and bits can be handled generically. fir::reg l_mcbist_fir_reg(i_target, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ); // Setup mcbist fir. All mcbist attentions are already special attentions FAPI_TRY(l_mcbist_fir_reg.recoverable_error().write(), "unable to write fir::reg %d", MCBIST_MCBISTFIRQ); for (const auto& p : mss::find_targets(i_target)) { fir::reg l_mca_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_MBACALFIRQ); l_mca_fir_reg.recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error() .checkstop() .checkstop() .recoverable_error(); FAPI_TRY(l_mca_fir_reg.write(), "unable to write fir::reg %d", MCA_MBACALFIRQ); } fapi_try_exit: return fapi2::current_err; } /// /// @brief Unmask and setup actions performed after mss_scominit /// (yeah, it's clearing bits - it's ok) /// @param[in] i_target the fapi2::Target of the MCBIST /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template<> fapi2::ReturnCode after_scominit( const fapi2::Target& i_target ) { FAPI_INF("unmask (and clear) mss fir after scominit"); fapi2::ReturnCode l_rc; // TK - unclear right now if these can become generic per MCBIST or whether these are specific // to Nimbus. If they can be generic,this whole thing can go back in the H file and the specifics // of the registers and bits can be handled generically. for (const auto& p : mss::find_targets_with_magic(i_target)) { fir::reg l_mca_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_IOM_PHY0_DDRPHY_FIR_REG); fir::reg l_cal_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_MBACALFIRQ); FAPI_TRY(l_mca_fir_reg.clear()); FAPI_TRY(l_mca_fir_reg.clear()); FAPI_TRY(l_cal_fir_reg.clear()); FAPI_TRY(l_cal_fir_reg.clear()); // No need to write after clearing - the clear does the read/modify/write. } fapi_try_exit: return fapi2::current_err; } /// /// @brief Unmask and setup actions performed after mss_ddr_phy_reset /// @param[in] i_target the fapi2::Target of the MCBIST /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template<> fapi2::ReturnCode after_phy_reset( const fapi2::Target& i_target ) { FAPI_INF("unmask mss fir after phy reset"); fapi2::ReturnCode l_rc; // TK - unclear right now if these can become generic per MCBIST or whether these are specific // to Nimbus. If they can be generic,this whole thing can go back in the H file and the specifics // of the registers and bits can be handled generically. fir::reg l_mcbist_fir_reg(i_target, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ); l_mcbist_fir_reg.checkstop() .recoverable_error() .checkstop(); FAPI_TRY(l_mcbist_fir_reg.write(), "unable to write fir::reg %d", MCBIST_MCBISTFIRQ); for (const auto& p : mss::find_targets(i_target)) { fir::reg l_mca_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_IOM_PHY0_DDRPHY_FIR_REG); fir::reg l_cal_fir_reg(p, l_rc); FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_MBACALFIRQ); l_cal_fir_reg.recoverable_error() .checkstop() .recoverable_error() .checkstop(); l_mca_fir_reg.recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error() .recoverable_error(); FAPI_TRY(l_mca_fir_reg.write(), "unable to write fir::reg %d", MCA_IOM_PHY0_DDRPHY_FIR_REG); FAPI_TRY(l_cal_fir_reg.write(), "unable to write fir::reg %d", MCA_MBACALFIRQ); } fapi_try_exit: return fapi2::current_err; } } }