1 /* 2 * \file trc_mem_acc_mapper.cpp 3 * \brief OpenCSD : 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 8 /* 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the copyright holder nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "mem_acc/trc_mem_acc_mapper.h" 36 #include "mem_acc/trc_mem_acc_file.h" 37 38 /************************************************************************************/ 39 /* mappers base class */ 40 /************************************************************************************/ 41 42 TrcMemAccMapper::TrcMemAccMapper() : 43 m_acc_curr(0), 44 m_trace_id_curr(0), 45 m_using_trace_id(false), 46 m_err_log(0) 47 { 48 } 49 50 TrcMemAccMapper::TrcMemAccMapper(bool using_trace_id) : 51 m_acc_curr(0), 52 m_trace_id_curr(0), 53 m_using_trace_id(using_trace_id), 54 m_err_log(0) 55 { 56 } 57 58 TrcMemAccMapper::~TrcMemAccMapper() 59 { 60 } 61 62 // memory access interface 63 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) 64 { 65 bool bReadFromCurr = true; 66 67 /* see if the address is in any range we know */ 68 if(!readFromCurrent(address, mem_space, cs_trace_id)) 69 bReadFromCurr = findAccessor(address, mem_space, cs_trace_id); 70 71 /* if bReadFromCurr then we know m_acc_curr is set */ 72 if(bReadFromCurr) 73 *num_bytes = m_acc_curr->readBytes(address, mem_space, *num_bytes,p_buffer); 74 else 75 *num_bytes = 0; 76 return OCSD_OK; 77 } 78 79 void TrcMemAccMapper::RemoveAllAccessors() 80 { 81 TrcMemAccessorBase *pAcc = 0; 82 pAcc = getFirstAccessor(); 83 while(pAcc != 0) 84 { 85 TrcMemAccFactory::DestroyAccessor(pAcc); 86 pAcc = getNextAccessor(); 87 } 88 clearAccessorList(); 89 } 90 91 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 */) 92 { 93 ocsd_err_t err = OCSD_OK; 94 if(findAccessor(st_address,mem_space,cs_trace_id)) 95 { 96 err = RemoveAccessor(m_acc_curr); 97 m_acc_curr = 0; 98 } 99 else 100 err = OCSD_ERR_INVALID_PARAM_VAL; 101 return err; 102 } 103 104 void TrcMemAccMapper::LogMessage(const std::string &msg) 105 { 106 if(m_err_log) 107 m_err_log->LogMessage(ITraceErrorLog::HANDLE_GEN_INFO,OCSD_ERR_SEV_INFO,msg); 108 } 109 110 /************************************************************************************/ 111 /* mappers global address space class - no differentiation in core trace IDs */ 112 /************************************************************************************/ 113 TrcMemAccMapGlobalSpace::TrcMemAccMapGlobalSpace() : TrcMemAccMapper() 114 { 115 } 116 117 TrcMemAccMapGlobalSpace::~TrcMemAccMapGlobalSpace() 118 { 119 } 120 121 ocsd_err_t TrcMemAccMapGlobalSpace::AddAccessor(TrcMemAccessorBase *p_accessor, const uint8_t /*cs_trace_id*/) 122 { 123 ocsd_err_t err = OCSD_OK; 124 bool bOverLap = false; 125 126 if(!p_accessor->validateRange()) 127 return OCSD_ERR_MEM_ACC_RANGE_INVALID; 128 129 std::vector<TrcMemAccessorBase *>::const_iterator it = m_acc_global.begin(); 130 while((it != m_acc_global.end()) && !bOverLap) 131 { 132 // if overlap and memory space match 133 if( ((*it)->overLapRange(p_accessor)) && 134 ((*it)->inMemSpace(p_accessor->getMemSpace())) 135 ) 136 { 137 bOverLap = true; 138 err = OCSD_ERR_MEM_ACC_OVERLAP; 139 } 140 it++; 141 } 142 143 // no overlap - add to the list of ranges. 144 if(!bOverLap) 145 m_acc_global.push_back(p_accessor); 146 147 return err; 148 } 149 150 bool TrcMemAccMapGlobalSpace::findAccessor(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t /*cs_trace_id*/) 151 { 152 bool bFound = false; 153 std::vector<TrcMemAccessorBase *>::const_iterator it = m_acc_global.begin(); 154 while((it != m_acc_global.end()) && !bFound) 155 { 156 if( (*it)->addrInRange(address) && 157 (*it)->inMemSpace(mem_space)) 158 { 159 bFound = true; 160 m_acc_curr = *it; 161 } 162 it++; 163 } 164 return bFound; 165 } 166 167 bool TrcMemAccMapGlobalSpace::readFromCurrent(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t /*cs_trace_id*/) 168 { 169 bool readFromCurr = false; 170 if(m_acc_curr) 171 readFromCurr = (m_acc_curr->addrInRange(address) && m_acc_curr->inMemSpace(mem_space)); 172 return readFromCurr; 173 } 174 175 176 TrcMemAccessorBase * TrcMemAccMapGlobalSpace::getFirstAccessor() 177 { 178 TrcMemAccessorBase *p_acc = 0; 179 m_acc_it = m_acc_global.begin(); 180 if(m_acc_it != m_acc_global.end()) 181 { 182 p_acc = *m_acc_it; 183 } 184 return p_acc; 185 } 186 187 TrcMemAccessorBase *TrcMemAccMapGlobalSpace::getNextAccessor() 188 { 189 TrcMemAccessorBase *p_acc = 0; 190 m_acc_it++; 191 if(m_acc_it != m_acc_global.end()) 192 { 193 p_acc = *m_acc_it; 194 } 195 return p_acc; 196 } 197 198 void TrcMemAccMapGlobalSpace::clearAccessorList() 199 { 200 m_acc_global.clear(); 201 } 202 203 ocsd_err_t TrcMemAccMapGlobalSpace::RemoveAccessor(const TrcMemAccessorBase *p_accessor) 204 { 205 bool bFound = false; 206 TrcMemAccessorBase *p_acc = getFirstAccessor(); 207 while(p_acc != 0) 208 { 209 if(p_acc == p_accessor) 210 { 211 m_acc_global.erase(m_acc_it); 212 TrcMemAccFactory::DestroyAccessor(p_acc); 213 p_acc = 0; 214 bFound = true; 215 } 216 else 217 p_acc = getNextAccessor(); 218 } 219 return bFound ? OCSD_OK : OCSD_ERR_INVALID_PARAM_VAL; 220 } 221 222 223 void TrcMemAccMapGlobalSpace::logMappedRanges() 224 { 225 std::string accStr; 226 TrcMemAccessorBase *pAccessor = getFirstAccessor(); 227 LogMessage("Mapped Memory Accessors\n"); 228 while(pAccessor != 0) 229 { 230 pAccessor->getMemAccString(accStr); 231 accStr += "\n"; 232 LogMessage(accStr); 233 pAccessor = getNextAccessor(); 234 } 235 LogMessage("========================\n"); 236 } 237 238 /* End of File trc_mem_acc_mapper.cpp */ 239