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
TrcMemAccMapper()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
TrcMemAccMapper(bool using_trace_id)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
~TrcMemAccMapper()58 TrcMemAccMapper::~TrcMemAccMapper()
59 {
60 }
61
62 // memory access interface
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)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
RemoveAllAccessors()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
RemoveAccessorByAddress(const ocsd_vaddr_t st_address,const ocsd_mem_space_acc_t mem_space,const uint8_t cs_trace_id)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
LogMessage(const std::string & msg)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 /************************************************************************************/
TrcMemAccMapGlobalSpace()113 TrcMemAccMapGlobalSpace::TrcMemAccMapGlobalSpace() : TrcMemAccMapper()
114 {
115 }
116
~TrcMemAccMapGlobalSpace()117 TrcMemAccMapGlobalSpace::~TrcMemAccMapGlobalSpace()
118 {
119 }
120
AddAccessor(TrcMemAccessorBase * p_accessor,const uint8_t)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
findAccessor(const ocsd_vaddr_t address,const ocsd_mem_space_acc_t mem_space,const uint8_t)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
readFromCurrent(const ocsd_vaddr_t address,const ocsd_mem_space_acc_t mem_space,const uint8_t)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
getFirstAccessor()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
getNextAccessor()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
clearAccessorList()198 void TrcMemAccMapGlobalSpace::clearAccessorList()
199 {
200 m_acc_global.clear();
201 }
202
RemoveAccessor(const TrcMemAccessorBase * p_accessor)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
logMappedRanges()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