/**
 * Copyright (C) 2020 IBM Corporation
 *
 * 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.
 */

#include "registration.hpp"

extern "C"
{
#include <libpdbg.h>
#include <libpdbg_sbe.h>
}

#include "extensions/phal/create_pel.hpp"
#include "extensions/phal/dump_utils.hpp"

#include <attributes_info.H>
#include <fmt/format.h>
#include <libphal.H>
#include <phal_exception.H>
#include <sys/wait.h>
#include <unistd.h>

#include <phosphor-logging/log.hpp>

#include <system_error>
#include <vector>

namespace openpower
{
namespace misc
{

/**
 * @brief Calls sbe_enter_mpipl on the SBE in the provided target.
 * @return void
 */
void sbeEnterMpReboot(struct pdbg_target* tgt)
{
    using namespace openpower::pel;
    using namespace openpower::phal;
    using namespace openpower::phal::sbe;
    using namespace openpower::phal::exception;
    using namespace phosphor::logging;

    try
    {
        mpiplEnter(tgt);
    }
    catch (const sbeError_t& sbeError)
    {
        if (sbeError.errType() == SBE_CHIPOP_NOT_ALLOWED)
        {
            // SBE is not ready to accept chip-ops,
            // Skip the request, no additional error handling required.
            log<level::INFO>(
                fmt::format("EnterMPIPL: Skipping ({}) on proc({})",
                            sbeError.what(), pdbg_target_index(tgt))
                    .c_str());
            return;
        }

        log<level::ERR>(fmt::format("EnterMPIPL failed({}) on proc({})",
                                    sbeError.what(), pdbg_target_index(tgt))
                            .c_str());

        std::string event;
        bool dumpIsRequired = false;

        if (sbeError.errType() == SBE_CMD_TIMEOUT)
        {
            event = "org.open_power.Processor.Error.SbeChipOpTimeout";
            dumpIsRequired = true;
        }
        else
        {
            event = "org.open_power.Processor.Error.SbeChipOpFailure";
        }

        // SRC6 : [0:15] chip position [16:23] command class, [24:31] Type
        uint32_t index = pdbg_target_index(tgt);

        // TODO Replace these consts with pdbg defines once it is exported.
        // Ref : pdbg/libsbefifo/sbefifo_private.h
        constexpr auto SBEFIFO_CMD_CLASS_MPIPL = 0xA900;
        constexpr auto SBEFIFO_CMD_ENTER_MPIPL = 0x01;
        uint32_t cmd = SBEFIFO_CMD_CLASS_MPIPL | SBEFIFO_CMD_ENTER_MPIPL;

        // To store additional data about ffdc.
        FFDCData pelAdditionalData;
        pelAdditionalData.emplace_back("SRC6",
                                       std::to_string((index << 16) | cmd));
        auto logId = createSbeErrorPEL(event, sbeError, pelAdditionalData, tgt);

        if (dumpIsRequired)
        {
            // Request SBE Dump
            using namespace openpower::phal::dump;
            DumpParameters dumpParameters = {logId, index, SBE_DUMP_TIMEOUT,
                                             DumpType::SBE};
            requestDump(dumpParameters);
        }
        throw;
    }
    // Capture genaral libphal error
    catch (const phalError_t& phalError)
    {
        // Failure reported
        log<level::ERR>(fmt::format("captureFFDC: Exception({}) on proc({})",
                                    phalError.what(), pdbg_target_index(tgt))
                            .c_str());
        openpower::pel::createPEL(
            "org.open_power.Processor.Error.SbeChipOpFailure");
        throw;
    }

    log<level::INFO>(
        fmt::format("Enter MPIPL completed on proc({})", pdbg_target_index(tgt))
            .c_str());
}

/**
 * @brief initiate memory preserving reboot on each SBE.
 * @return void
 */
void enterMpReboot()
{
    using namespace phosphor::logging;
    struct pdbg_target* target;
    std::vector<pid_t> pidList;
    bool failed = false;
    pdbg_targets_init(NULL);
    ATTR_HWAS_STATE_Type hwasState;

    log<level::INFO>("Starting memory preserving reboot");
    pdbg_for_each_class_target("proc", target)
    {
        if (DT_GET_PROP(ATTR_HWAS_STATE, target, hwasState))
        {
            log<level::ERR>("Could not read HWAS_STATE attribute");
        }
        if (!hwasState.functional)
        {
            continue;
        }

        pid_t pid = fork();

        if (pid < 0)
        {
            log<level::ERR>("Fork failed while starting mp reboot");
            failed = true;
        }
        else if (pid == 0)
        {
            sbeEnterMpReboot(target);
            std::exit(EXIT_SUCCESS);
        }
        else
        {
            pidList.push_back(std::move(pid));
        }
    }

    // if no functional proc found exit with failure
    if (pidList.size() == 0)
    {
        log<level::ERR>("EnterMPReboot is not executed on any processors");
        openpower::pel::createPEL("org.open_power.PHAL.Error.MPReboot");
        std::exit(EXIT_FAILURE);
    }

    for (auto& p : pidList)
    {
        int status = 0;
        waitpid(p, &status, 0);
        if (WEXITSTATUS(status))
        {
            log<level::ERR>("Memory preserving reboot failed");
            failed = true;
        }
    }

    if (failed)
    {
        std::exit(EXIT_FAILURE);
    }
}

REGISTER_PROCEDURE("enterMpReboot", enterMpReboot)

} // namespace misc
} // namespace openpower
