blob: 3957b984037ea8d6c2682d4375e74beaa5190d38 [file] [log] [blame]
/*
* \file trc_mem_acc_mapper.cpp
* \brief Reference CoreSight Trace Decoder :
*
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mem_acc/trc_mem_acc_mapper.h"
#include "mem_acc/trc_mem_acc_file.h"
/************************************************************************************/
/* mappers base class */
/************************************************************************************/
TrcMemAccMapper::TrcMemAccMapper() :
m_acc_curr(0),
m_trace_id_curr(0),
m_using_trace_id(false),
m_err_log(0)
{
}
TrcMemAccMapper::TrcMemAccMapper(bool using_trace_id) :
m_acc_curr(0),
m_trace_id_curr(0),
m_using_trace_id(using_trace_id),
m_err_log(0)
{
}
TrcMemAccMapper::~TrcMemAccMapper()
{
}
// memory access interface
rctdl_err_t TrcMemAccMapper::ReadTargetMemory(const rctdl_vaddr_t address, const uint8_t cs_trace_id, const rctdl_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer)
{
bool bReadFromCurr = true;
/* see if the address is in any range we know */
if(!readFromCurrent(address, mem_space, cs_trace_id))
bReadFromCurr = findAccessor(address, mem_space, cs_trace_id);
/* if bReadFromCurr then we know m_acc_curr is set */
if(bReadFromCurr)
*num_bytes = m_acc_curr->readBytes(address, mem_space, *num_bytes,p_buffer);
else
*num_bytes = 0;
return RCTDL_OK;
}
void TrcMemAccMapper::RemoveAllAccessors()
{
TrcMemAccessorBase *pAcc = 0;
pAcc = getFirstAccessor();
while(pAcc != 0)
{
TrcMemAccFactory::DestroyAccessor(pAcc);
pAcc = getNextAccessor();
}
clearAccessorList();
}
rctdl_err_t TrcMemAccMapper::RemoveAccessorByAddress(const rctdl_vaddr_t st_address, const rctdl_mem_space_acc_t mem_space, const uint8_t cs_trace_id /* = 0 */)
{
rctdl_err_t err = RCTDL_OK;
if(findAccessor(st_address,mem_space,cs_trace_id))
{
err = RemoveAccessor(m_acc_curr);
m_acc_curr = 0;
}
else
err = RCTDL_ERR_INVALID_PARAM_VAL;
return err;
}
void TrcMemAccMapper::LogMessage(const std::string &msg)
{
if(m_err_log)
m_err_log->LogMessage(ITraceErrorLog::HANDLE_GEN_INFO,RCTDL_ERR_SEV_INFO,msg);
}
/************************************************************************************/
/* mappers global address space class - no differentiation in core trace IDs */
/************************************************************************************/
TrcMemAccMapGlobalSpace::TrcMemAccMapGlobalSpace() : TrcMemAccMapper()
{
}
TrcMemAccMapGlobalSpace::~TrcMemAccMapGlobalSpace()
{
}
rctdl_err_t TrcMemAccMapGlobalSpace::AddAccessor(TrcMemAccessorBase *p_accessor, const uint8_t /*cs_trace_id*/)
{
rctdl_err_t err = RCTDL_OK;
bool bOverLap = false;
if(!p_accessor->validateRange())
return RCTDL_ERR_MEM_ACC_RANGE_INVALID;
std::vector<TrcMemAccessorBase *>::const_iterator it = m_acc_global.begin();
while((it != m_acc_global.end()) && !bOverLap)
{
// if overlap and memory space match
if( ((*it)->overLapRange(p_accessor)) &&
((*it)->inMemSpace(p_accessor->getMemSpace()))
)
{
bOverLap = true;
err = RCTDL_ERR_MEM_ACC_OVERLAP;
}
it++;
}
// no overlap - add to the list of ranges.
if(!bOverLap)
m_acc_global.push_back(p_accessor);
return err;
}
bool TrcMemAccMapGlobalSpace::findAccessor(const rctdl_vaddr_t address, const rctdl_mem_space_acc_t mem_space, const uint8_t /*cs_trace_id*/)
{
bool bFound = false;
std::vector<TrcMemAccessorBase *>::const_iterator it = m_acc_global.begin();
while((it != m_acc_global.end()) && !bFound)
{
if( (*it)->addrInRange(address) &&
(*it)->inMemSpace(mem_space))
{
bFound = true;
m_acc_curr = *it;
}
it++;
}
return bFound;
}
bool TrcMemAccMapGlobalSpace::readFromCurrent(const rctdl_vaddr_t address, const rctdl_mem_space_acc_t mem_space, const uint8_t /*cs_trace_id*/)
{
bool readFromCurr = false;
if(m_acc_curr)
readFromCurr = (m_acc_curr->addrInRange(address) && m_acc_curr->inMemSpace(mem_space));
return readFromCurr;
}
TrcMemAccessorBase * TrcMemAccMapGlobalSpace::getFirstAccessor()
{
TrcMemAccessorBase *p_acc = 0;
m_acc_it = m_acc_global.begin();
if(m_acc_it != m_acc_global.end())
{
p_acc = *m_acc_it;
}
return p_acc;
}
TrcMemAccessorBase *TrcMemAccMapGlobalSpace::getNextAccessor()
{
TrcMemAccessorBase *p_acc = 0;
m_acc_it++;
if(m_acc_it != m_acc_global.end())
{
p_acc = *m_acc_it;
}
return p_acc;
}
void TrcMemAccMapGlobalSpace::clearAccessorList()
{
m_acc_global.clear();
}
rctdl_err_t TrcMemAccMapGlobalSpace::RemoveAccessor(const TrcMemAccessorBase *p_accessor)
{
bool bFound = false;
TrcMemAccessorBase *p_acc = getFirstAccessor();
while(p_acc != 0)
{
if(p_acc == p_accessor)
{
m_acc_global.erase(m_acc_it);
TrcMemAccFactory::DestroyAccessor(p_acc);
p_acc = 0;
bFound = true;
}
else
p_acc = getNextAccessor();
}
return bFound ? RCTDL_OK : RCTDL_ERR_INVALID_PARAM_VAL;
}
void TrcMemAccMapGlobalSpace::logMappedRanges()
{
std::string accStr;
TrcMemAccessorBase *pAccessor = getFirstAccessor();
LogMessage("Mapped Memory Accessors\n");
while(pAccessor != 0)
{
pAccessor->getMemAccString(accStr);
accStr += "\n";
LogMessage(accStr);
pAccessor = getNextAccessor();
}
LogMessage("========================\n");
}
/* End of File trc_mem_acc_mapper.cpp */