diff options
Diffstat (limited to 'decoder/source/mem_acc')
-rw-r--r-- | decoder/source/mem_acc/trc_mem_acc_base.cpp | 148 | ||||
-rw-r--r-- | decoder/source/mem_acc/trc_mem_acc_bufptr.cpp | 54 | ||||
-rw-r--r-- | decoder/source/mem_acc/trc_mem_acc_cb.cpp | 32 | ||||
-rw-r--r-- | decoder/source/mem_acc/trc_mem_acc_file.cpp | 391 | ||||
-rw-r--r-- | decoder/source/mem_acc/trc_mem_acc_mapper.cpp | 238 |
5 files changed, 863 insertions, 0 deletions
diff --git a/decoder/source/mem_acc/trc_mem_acc_base.cpp b/decoder/source/mem_acc/trc_mem_acc_base.cpp new file mode 100644 index 000000000000..1250bdc42d93 --- /dev/null +++ b/decoder/source/mem_acc/trc_mem_acc_base.cpp @@ -0,0 +1,148 @@ +/*! + * \file trc_mem_acc_base.cpp + * \brief OpenCSD : Trace memory accessor base class. + * + * \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_base.h" +#include "mem_acc/trc_mem_acc_file.h" +#include "mem_acc/trc_mem_acc_cb.h" +#include "mem_acc/trc_mem_acc_bufptr.h" + +#include <sstream> +#include <iomanip> + + /** Accessor Creation */ +ocsd_err_t TrcMemAccFactory::CreateBufferAccessor(TrcMemAccessorBase **pAccessor, const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size) +{ + ocsd_err_t err = OCSD_OK; + TrcMemAccessorBase *pAcc = 0; + pAcc = new (std::nothrow) TrcMemAccBufPtr(s_address,p_buffer,size); + if(pAcc == 0) + err = OCSD_ERR_MEM; + *pAccessor = pAcc; + return err; +} + +ocsd_err_t TrcMemAccFactory::CreateFileAccessor(TrcMemAccessorBase **pAccessor, const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset /*= 0*/, size_t size /*= 0*/) +{ + ocsd_err_t err = OCSD_OK; + TrcMemAccessorFile *pFileAccessor = 0; + err = TrcMemAccessorFile::createFileAccessor(&pFileAccessor, pathToFile, startAddr, offset,size); + *pAccessor = pFileAccessor; + return err; +} + +ocsd_err_t TrcMemAccFactory::CreateCBAccessor(TrcMemAccessorBase **pAccessor, const ocsd_vaddr_t s_address, const ocsd_vaddr_t e_address, const ocsd_mem_space_acc_t mem_space) +{ + ocsd_err_t err = OCSD_OK; + TrcMemAccessorBase *pAcc = 0; + pAcc = new (std::nothrow) TrcMemAccCB(s_address,e_address,mem_space); + if(pAcc == 0) + err = OCSD_ERR_MEM; + *pAccessor = pAcc; + return err; +} + +/** Accessor Destruction */ +void TrcMemAccFactory::DestroyAccessor(TrcMemAccessorBase *pAccessor) +{ + switch(pAccessor->getType()) + { + case TrcMemAccessorBase::MEMACC_FILE: + TrcMemAccessorFile::destroyFileAccessor(dynamic_cast<TrcMemAccessorFile *>(pAccessor)); + break; + + case TrcMemAccessorBase::MEMACC_CB_IF: + case TrcMemAccessorBase::MEMACC_BUFPTR: + delete pAccessor; + break; + + default: + break; + } +} + + +/* memory access info logging */ +void TrcMemAccessorBase::getMemAccString(std::string &accStr) const +{ + std::ostringstream oss; + + switch(m_type) + { + case MEMACC_FILE: + oss << "FileAcc; Range::0x"; + break; + + case MEMACC_BUFPTR: + oss << "BuffAcc; Range::0x"; + break; + + case MEMACC_CB_IF: + oss << "CB Acc; Range::0x"; + break; + + default: + oss << "UnknAcc; Range::0x"; + break; + } + oss << std::hex << std::setw(2) << std::setfill('0') << m_startAddress << ":" << m_endAddress; + oss << "; Mem Space::"; + switch(m_mem_space) + { + case OCSD_MEM_SPACE_EL1S: oss << "EL1S"; break; + case OCSD_MEM_SPACE_EL1N: oss << "EL1N"; break; + case OCSD_MEM_SPACE_EL2: oss << "EL2"; break; + case OCSD_MEM_SPACE_EL3: oss << "EL3"; break; + case OCSD_MEM_SPACE_S: oss << "Any S"; break; + case OCSD_MEM_SPACE_N: oss << "Any NS"; break; + case OCSD_MEM_SPACE_ANY: oss << "Any"; break; + + default: + { + uint8_t MSBits = (uint8_t)m_mem_space; + if(MSBits & (uint8_t)OCSD_MEM_SPACE_EL1S) + oss << "EL1S,"; + if(MSBits & (uint8_t)OCSD_MEM_SPACE_EL1N) + oss << "EL1N,"; + if(MSBits & (uint8_t)OCSD_MEM_SPACE_EL2) + oss << "EL2,"; + if(MSBits & (uint8_t)OCSD_MEM_SPACE_EL3) + oss << "EL3,"; + } + break; + } + accStr = oss.str(); +} + +/* End of File trc_mem_acc_base.cpp */ diff --git a/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp b/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp new file mode 100644 index 000000000000..fee663b30d06 --- /dev/null +++ b/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp @@ -0,0 +1,54 @@ +/* + * \file trc_mem_acc_bufptr.cpp + * \brief OpenCSD : + * + * \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 <cstring> + +#include "mem_acc/trc_mem_acc_bufptr.h" + +TrcMemAccBufPtr::TrcMemAccBufPtr(const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size) : + TrcMemAccessorBase(MEMACC_BUFPTR, s_address, s_address+size-1), + m_p_buffer(p_buffer), + m_size(size) +{ +} + +const uint32_t TrcMemAccBufPtr::readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint32_t reqBytes, uint8_t *byteBuffer) +{ + // mapper wlll filter memory spaces. + uint32_t bytesRead = bytesInRange(address,reqBytes); // check bytes available + if(bytesRead) + memcpy(byteBuffer,m_p_buffer+address-m_startAddress,bytesRead); + return bytesRead; +} + +/* End of File trc_mem_acc_bufptr.cpp */ diff --git a/decoder/source/mem_acc/trc_mem_acc_cb.cpp b/decoder/source/mem_acc/trc_mem_acc_cb.cpp new file mode 100644 index 000000000000..28dedcb0fba6 --- /dev/null +++ b/decoder/source/mem_acc/trc_mem_acc_cb.cpp @@ -0,0 +1,32 @@ +/*! + * \file trc_mem_acc_cb.cpp + * \brief OpenCSD : Trace Mem accessor - callback function + * + * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. + */ + +#include "mem_acc/trc_mem_acc_cb.h" + +TrcMemAccCB::TrcMemAccCB(const ocsd_vaddr_t s_address, + const ocsd_vaddr_t e_address, + const ocsd_mem_space_acc_t mem_space) : + TrcMemAccessorBase(MEMACC_CB_IF, s_address, e_address), + m_p_CBclass(0), + m_p_CBfn(0), + m_p_cbfn_context(0) +{ + setMemSpace(mem_space); +} + +/** Memory access override - allow decoder to read bytes from the buffer. */ +const uint32_t TrcMemAccCB::readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t memSpace, const uint32_t reqBytes, uint8_t *byteBuffer) +{ + // if we have a callback object, use it to call back. + if(m_p_CBclass) + return m_p_CBclass->readBytes(address,memSpace,reqBytes,byteBuffer); + if(m_p_CBfn) + return m_p_CBfn(m_p_cbfn_context, address,memSpace,reqBytes,byteBuffer); + return 0; +} + +/* End of File trc_mem_acc_cb.cpp */ diff --git a/decoder/source/mem_acc/trc_mem_acc_file.cpp b/decoder/source/mem_acc/trc_mem_acc_file.cpp new file mode 100644 index 000000000000..87901c83dcee --- /dev/null +++ b/decoder/source/mem_acc/trc_mem_acc_file.cpp @@ -0,0 +1,391 @@ +/* + * \file trc_mem_acc_file.cpp + * \brief OpenCSD : + * + * \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_file.h" + +#include <sstream> +#include <iomanip> + +/***************************************************/ +/* protected construction and reference counting */ +/***************************************************/ + +TrcMemAccessorFile::TrcMemAccessorFile() : TrcMemAccessorBase(MEMACC_FILE) +{ + m_ref_count = 0; + m_base_range_set = false; + m_has_access_regions = false; + m_file_size = 0; +} + +TrcMemAccessorFile::~TrcMemAccessorFile() +{ + if(m_mem_file.is_open()) + m_mem_file.close(); + if(m_access_regions.size()) + { + std::list<FileRegionMemAccessor *>::iterator it; + it = m_access_regions.begin(); + while(it != m_access_regions.end()) + { + delete (*it); + it++; + } + m_access_regions.clear(); + } +} + +ocsd_err_t TrcMemAccessorFile::initAccessor(const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset, size_t size) +{ + ocsd_err_t err = OCSD_OK; + bool init = false; + + m_mem_file.open(pathToFile.c_str(), std::ifstream::binary | std::ifstream::ate); + if(m_mem_file.is_open()) + { + m_file_size = (ocsd_vaddr_t)m_mem_file.tellg() & ((ocsd_vaddr_t)~0x1); + m_mem_file.seekg(0, m_mem_file.beg); + // adding an offset of 0, sets the base range. + if((offset == 0) && (size == 0)) + { + init = AddOffsetRange(startAddr, ((size_t)m_file_size)-offset, offset); + } + else if((offset + size) <= m_file_size) + { + // if offset != 0, size must by != 0 + init = AddOffsetRange(startAddr, size, offset); + } + m_file_path = pathToFile; + } + else + err = OCSD_ERR_MEM_ACC_FILE_NOT_FOUND; + if(!init) + err = OCSD_ERR_NOT_INIT; + return err; +} + + +FileRegionMemAccessor *TrcMemAccessorFile::getRegionForAddress(const ocsd_vaddr_t startAddr) const +{ + FileRegionMemAccessor *p_region = 0; + if(m_has_access_regions) + { + std::list<FileRegionMemAccessor *>::const_iterator it; + it = m_access_regions.begin(); + while((it != m_access_regions.end()) && (p_region == 0)) + { + if((*it)->addrInRange(startAddr)) + p_region = *it; + it++; + } + } + return p_region; +} + + +/***************************************************/ +/* static object creation */ +/***************************************************/ + +std::map<std::string, TrcMemAccessorFile *> TrcMemAccessorFile::s_FileAccessorMap; + +// return existing or create new accessor +ocsd_err_t TrcMemAccessorFile::createFileAccessor(TrcMemAccessorFile **p_acc, const std::string &pathToFile, ocsd_vaddr_t startAddr, size_t offset /*= 0*/, size_t size /*= 0*/) +{ + ocsd_err_t err = OCSD_OK; + TrcMemAccessorFile * acc = 0; + std::map<std::string, TrcMemAccessorFile *>::iterator it = s_FileAccessorMap.find(pathToFile); + if(it != s_FileAccessorMap.end()) + { + acc = it->second; + if(acc->addrStartOfRange(startAddr)) + acc->IncRefCount(); + else + { + err = OCSD_ERR_MEM_ACC_FILE_DIFF_RANGE; + acc = 0; + } + } + else + { + acc = new (std::nothrow) TrcMemAccessorFile(); + if(acc != 0) + { + if((err = acc->initAccessor(pathToFile,startAddr, offset,size)) == OCSD_OK) + { + acc->IncRefCount(); + s_FileAccessorMap.insert(std::pair<std::string, TrcMemAccessorFile *>(pathToFile,acc)); + } + else + { + delete acc; + acc = 0; + } + } + else + err = OCSD_ERR_MEM; + } + *p_acc = acc; + return err; +} + +void TrcMemAccessorFile::destroyFileAccessor(TrcMemAccessorFile *p_accessor) +{ + if(p_accessor != 0) + { + p_accessor->DecRefCount(); + if(p_accessor->getRefCount() == 0) + { + std::map<std::string, TrcMemAccessorFile *>::iterator it = s_FileAccessorMap.find(p_accessor->getFilePath()); + if(it != s_FileAccessorMap.end()) + { + s_FileAccessorMap.erase(it); + } + delete p_accessor; + } + } +} + +const bool TrcMemAccessorFile::isExistingFileAccessor(const std::string &pathToFile) +{ + bool bExists = false; + std::map<std::string, TrcMemAccessorFile *>::const_iterator it = s_FileAccessorMap.find(pathToFile); + if(it != s_FileAccessorMap.end()) + bExists = true; + return bExists; +} + +TrcMemAccessorFile * TrcMemAccessorFile::getExistingFileAccessor(const std::string &pathToFile) +{ + TrcMemAccessorFile * p_acc = 0; + std::map<std::string, TrcMemAccessorFile *>::iterator it = s_FileAccessorMap.find(pathToFile); + if(it != s_FileAccessorMap.end()) + p_acc = it->second; + return p_acc; +} + + + +/***************************************************/ +/* accessor instance functions */ +/***************************************************/ +const uint32_t TrcMemAccessorFile::readBytes(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint32_t reqBytes, uint8_t *byteBuffer) +{ + if(!m_mem_file.is_open()) + return 0; + uint32_t bytesRead = 0; + + if(m_base_range_set) + { + bytesRead = TrcMemAccessorBase::bytesInRange(address,reqBytes); // get avialable bytes in range. + if(bytesRead) + { + ocsd_vaddr_t addr_pos = (ocsd_vaddr_t)m_mem_file.tellg(); + if((address - m_startAddress) != addr_pos) + m_mem_file.seekg(address - m_startAddress); + m_mem_file.read((char *)byteBuffer,bytesRead); + } + } + + if((bytesRead == 0) && m_has_access_regions) + { + bytesRead = bytesInRange(address,reqBytes); + if(bytesRead) + { + FileRegionMemAccessor *p_region = getRegionForAddress(address); + ocsd_vaddr_t addr_pos = (ocsd_vaddr_t)m_mem_file.tellg(); + if((address - p_region->regionStartAddress() + p_region->getOffset()) != addr_pos) + m_mem_file.seekg(address - p_region->regionStartAddress() + p_region->getOffset()); + m_mem_file.read((char *)byteBuffer,bytesRead); + } + } + return bytesRead; +} + +bool TrcMemAccessorFile::AddOffsetRange(const ocsd_vaddr_t startAddr, const size_t size, const size_t offset) +{ + bool addOK = false; + if(m_file_size == 0) // must have set the file size + return false; + if(addrInRange(startAddr) || addrInRange(startAddr+size-1)) // cannot be overlapping + return false; + + // now either set the base range or an offset range + if(offset == 0) + { + if(!m_base_range_set) + { + setRange(startAddr, startAddr+size-1); + m_base_range_set = true; + addOK = true; + } + } + else + { + if((offset + size) <= m_file_size) + { + FileRegionMemAccessor *frmacc = new (std::nothrow) FileRegionMemAccessor(); + if(frmacc) + { + frmacc->setOffset(offset); + frmacc->setRange(startAddr,startAddr+size-1); + m_access_regions.push_back(frmacc); + m_access_regions.sort(); + // may need to trim the 0 offset base range... + if(m_base_range_set) + { + std::list<FileRegionMemAccessor *>::iterator it; + it = m_access_regions.begin(); + size_t first_range_offset = (*it)->getOffset(); + if((m_startAddress + first_range_offset - 1) > m_endAddress) + m_endAddress = m_startAddress + first_range_offset - 1; + } + addOK = true; + m_has_access_regions = true; + } + } + } + return addOK; +} + +const bool TrcMemAccessorFile::addrInRange(const ocsd_vaddr_t s_address) const +{ + bool bInRange = false; + if(m_base_range_set) + bInRange = TrcMemAccessorBase::addrInRange(s_address); + + if(!bInRange && m_has_access_regions) + { + if(getRegionForAddress(s_address) != 0) + bInRange = true; + } + return bInRange; +} + +const bool TrcMemAccessorFile::addrStartOfRange(const ocsd_vaddr_t s_address) const +{ + bool bInRange = false; + if(m_base_range_set) + bInRange = TrcMemAccessorBase::addrStartOfRange(s_address); + if(!bInRange && m_has_access_regions) + { + FileRegionMemAccessor *pRegion = getRegionForAddress(s_address); + if(pRegion) + bInRange = (pRegion->regionStartAddress() == s_address); + } + return bInRange; +} + + + /* validate ranges */ +const bool TrcMemAccessorFile::validateRange() +{ + bool bRangeValid = true; + if(m_base_range_set) + bRangeValid = TrcMemAccessorBase::validateRange(); + + if(m_has_access_regions && bRangeValid) + { + std::list<FileRegionMemAccessor *>::const_iterator it; + it = m_access_regions.begin(); + while((it != m_access_regions.end()) && bRangeValid) + { + bRangeValid = (*it)->validateRange(); + it++; + } + } + return bRangeValid; +} + +const uint32_t TrcMemAccessorFile::bytesInRange(const ocsd_vaddr_t s_address, const uint32_t reqBytes) const +{ + uint32_t bytesInRange = 0; + if(m_base_range_set) + bytesInRange = TrcMemAccessorBase::bytesInRange(s_address,reqBytes); + + if((bytesInRange == 0) && (m_has_access_regions)) + { + FileRegionMemAccessor *p_region = getRegionForAddress(s_address); + bytesInRange = p_region->bytesInRange(s_address,reqBytes); + } + + return bytesInRange; +} + +const bool TrcMemAccessorFile::overLapRange(const TrcMemAccessorBase *p_test_acc) const +{ + bool bOverLapRange = false; + if(m_base_range_set) + bOverLapRange = TrcMemAccessorBase::overLapRange(p_test_acc); + + if(!bOverLapRange && (m_has_access_regions)) + { + std::list<FileRegionMemAccessor *>::const_iterator it; + it = m_access_regions.begin(); + while((it != m_access_regions.end()) && !bOverLapRange) + { + bOverLapRange = (*it)->overLapRange(p_test_acc); + it++; + } + } + return bOverLapRange; +} + + /*! Override to handle ranges and offset accessors plus add in file name. */ +void TrcMemAccessorFile::getMemAccString(std::string &accStr) const +{ + std::ostringstream oss; + accStr = ""; + if(m_base_range_set) + { + TrcMemAccessorBase::getMemAccString(accStr); + } + + if(m_has_access_regions) + { + std::string addStr; + std::list<FileRegionMemAccessor *>::const_iterator it; + it = m_access_regions.begin(); + while(it != m_access_regions.end()) + { + (*it)->getMemAccString(addStr); + if(accStr.length()) + accStr += "\n"; + accStr += addStr; + it++; + } + } + accStr += (std::string)"\nFilename=" + m_file_path; +} + +/* End of File trc_mem_acc_file.cpp */ diff --git a/decoder/source/mem_acc/trc_mem_acc_mapper.cpp b/decoder/source/mem_acc/trc_mem_acc_mapper.cpp new file mode 100644 index 000000000000..6d4f085c6fa0 --- /dev/null +++ b/decoder/source/mem_acc/trc_mem_acc_mapper.cpp @@ -0,0 +1,238 @@ +/* + * \file trc_mem_acc_mapper.cpp + * \brief OpenCSD : + * + * \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 +ocsd_err_t TrcMemAccMapper::ReadTargetMemory(const ocsd_vaddr_t address, const uint8_t cs_trace_id, const ocsd_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 OCSD_OK; +} + +void TrcMemAccMapper::RemoveAllAccessors() +{ + TrcMemAccessorBase *pAcc = 0; + pAcc = getFirstAccessor(); + while(pAcc != 0) + { + TrcMemAccFactory::DestroyAccessor(pAcc); + pAcc = getNextAccessor(); + } + clearAccessorList(); +} + +ocsd_err_t TrcMemAccMapper::RemoveAccessorByAddress(const ocsd_vaddr_t st_address, const ocsd_mem_space_acc_t mem_space, const uint8_t cs_trace_id /* = 0 */) +{ + ocsd_err_t err = OCSD_OK; + if(findAccessor(st_address,mem_space,cs_trace_id)) + { + err = RemoveAccessor(m_acc_curr); + m_acc_curr = 0; + } + else + err = OCSD_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,OCSD_ERR_SEV_INFO,msg); +} + +/************************************************************************************/ +/* mappers global address space class - no differentiation in core trace IDs */ +/************************************************************************************/ +TrcMemAccMapGlobalSpace::TrcMemAccMapGlobalSpace() : TrcMemAccMapper() +{ +} + +TrcMemAccMapGlobalSpace::~TrcMemAccMapGlobalSpace() +{ +} + +ocsd_err_t TrcMemAccMapGlobalSpace::AddAccessor(TrcMemAccessorBase *p_accessor, const uint8_t /*cs_trace_id*/) +{ + ocsd_err_t err = OCSD_OK; + bool bOverLap = false; + + if(!p_accessor->validateRange()) + return OCSD_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 = OCSD_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 ocsd_vaddr_t address, const ocsd_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 ocsd_vaddr_t address, const ocsd_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(); +} + +ocsd_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 ? OCSD_OK : OCSD_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 */ |