/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2017                        */
/* [+] 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 prdfHomRegisterAccess.C
  @brief definition of HomRegisterAccess
*/
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------

#include <hei_includes.hpp>
#include <util/hei_bit_string.hpp>

#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
#include <prdfMain.H>
#include <prdfPlatServices.H>
#include <prdfGlobal.H>
#include <prdfErrlUtil.H>

#ifdef __HOSTBOOT_RUNTIME
#include <pm_common_ext.H>
#include <p9_stop_api.H>
#endif

using namespace TARGETING;

namespace PRDF
{

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//------------------------------------------------------------------------------
// Member Function Specifications
//------------------------------------------------------------------------------

ScomService& getScomService()
{
    return PRDF_GET_SINGLETON(theScomService);
}

ScomService::ScomService() :
    iv_ScomAccessor(nullptr)
{
    PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
    iv_ScomAccessor = new ScomAccessor();
}

ScomService::~ScomService()
{
    if(nullptr != iv_ScomAccessor)
    {
        PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = nullptr;
    }
}

void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
{
    PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");

    if(nullptr != iv_ScomAccessor)
    {
        PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = nullptr;
    }

    iv_ScomAccessor = &i_ScomAccessor;
}

uint32_t ScomService::Access(TargetHandle_t i_target,
                             BitString & bs,
                             uint64_t registerId,
                             RegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomService::Access()");
    uint32_t rc = SUCCESS;

    rc = iv_ScomAccessor->Access( i_target,
                                  bs,
                                  registerId,
                                  operation);

    PRDF_DEXIT("ScomService::Access(): rc=%d", rc);

    return rc;
}


uint32_t ScomAccessor::Access(TargetHandle_t i_target,
                                BitString & bs,
                                uint64_t registerId,
                                RegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomAccessor::Access()");

    uint32_t rc = SUCCESS;

    if(i_target != nullptr)
    {
        switch (operation)
        {
            case RegisterAccess::WRITE:
            {
                rc = PRDF::PlatServices::putScom(i_target, bs, registerId);

                #ifdef __HOSTBOOT_RUNTIME
                using namespace stopImageSection;

                // Update CORE/EQ/EX Fir masks in HCODE image
                TARGETING::TYPE type = PlatServices::getTargetType(i_target);
                if( TYPE_EX == type || TYPE_EQ == type || TYPE_CORE == type )
                {
                    uint32_t l_MaskReg[7] = {
                                        0x2004000f,   // EC_LFIR_MASK_OR
                                        0x20010a45,   // EC_COREFIR_MASK_OR
                                        0x1004000f,   // EQ_LOCAL_FIR_MASK_OR
                                        0x10010805,   // EX_L2FIR_MASK_OR
                                        0x10011005,   // EX_NCUFIR_MASK_OR
                                        0x10011805,   // EX_L3FIR_MASK_OR
                                        0x10012005 }; // EX_CMEFIR_MASK_OR

                    for(uint32_t l_count = 0; l_count < 7; l_count++)
                    {
                        if( l_MaskReg[l_count]  == registerId )
                        {
                            errlHndl_t err = nullptr;
                            uint32_t sec = (TYPE_CORE == type) ?
                                P9_STOP_SECTION_CORE_SCOM :
                                P9_STOP_SECTION_EQ_SCOM;

                            uint64_t scomVal =
                                (((uint64_t)bs.getFieldJustify(0, 32)) << 32) |
                                 ((uint64_t)bs.getFieldJustify(32, 32));

                            err = RTPM::hcode_update(sec,
                                                     P9_STOP_SCOM_OR_APPEND,
                                                     i_target,
                                                     registerId,
                                                     scomVal);
                            if( nullptr != err)
                            {
                                HEI_ERR("[ScomAccessor::Access()] Error in"
                                         " hcode_update");
                                PRDF_COMMIT_ERRL( err, ERRL_ACTION_REPORT );
                            }
                            break;
                        }
                    }
                }
                #endif
                break;
            }

            case RegisterAccess::READ:
                bs.clearAll(); // clear all bits

                rc = PRDF::PlatServices::getScom(i_target, bs, registerId);

                break;

            default:
                HEI_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X",
                          operation);
                break;

        } // end switch operation

    }
    else // Invalid target
    {
        rc = PRD_SCANCOM_FAILURE;
    }

    PRDF_DEXIT("ScomAccessor::Access()");

    return rc;
}

} // End namespace PRDF
