<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/htmgt/htmgt.C $                                       */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2014,2022                        */
/* [+] 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                                                     */

#include <htmgt/htmgt.H>
#include <htmgt/htmgt_reasoncodes.H>
#include "htmgt_activate.H"
#include "htmgt_cfgdata.H"
#include "htmgt_utility.H"
#include "htmgt_occmanager.H"
#include "htmgt_poll.H"
#include <devicefw/userif.H>
#include <console/consoleif.H>

//  Targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/attributes.H>
#include <targeting/common/targetservice.H>
#include <isteps/pm/scopedHomerMapper.H>

#include <sys/time.h>
#include <targeting/common/attributeTank.H>

#include <isteps/pm/pm_common_ext.H>

using namespace TARGETING;

namespace HTMGT
{

    // Move the OCCs to active state or log unrecoverable error and
    // stay in safe mode
    void processOccStartStatus(const bool i_startCompleted,
                               TARGETING::Target * i_failedOccTarget)
    {
        TMGT_INF(">>processOccStartStatus(%d,0x%p)",
                 i_startCompleted, i_failedOccTarget);
        errlHndl_t l_err = nullptr;
        uint32_t l_huid = 0;
        bool skip_comm = true;
        if (i_failedOccTarget)
        {
            l_huid = TARGETING::get_huid(i_failedOccTarget);
        }
        TMGT_INF("processOccStartStatus(Start Success=%c, failedOcc=0x%08X)",
                 i_startCompleted?'y':'n', l_huid);

        TARGETING::Target* sys = nullptr;
        TARGETING::targetService().getTopLevelTarget(sys);
        uint8_t safeMode = 0;
        if(sys)
        {
            sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
        }
        if (safeMode == 0)
        {
            check_reset_count();
        }
        else
        {
            // OCCs were started, so clear Safe Mode
            TMGT_INF("processOccStartStatus: System was in Safe Mode, but OCCs "
                     "were started.  Clearing Safe Mode");
            safeMode = 0;
            sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
            OccManager::clearResetCounts();
        }

        if (false == int_flags_set(FLAG_HOLD_OCCS_IN_RESET))
        {
            if (i_startCompleted)
            {
                // Start listening for OCC atts
                OccManager::setOccsStarted(true);

                // Query functional OCCs (OCCs have just been started)
                l_err = OccManager::buildOccs(true);
                if (nullptr == l_err)
                {
                    if (nullptr != OccManager::getMasterOcc())
                    {
                        do
                        {
                            // Memory throttles are calculated during istep 18

                            // Make sure OCCs are ready for communication
                            l_err = OccManager::waitForOccCheckpoint();
                            if( l_err )
                            {
                                break;
                            }

#ifdef __HOSTBOOT_RUNTIME
                            nanosleep(1,0);
#endif

                            // Send poll to establish comm
                            TMGT_INF("Send initial poll to all OCCs to"
                                     " establish comm");
                            l_err = OccManager::sendOccPoll();
                            if (OccManager::occNeedsReset())
                            {
                                if (l_err == nullptr)
                                {
                                    /*@
                                     * @errortype
                                     * @reasoncode HTMGT_RC_OCC_UNEXPECTED_STATE
                                     * @moduleid  HTMGT_MOD_LOAD_START_STATUS
                                     * @devdesc OCC needs reset after initial poll
                                     * @custdesc An internal firmware error occurred
                                     */
                                    bldErrLog(l_err,
                                              HTMGT_MOD_LOAD_START_STATUS,
                                              HTMGT_RC_OCC_UNEXPECTED_STATE,
                                              0, 0, 0, 1,
                                              ERRORLOG::ERRL_SEV_INFORMATIONAL);
                                }
                                // No need to continue if reset is required
                                break;
                            }
                            else if (l_err)
                            {
                                // Continue even if polls failed (will retried)
                                ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                            }
                            skip_comm = false;

                            // Send ALL config data
                            l_err = sendOccConfigData();
                            if (l_err)
                            {
                                break;
                            }

                            // Set the User PCAP
                            l_err = sendOccUserPowerCap();
                            if (l_err)
                            {
                                break;
                            }

                            // Wait for all OCCs to go to the target state
                            l_err = waitForOccState();
                            if ( l_err )
                            {
                                break;
                            }

                            if (OccManager::occNeedsReset())
                            {
                                bldErrLog(l_err,
                                          HTMGT_MOD_LOAD_START_STATUS,
                                          HTMGT_RC_OCC_UNEXPECTED_STATE,
                                          0, 0, 0, 0,
                                          ERRORLOG::ERRL_SEV_INFORMATIONAL);
                                break;
                            }

                            // Set enabled sensors for all OCCs,
                            // so BMC can start communication with OCCs
                            l_err = setOccEnabledSensors(true);
                            if (l_err)
                            {
                                // Continue even if failed to update sensor
                                ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                            }

                        } while(0);
                    }
                    else
                    {
                        TMGT_ERR("Unable to find any Master capable OCCs");
                        /*@
                         * @errortype
                         * @reasoncode      HTMGT_RC_OCC_MASTER_NOT_FOUND
                         * @moduleid        HTMGT_MOD_LOAD_START_STATUS
                         * @userdata1       number of OCCs
                         * @devdesc         No OCC master was found
                         * @custdesc        An internal firmware error occurred
                         */
                        bldErrLog(l_err, HTMGT_MOD_LOAD_START_STATUS,
                                  HTMGT_RC_OCC_MASTER_NOT_FOUND,
                                  0, OccManager::getNumOccs(), 0, 0,
                                  ERRORLOG::ERRL_SEV_INFORMATIONAL);
                    }
                }
                else
                {
                    // Failed to find functional OCCs, no need to try again
                    // Set original error log as unrecoverable/degraded performance and commit
                    l_err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE1);
                    ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                }
            }
            else
            {
                TMGT_ERR("All OCCs were not loaded/started successfully");
                /*@
                 * @errortype
                 * @reasoncode      HTMGT_RC_OCC_START_FAIL
                 * @moduleid        HTMGT_MOD_LOAD_START_STATUS
                 * @userdata1       Failing OCC HUID
                 * @devdesc         OCCs were not loaded/started successfully
                 * @custdesc        An internal firmware error occurred
                 */
                bldErrLog(l_err, HTMGT_MOD_LOAD_START_STATUS,
                          HTMGT_RC_OCC_START_FAIL,
                          0, l_huid, 0, 0,
                          ERRORLOG::ERRL_SEV_INFORMATIONAL);
            }

            if (nullptr != l_err)
            {
                // If the start failed, HTMGT will attempt reset.
                // This will end up being a recursive call: After the
                // reset is done, this function will get called again.
                // If the reset returns success, then we know the
                // recovery was successful. When there are multiple reset
                // failures, the inital resetOcc() calls will return an
                // error.  That error can be ignored IF the OCCs were
                // actually enabled successfully in later recursive calls.
                TMGT_ERR("OCCs not all active (rc=0x%04X).  Attempting OCC "
                         "Reset", l_err->reasonCode());
                TMGT_CONSOLE("OCCs are not active (rc=0x%04X). "
                             "Attempting OCC Reset",
                             l_err->reasonCode());
                TMGT_INF("processOccStartStatus: Calling resetOccs");
                // Reset ALL OCCs, don't skip incrementing reset count, and
                // if comm has not been established, don't try to talk to OCCs
                errlHndl_t reset_err = OccManager::resetOccs(nullptr,
                                                             false,
                                                             skip_comm);
                if(reset_err)
                {
                    // reset failed and OCCs still not running yet
                    TMGT_ERR("processOccStartStatus: OccManager::resetOccs"
                             " failed with 0x%04X",
                             reset_err->reasonCode());

                    // Set original error log  as unrecoverable/degraded and commit
                    l_err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE1);
                    ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);

                    // Commit occReset error
                    ERRORLOG::errlCommit(reset_err, HTMGT_COMP_ID);
                }
                else
                {
                    const uint16_t l_rc = l_err->reasonCode();<commit_msg>HTMGT: Prevent extra unrecoverable PEL when going to safe mode<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/htmgt/htmgt.C $                                       */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2014,2022                        */
/* [+] 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                                                     */

#include <htmgt/htmgt.H>
#include <htmgt/htmgt_reasoncodes.H>
#include "htmgt_activate.H"
#include "htmgt_cfgdata.H"
#include "htmgt_utility.H"
#include "htmgt_occmanager.H"
#include "htmgt_poll.H"
#include <devicefw/userif.H>
#include <console/consoleif.H>

//  Targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/attributes.H>
#include <targeting/common/targetservice.H>
#include <isteps/pm/scopedHomerMapper.H>

#include <sys/time.h>
#include <targeting/common/attributeTank.H>

#include <isteps/pm/pm_common_ext.H>

using namespace TARGETING;

namespace HTMGT
{

    // Move the OCCs to active state or log unrecoverable error and
    // stay in safe mode
    void processOccStartStatus(const bool i_startCompleted,
                               TARGETING::Target * i_failedOccTarget)
    {
        TMGT_INF(">>processOccStartStatus(%d,0x%p)",
                 i_startCompleted, i_failedOccTarget);
        errlHndl_t l_err = nullptr;
        uint32_t l_huid = 0;
        bool skip_comm = true;
        if (i_failedOccTarget)
        {
            l_huid = TARGETING::get_huid(i_failedOccTarget);
        }
        TMGT_INF("processOccStartStatus(Start Success=%c, failedOcc=0x%08X)",
                 i_startCompleted?'y':'n', l_huid);

        TARGETING::Target* sys = nullptr;
        TARGETING::targetService().getTopLevelTarget(sys);
        uint8_t safeMode = 0;
        if(sys)
        {
            sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
        }
        if (safeMode == 0)
        {
            check_reset_count();
        }
        else
        {
            // OCCs were started, so clear Safe Mode
            TMGT_INF("processOccStartStatus: System was in Safe Mode, but OCCs "
                     "were started.  Clearing Safe Mode");
            safeMode = 0;
            sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
            OccManager::clearResetCounts();
        }

        if (false == int_flags_set(FLAG_HOLD_OCCS_IN_RESET))
        {
            if (i_startCompleted)
            {
                // Start listening for OCC atts
                OccManager::setOccsStarted(true);

                // Query functional OCCs (OCCs have just been started)
                l_err = OccManager::buildOccs(true);
                if (nullptr == l_err)
                {
                    if (nullptr != OccManager::getMasterOcc())
                    {
                        do
                        {
                            // Memory throttles are calculated during istep 18

                            // Make sure OCCs are ready for communication
                            l_err = OccManager::waitForOccCheckpoint();
                            if( l_err )
                            {
                                break;
                            }

#ifdef __HOSTBOOT_RUNTIME
                            nanosleep(1,0);
#endif

                            // Send poll to establish comm
                            TMGT_INF("Send initial poll to all OCCs to"
                                     " establish comm");
                            l_err = OccManager::sendOccPoll();
                            if (OccManager::occNeedsReset())
                            {
                                if (l_err == nullptr)
                                {
                                    /*@
                                     * @errortype
                                     * @reasoncode HTMGT_RC_OCC_UNEXPECTED_STATE
                                     * @moduleid  HTMGT_MOD_LOAD_START_STATUS
                                     * @devdesc OCC needs reset after initial poll
                                     * @custdesc An internal firmware error occurred
                                     */
                                    bldErrLog(l_err,
                                              HTMGT_MOD_LOAD_START_STATUS,
                                              HTMGT_RC_OCC_UNEXPECTED_STATE,
                                              0, 0, 0, 1,
                                              ERRORLOG::ERRL_SEV_INFORMATIONAL);
                                }
                                // No need to continue if reset is required
                                break;
                            }
                            else if (l_err)
                            {
                                // Continue even if polls failed (will retried)
                                ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                            }
                            skip_comm = false;

                            // Send ALL config data
                            l_err = sendOccConfigData();
                            if (l_err)
                            {
                                break;
                            }

                            // Set the User PCAP
                            l_err = sendOccUserPowerCap();
                            if (l_err)
                            {
                                break;
                            }

                            // Wait for all OCCs to go to the target state
                            l_err = waitForOccState();
                            if ( l_err )
                            {
                                break;
                            }

                            if (OccManager::occNeedsReset())
                            {
                                bldErrLog(l_err,
                                          HTMGT_MOD_LOAD_START_STATUS,
                                          HTMGT_RC_OCC_UNEXPECTED_STATE,
                                          0, 0, 0, 0,
                                          ERRORLOG::ERRL_SEV_INFORMATIONAL);
                                break;
                            }

                            // Set enabled sensors for all OCCs,
                            // so BMC can start communication with OCCs
                            l_err = setOccEnabledSensors(true);
                            if (l_err)
                            {
                                // Continue even if failed to update sensor
                                ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                            }

                        } while(0);
                    }
                    else
                    {
                        TMGT_ERR("Unable to find any Master capable OCCs");
                        /*@
                         * @errortype
                         * @reasoncode      HTMGT_RC_OCC_MASTER_NOT_FOUND
                         * @moduleid        HTMGT_MOD_LOAD_START_STATUS
                         * @userdata1       number of OCCs
                         * @devdesc         No OCC master was found
                         * @custdesc        An internal firmware error occurred
                         */
                        bldErrLog(l_err, HTMGT_MOD_LOAD_START_STATUS,
                                  HTMGT_RC_OCC_MASTER_NOT_FOUND,
                                  0, OccManager::getNumOccs(), 0, 0,
                                  ERRORLOG::ERRL_SEV_INFORMATIONAL);
                    }
                }
                else
                {
                    // Failed to find functional OCCs, no need to try again
                    // Set original error log as unrecoverable/degraded performance and commit
                    l_err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE1);
                    ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
                }
            }
            else
            {
                TMGT_ERR("All OCCs were not loaded/started successfully");
                /*@
                 * @errortype
                 * @reasoncode      HTMGT_RC_OCC_START_FAIL
                 * @moduleid        HTMGT_MOD_LOAD_START_STATUS
                 * @userdata1       Failing OCC HUID
                 * @devdesc         OCCs were not loaded/started successfully
                 * @custdesc        An internal firmware error occurred
                 */
                bldErrLog(l_err, HTMGT_MOD_LOAD_START_STATUS,
                          HTMGT_RC_OCC_START_FAIL,
                          0, l_huid, 0, 0,
                          ERRORLOG::ERRL_SEV_INFORMATIONAL);
            }

            if (nullptr != l_err)
            {
                // If the start failed, HTMGT will attempt reset.
                // This will end up being a recursive call: After the
                // reset is done, this function will get called again.
                // If the reset returns success, then we know the
                // recovery was successful. When there are multiple reset
                // failures, the inital resetOcc() calls will return an
                // error.  That error can be ignored IF the OCCs were
                // actually enabled successfully in later recursive calls.
                TMGT_ERR("OCCs not all active (rc=0x%04X).  Attempting OCC "
                         "Reset", l_err->reasonCode());
                TMGT_CONSOLE("OCCs are not active (rc=0x%04X). "
                             "Attempting OCC Reset",
                             l_err->reasonCode());
                TMGT_INF("processOccStartStatus: Calling resetOccs");
                // Reset ALL OCCs, don't skip incrementing reset count, and
                // if comm has not been established, don't try to talk to OCCs
                errlHndl_t reset_err = OccManager::resetOccs(nullptr,
                                                             false,
                                                             skip_comm);
                if(reset_err)
                {
                    // reset failed and OCCs still not running yet
                    TMGT_ERR("processOccStartStatus: OccManager::resetOccs"
                             " failed with 0x%04X",
                             reset_err->reasonCode());

                    // Only make original error unrecoverable if it was cause of safe mode
                    uint32_t safeInstance = 0;
                    if (l_err->reasonCode() ==
                        OccManager::getSafeModeReason(safeInstance))
                    {
                        // Set original error log as unrecoverable/degraded and commit
                        l_err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE1);
                    }
                    ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);

                    // Commit occReset error
                    ERRORLOG::errlCommit(reset_err, HTMGT_COMP_ID);
                }
                else
                {
                    const uint16_t l_rc = l_err->reasonCode();
{'fraction_non_alphanumeric': 0.06568619678109887, 'fraction_numerical': 0.004638071830650916, 'mean_word_length': 0.8807872959069559, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 144, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4473671', 'n_tokens_mistral': 5957, 'n_tokens_neox': 5595, 'n_words': 1356}