aboutsummaryrefslogtreecommitdiff
path: root/decoder/source/mem_acc
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/source/mem_acc')
-rw-r--r--decoder/source/mem_acc/trc_mem_acc_base.cpp148
-rw-r--r--decoder/source/mem_acc/trc_mem_acc_bufptr.cpp54
-rw-r--r--decoder/source/mem_acc/trc_mem_acc_cb.cpp32
-rw-r--r--decoder/source/mem_acc/trc_mem_acc_file.cpp391
-rw-r--r--decoder/source/mem_acc/trc_mem_acc_mapper.cpp238
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 */