blob: 7e4cce81bafc5dbe6a81f431b9edd3114bf6b257 [file] [log] [blame]
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfScomRegister.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 */
// Module Description **************************************************
//
// Description: This module provides the implementation for the PRD Scan
// Comm Register Chip class.
//
// End Module Description **********************************************
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include <iipchip.h>
#include <prdfScomRegister.H>
#include <iipconst.h>
#include <iipbits.h>
#include <prdfMain.H>
#include <prdfRasServices.H>
#include <prdfRegisterCache.H>
#include <prdfHomRegisterAccess.H>
#include <prdfPlatServices.H>
#include <prdfExtensibleChip.H>
//----------------------------------------------------------------------
// User Types
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Constants
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Macros
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Internal Function Prototypes
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Global Variables
//----------------------------------------------------------------------
//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------
// --------------------------------------------------------------------
namespace PRDF
{
// ---------------------------------------------------------------------
void ScomRegister::SetBitString( const BitString *bs )
{
BitString & l_string = AccessBitString();
l_string.setString(*bs);
}
//------------------------------------------------------------------------------
const BitString * ScomRegister::GetBitString(ATTENTION_TYPE i_type) const
{
// Calling Read() will ensure that an entry exists in the cache and the
// entry has at been synched with hardware at least once. Note that we
// cannot read hardware for write-only registers. In this case, an entry
// will be created in the cache, if it does not exist, when readCache() is
// called below.
if ( ( ACCESS_NONE != iv_operationType ) &&
( ACCESS_WO != iv_operationType ) )
{
Read();
}
return &(readCache());
}
//------------------------------------------------------------------------------
BitString & ScomRegister::AccessBitString()
{
// Calling Read() will ensure that an entry exists in the cache and the
// entry has at been synched with hardware at least once. Note that we
// cannot read hardware for write-only registers. In this case, an entry
// will be created in the cache, if it does not exist, when readCache() is
// called below.
if ( ( ACCESS_NONE != iv_operationType ) &&
( ACCESS_WO != iv_operationType ) )
{
Read();
}
return readCache();
}
//------------------------------------------------------------------------------
uint32_t ScomRegister::Read() const
{
uint32_t o_rc = SUCCESS;
// First query the cache for an existing entry.
if ( !queryCache() )
{
// There was not a previous entry in the cache, so do a ForceRead() to
// sync the cache with hardware.
o_rc = ForceRead();
}
return o_rc;
}
//------------------------------------------------------------------------------
uint32_t ScomRegister::ForceRead() const
{
#define PRDF_FUNC "[ScomRegister::ForceRead] "
uint32_t o_rc = FAIL;
do
{
// No read allowed if register access attribute is write-only or no
// access.
if ( ( ACCESS_NONE == iv_operationType ) &&
( ACCESS_WO == iv_operationType ) )
{
PRDF_ERR( PRDF_FUNC "Write-only register: 0x%08x 0x%016llx",
getChip()->GetId(), iv_scomAddress );
break;
}
// Read hardware.
o_rc = Access( readCache(), MopRegisterAccess::READ );
if ( SUCCESS != o_rc )
{
// The read failed. Remove the entry from the cache so a subsequent
// Read() will attempt to read from hardware again.
flushCache( getChip() );
}
} while (0);
return o_rc;
#undef PRDF_FUNC
}
//------------------------------------------------------------------------------
uint32_t ScomRegister::Write()
{
#define PRDF_FUNC "[ScomRegister::Write] "
uint32_t o_rc = FAIL;
do
{
// No write allowed if register access attribute is read-only or no
// access.
if ( ( ACCESS_NONE == iv_operationType ) &&
( ACCESS_RO == iv_operationType ) )
{
PRDF_ERR( PRDF_FUNC "Read-only register: 0x%08x 0x%016llx",
getChip()->GetId(), iv_scomAddress );
break;
}
// Query the cache for an existing entry.
if ( !queryCache() )
{
// Something bad happened and there was nothing in the cache to
// write to hardware.
PRDF_ERR( PRDF_FUNC "No entry found in cache: 0x%08x 0x%016llx",
getChip()->GetId(), iv_scomAddress );
break;
}
// Write hardware.
o_rc = Access( readCache(), MopRegisterAccess::WRITE );
} while (0);
return o_rc;
#undef PRDF_FUNC
}
//------------------------------------------------------------------------------
uint32_t ScomRegister::Access( BitString & bs,
MopRegisterAccess::Operation op ) const
{
int32_t l_rc = SCR_ACCESS_FAILED;
TARGETING::TargetHandle_t i_pchipTarget = getChip()->GetChipHandle();
l_rc = getScomService().Access( i_pchipTarget,bs,iv_scomAddress,op );
return(l_rc);
}
//-----------------------------------------------------------------------------
ExtensibleChip* ScomRegister::getChip( )const
{
ExtensibleChip* l_pchip = NULL;
l_pchip = ServiceDataCollector::getChipAnalyzed();
TARGETING::TYPE l_type = PlatServices::getTargetType(
l_pchip->GetChipHandle() );
PRDF_ASSERT( iv_chipType == l_type )
return l_pchip;
}
//------------------------------------------------------------------------------
bool ScomRegister::queryCache() const
{
RegDataCache & cache = RegDataCache::getCachedRegisters();
BitString * bs = cache.queryCache( getChip(), this );
return ( NULL != bs );
}
//------------------------------------------------------------------------------
BitString & ScomRegister::readCache() const
{
RegDataCache & cache = RegDataCache::getCachedRegisters();
return cache.read( getChip(), this );
}
//------------------------------------------------------------------------------
void ScomRegister::flushCache( ExtensibleChip *i_pChip ) const
{
RegDataCache & regDump = RegDataCache::getCachedRegisters();
if( NULL == i_pChip )
{
regDump.flush();
}
else
{
regDump.flush( i_pChip ,this );
}
}
//-----------------------------------------------------------------------------
bool ScomRegister::operator == ( const ScomRegister & i_rightRegister ) const
{
if( iv_scomAddress == i_rightRegister.GetAddress() )
{
return ( iv_chipType == i_rightRegister.getChipType() );
}
else
{
return false ;
}
}
//-----------------------------------------------------------------------------
bool ScomRegister::operator < ( const ScomRegister & i_rightRegister ) const
{
if( iv_scomAddress == i_rightRegister.GetAddress() )
{
return ( iv_chipType < i_rightRegister.getChipType() );
}
else
{
return( iv_scomAddress < i_rightRegister.GetAddress() );
}
}
//-----------------------------------------------------------------------------
bool ScomRegister::operator >= ( const ScomRegister & i_rightRegister ) const
{
return !( *this < i_rightRegister );
}
}//namespace PRDF ends