<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/fir/check.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 check.C
/// @brief Subroutines for checking MSS FIR
///
// *HWP HWP Owner: <NAME> <<EMAIL>>
// *HWP HWP Backup: <NAME> <<EMAIL>>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

#include <generic/memory/lib/utils/scom.H>
#include <lib/fir/fir.H>
#include <lib/fir/check.H>
#include <lib/utils/assert_noexit.H>
#include <generic/memory/lib/utils/find.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

namespace mss
{

namespace check
{

///
/// @brief A small, local, class to hold some of the FFDC information we need from the ports
///
struct fir_ffdc
{
    ///
    /// @brief fir_ffdc ctor
    /// @param[in] the MCA target the FFDC was collected from
    /// @param[in] the cal FIR information
    /// @param[in] the phy FIR information
    ///
    fir_ffdc( const fapi2::Target<TARGET_TYPE_MCA>& i_target, const uint64_t i_calfir, const uint64_t i_phyfir ):
        iv_target(i_target),
        iv_calfir(i_calfir),
        iv_phyfir(i_phyfir)
    {}

    ~fir_ffdc() = default;
    fir_ffdc() = delete;

    fapi2::Target<TARGET_TYPE_MCA> iv_target;
    uint64_t iv_calfir;
    uint64_t iv_phyfir;
};

///
/// @brief Check FIR bits during PHY reset
/// @note For DDRPHYFIR and some MBACALFIR errors, up to and including phy reset, need to
/// handle within the phy reset procedure, since we may get errors from a 'non-functional'
/// magic port, which PRD can't analyze.
/// @param[in] i_target the fapi2::Target MCBIST
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode during_phy_reset( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    // Save off the current current_err
    fapi2::ReturnCode l_current_err(fapi2::current_err);

    // Error path: if we hit error before FIR check (we can see that in current_err), and FIR check also
    // finds something, commit first error and exit phy reset with new error from FIR check
    // If bit on, call out MCA with deconfig and gard, including DDRPHYFIR and MBACALFIR in FFDC
    // Do FIR check on all ports, so we can log errors from multiple ports that happen to have FIR bits on

    // Create a mask from the bits Marc wants us to check
    fapi2::buffer<uint64_t> l_calfir_mask;
    l_calfir_mask.setBit<MCA_MBACALFIRQ_MBA_RECOVERABLE_ERROR>()
    .setBit<MCA_MBACALFIRQ_MBA_NONRECOVERABLE_ERROR>()
    .setBit<MCA_MBACALFIRQ_SM_1HOT_ERR>();

    fapi2::buffer<uint64_t> l_phyfir_mask;
    l_phyfir_mask.setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_0>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_1>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_3>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_4>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_5>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_6>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_7>();


    // Go grab the MCA_MBACALFIRQ for each port. We only save off some of the FFDC information for the ports which
    // have FIR set. This allows us to 1) see if we have any thing to do (empty vector means we don't) and 2) gives us
    // all the information we need to log all the proper errors.
    std::vector< fir_ffdc> l_fir_ffdc;

    for (const auto& p : mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target))
    {
        fapi2::buffer<uint64_t> l_calfir_data;
        fapi2::buffer<uint64_t> l_phyfir_data;
        fapi2::buffer<uint64_t> l_calfir_masked;
        fapi2::buffer<uint64_t> l_phyfir_masked;

        FAPI_TRY( mss::getScom(p, MCA_MBACALFIRQ, l_calfir_data) );
        FAPI_TRY( mss::getScom(p, MCA_IOM_PHY0_DDRPHY_FIR_REG, l_phyfir_data) );

        l_calfir_masked = l_calfir_data & l_calfir_mask;
        l_phyfir_masked = l_phyfir_data & l_phyfir_mask;

        // If either has set bits we make a little record in the vector
        if ((l_calfir_masked != 0) || (l_phyfir_masked != 0))
        {
            l_fir_ffdc.push_back( fir_ffdc(p, l_calfir_data, l_phyfir_data) );
        }<commit_msg>Clear DLL CNTL ERROR and FIR bits for workaround<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/fir/check.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 check.C
/// @brief Subroutines for checking MSS FIR
///
// *HWP HWP Owner: <NAME> <<EMAIL>>
// *HWP HWP Backup: <NAME> <<EMAIL>>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

#include <generic/memory/lib/utils/scom.H>
#include <lib/fir/fir.H>
#include <lib/fir/check.H>
#include <lib/utils/assert_noexit.H>
#include <generic/memory/lib/utils/find.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;

namespace mss
{

namespace check
{

///
/// @brief A small, local, class to hold some of the FFDC information we need from the ports
///
struct fir_ffdc
{
    ///
    /// @brief fir_ffdc ctor
    /// @param[in] the MCA target the FFDC was collected from
    /// @param[in] the cal FIR information
    /// @param[in] the phy FIR information
    ///
    fir_ffdc( const fapi2::Target<TARGET_TYPE_MCA>& i_target, const uint64_t i_calfir, const uint64_t i_phyfir ):
        iv_target(i_target),
        iv_calfir(i_calfir),
        iv_phyfir(i_phyfir)
    {}

    ~fir_ffdc() = default;
    fir_ffdc() = delete;

    fapi2::Target<TARGET_TYPE_MCA> iv_target;
    uint64_t iv_calfir;
    uint64_t iv_phyfir;
};

///
/// @brief Check FIR bits during PHY reset
/// @note For DDRPHYFIR and some MBACALFIR errors, up to and including phy reset, need to
/// handle within the phy reset procedure, since we may get errors from a 'non-functional'
/// magic port, which PRD can't analyze.
/// @param[in] i_target the fapi2::Target MCBIST
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode during_phy_reset( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    // Save off the current current_err
    fapi2::ReturnCode l_current_err(fapi2::current_err);

    // Error path: if we hit error before FIR check (we can see that in current_err), and FIR check also
    // finds something, commit first error and exit phy reset with new error from FIR check
    // If bit on, call out MCA with deconfig and gard, including DDRPHYFIR and MBACALFIR in FFDC
    // Do FIR check on all ports, so we can log errors from multiple ports that happen to have FIR bits on

    // Create a mask from the bits Marc wants us to check
    fapi2::buffer<uint64_t> l_calfir_mask;
    l_calfir_mask.setBit<MCA_MBACALFIRQ_MBA_RECOVERABLE_ERROR>()
    .setBit<MCA_MBACALFIRQ_MBA_NONRECOVERABLE_ERROR>()
    .setBit<MCA_MBACALFIRQ_SM_1HOT_ERR>();

    fapi2::buffer<uint64_t> l_phyfir_mask;
    l_phyfir_mask.setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_0>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_1>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_2>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_3>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_4>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_5>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_6>()
    .setBit<MCA_IOM_PHY0_DDRPHY_FIR_REG_ERROR_7>();


    // Go grab the MCA_MBACALFIRQ for each port. We only save off some of the FFDC information for the ports which
    // have FIR set. This allows us to 1) see if we have any thing to do (empty vector means we don't) and 2) gives us
    // all the information we need to log all the proper errors.
    std::vector< fir_ffdc> l_fir_ffdc;

    for (const auto& p : mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target))
    {
        fapi2::buffer<uint64_t> l_calfir_data;
        fapi2::buffer<uint64_t> l_phyfir_data;
        fapi2::buffer<uint64_t> l_calfir_masked;
        fapi2::buffer<uint64_t> l_phyfir_masked;

        FAPI_TRY( mss::getScom(p, MCA_MBACALFIRQ, l_calfir_data) );
        FAPI_TRY( mss::getScom(p, MCA_IOM_PHY0_DDRPHY_FIR_REG, l_phyfir_data) );

        l_calfir_masked = l_calfir_data & l_calfir_mask;
        l_phyfir_masked = l_phyfir_data & l_phyfir_mask;

        // If either has set bits we make a little record in the vector
        if ((l_calfir_masked != 0) || (l_phyfir_masked != 0))
        {
            l_fir_ffdc.push_back( fir_ffdc(p, l_calfir_data, l_phyfir_data) );
        }
{'fraction_non_alphanumeric': 0.09565875820292781, 'fraction_numerical': 0.012619888944977285, 'mean_word_length': 1.931442663378545, 'pattern_counts': {'":': 0, '<': 76, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 62, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '977837', 'n_tokens_mistral': 3882, 'n_tokens_neox': 3718, 'n_words': 981}