1 /*
2 * \file ss_to_dcdtree.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 "ss_to_dcdtree.h"
36 #include "ss_key_value_names.h"
37
38
CreateDcdTreeFromSnapShot()39 CreateDcdTreeFromSnapShot::CreateDcdTreeFromSnapShot() :
40 m_bInit(false),
41 m_pDecodeTree(0),
42 m_pReader(0),
43 m_pErrLogInterface(0),
44 m_bPacketProcOnly(false),
45 m_BufferFileName("")
46 {
47 m_errlog_handle = 0;
48 m_add_create_flags = 0;
49 }
50
~CreateDcdTreeFromSnapShot()51 CreateDcdTreeFromSnapShot::~CreateDcdTreeFromSnapShot()
52 {
53 destroyDecodeTree();
54 }
55
initialise(SnapShotReader * pReader,ITraceErrorLog * pErrLogInterface)56 void CreateDcdTreeFromSnapShot::initialise(SnapShotReader *pReader, ITraceErrorLog *pErrLogInterface)
57 {
58 if((pErrLogInterface != 0) && (pReader != 0))
59 {
60 m_pReader = pReader;
61 m_pErrLogInterface = pErrLogInterface;
62 m_errlog_handle = m_pErrLogInterface->RegisterErrorSource("ss2_dcdtree");
63 m_bInit = true;
64 }
65 }
66
getBufferFileNameFromBuffName(const std::string & buff_name)67 std::string CreateDcdTreeFromSnapShot::getBufferFileNameFromBuffName(const std::string& buff_name)
68 {
69 Parser::TraceBufferSourceTree tree;
70 std::string buffFileName = "";
71
72 if (m_pReader->getTraceBufferSourceTree(buff_name, tree))
73 {
74 buffFileName = m_pReader->getSnapShotDir() + tree.buffer_info.dataFileName;
75 }
76 return buffFileName;
77 }
78
79
createDecodeTree(const std::string & SourceName,bool bPacketProcOnly,uint32_t add_create_flags)80 bool CreateDcdTreeFromSnapShot::createDecodeTree(const std::string &SourceName, bool bPacketProcOnly, uint32_t add_create_flags)
81 {
82 ocsd_err_t err = OCSD_OK;
83
84 m_add_create_flags = add_create_flags;
85 if(m_bInit)
86 {
87 if(!m_pReader->snapshotReadOK())
88 {
89 LogError("Supplied snapshot reader has not correctly read the snapshot.\n");
90 return false;
91 }
92
93 m_bPacketProcOnly = bPacketProcOnly;
94 Parser::TraceBufferSourceTree tree;
95
96 if(m_pReader->getTraceBufferSourceTree(SourceName, tree))
97 {
98 int numDecodersCreated = 0; // count how many we create - if none then give up.
99 uint32_t formatter_flags = OCSD_DFRMTR_FRAME_MEM_ALIGN;
100
101 /* make a note of the trace binary file name + path to ss directory */
102 m_BufferFileName = m_pReader->getSnapShotDir() + tree.buffer_info.dataFileName;
103
104 ocsd_dcd_tree_src_t src_format = tree.buffer_info.dataFormat == "source_data" ? OCSD_TRC_SRC_SINGLE : OCSD_TRC_SRC_FRAME_FORMATTED;
105
106 if (tree.buffer_info.dataFormat == "dstream_coresight")
107 formatter_flags = OCSD_DFRMTR_HAS_FSYNCS;
108
109 /* create the initial device tree */
110 // TBD: handle syncs / hsyncs data from TPIU
111 m_pDecodeTree = DecodeTree::CreateDecodeTree(src_format, formatter_flags);
112 if(m_pDecodeTree == 0)
113 {
114 LogError("Failed to create decode tree object\n");
115 return false;
116 }
117
118 // use our error logger - don't use the tree default.
119 m_pDecodeTree->setAlternateErrorLogger(m_pErrLogInterface);
120
121 if(!bPacketProcOnly)
122 {
123 m_pDecodeTree->createMemAccMapper();
124 }
125
126 /* run through each protocol source to this buffer... */
127 std::map<std::string, std::string>::iterator it = tree.source_core_assoc.begin();
128
129 while(it != tree.source_core_assoc.end())
130 {
131 Parser::Parsed *etm_dev, *core_dev;
132 if(m_pReader->getDeviceData(it->first,&etm_dev))
133 {
134 // found the device data for this device.
135
136 // see if we have a core name (STM / ITM not associated with a core);
137 std::string coreDevName = it->second;
138 if(coreDevName.size() > 0)
139 {
140 if(m_pReader->getDeviceData(coreDevName,&core_dev))
141 {
142 if(createPEDecoder(core_dev->deviceTypeName,etm_dev))
143 {
144 numDecodersCreated++;
145 if(!bPacketProcOnly &&(core_dev->dumpDefs.size() > 0))
146 {
147 err = processDumpfiles(core_dev->dumpDefs);
148 }
149 }
150 else
151 {
152 std::ostringstream oss;
153 oss << "Failed to create decoder for source " << it->first << ".\n";
154 LogError(oss.str());
155 }
156 }
157 else
158 {
159 // Could not find the device data for the core.
160 // unexpected - since we created the associations.
161 std::ostringstream oss;
162 oss << "Failed to get device data for source " << it->first << ".\n";
163 LogError(oss.str());
164 }
165 }
166 else
167 {
168 // none-core source
169 if(createSTDecoder(etm_dev))
170 {
171 numDecodersCreated++;
172 }
173 else
174 {
175 std::ostringstream oss;
176 oss << "Failed to create decoder for none core source " << it->first << ".\n";
177 LogError(oss.str());
178 }
179 }
180 }
181 else
182 {
183 // TBD: could not find the device data for the source.
184 // again unexpected - suggests ss format error.
185 std::ostringstream oss;
186 oss << "Failed to find device data for source " << it->first << ".\n";
187 LogError(oss.str());
188 }
189 if(src_format == OCSD_TRC_SRC_SINGLE)
190 it = tree.source_core_assoc.end();
191 else
192 it++;
193 }
194
195 if((numDecodersCreated == 0) || (err != OCSD_OK))
196 {
197 // nothing useful found
198 destroyDecodeTree();
199 }
200 }
201 else
202 {
203 std::ostringstream oss;
204 oss << "Failed to get parsed source tree for buffer " << SourceName << ".\n";
205 LogError(oss.str());
206 }
207 }
208 return (bool)(m_pDecodeTree != 0);
209 }
210
destroyDecodeTree()211 void CreateDcdTreeFromSnapShot::destroyDecodeTree()
212 {
213 if(m_pDecodeTree)
214 DecodeTree::DestroyDecodeTree(m_pDecodeTree);
215 m_pDecodeTree = 0;
216 m_pReader = 0;
217 m_pErrLogInterface = 0;
218 m_errlog_handle = 0;
219 m_BufferFileName = "";
220 }
221
LogError(const std::string & msg)222 void CreateDcdTreeFromSnapShot::LogError(const std::string &msg)
223 {
224 ocsdError err(OCSD_ERR_SEV_ERROR,OCSD_ERR_TEST_SS_TO_DECODER,msg);
225 m_pErrLogInterface->LogError(m_errlog_handle,&err);
226 }
227
LogError(const ocsdError & err)228 void CreateDcdTreeFromSnapShot::LogError(const ocsdError &err)
229 {
230 m_pErrLogInterface->LogError(m_errlog_handle,&err);
231 }
232
createPEDecoder(const std::string & coreName,Parser::Parsed * devSrc)233 bool CreateDcdTreeFromSnapShot::createPEDecoder(const std::string &coreName, Parser::Parsed *devSrc)
234 {
235 bool bCreatedDecoder = false;
236 std::string devTypeName = devSrc->deviceTypeName;
237
238 // split off .x from type name.
239 std::string::size_type pos = devTypeName.find_first_of('.');
240 if(pos != std::string::npos)
241 devTypeName = devTypeName.substr(0,pos);
242
243 // split according to protocol
244 if(devTypeName == ETMv4Protocol)
245 {
246 bCreatedDecoder = createETMv4Decoder(coreName,devSrc);
247 }
248 else if(devTypeName == ETMv3Protocol)
249 {
250 bCreatedDecoder = createETMv3Decoder(coreName,devSrc);
251 }
252 else if(devTypeName == PTMProtocol || devTypeName == PFTProtocol)
253 {
254 bCreatedDecoder = createPTMDecoder(coreName,devSrc);
255 }
256 else if (devTypeName == ETEProtocol)
257 {
258 bCreatedDecoder = createETEDecoder(coreName, devSrc);
259 }
260
261 return bCreatedDecoder;
262 }
263
264 // create an ETMv4 decoder based on the deviceN.ini file.
createETMv4Decoder(const std::string & coreName,Parser::Parsed * devSrc,const bool bDataChannel)265 bool CreateDcdTreeFromSnapShot::createETMv4Decoder(const std::string &coreName, Parser::Parsed *devSrc, const bool bDataChannel /* = false*/)
266 {
267 bool createdDecoder = false;
268 bool configOK = true;
269
270 // generate the config data from the device data.
271 ocsd_etmv4_cfg config;
272
273 regs_to_access_t regs_to_access[] = {
274 { ETMv4RegCfg, true, &config.reg_configr, 0 },
275 { ETMv4RegIDR, true, &config.reg_traceidr, 0 },
276 { ETMv4RegIDR0, true, &config.reg_idr0, 0 },
277 { ETMv4RegIDR1, false, &config.reg_idr1, 0x4100F403 },
278 { ETMv4RegIDR2, true, &config.reg_idr2, 0 },
279 { ETMv4RegIDR8, false, &config.reg_idr8, 0 },
280 { ETMv4RegIDR9, false, &config.reg_idr9, 0 },
281 { ETMv4RegIDR10, false, &config.reg_idr10, 0 },
282 { ETMv4RegIDR11, false, &config.reg_idr11, 0 },
283 { ETMv4RegIDR12, false, &config.reg_idr12, 0 },
284 { ETMv4RegIDR13,false, &config.reg_idr13, 0 },
285 };
286
287 // extract registers
288 configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
289
290 // extract core profile
291 if(configOK)
292 configOK = getCoreProfile(coreName,config.arch_ver,config.core_prof);
293
294 // good config - generate the decoder on the tree.
295 if(configOK)
296 {
297 ocsd_err_t err = OCSD_OK;
298 EtmV4Config configObj(&config);
299 const char *decoderName = bDataChannel ? OCSD_BUILTIN_DCD_ETMV4D : OCSD_BUILTIN_DCD_ETMV4I;
300
301 err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER),&configObj);
302
303 if(err == OCSD_OK)
304 createdDecoder = true;
305 else
306 {
307 std::string msg = "Snapshot processor : failed to create " + (std::string)decoderName + " decoder on decode tree.";
308 LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,msg));
309 }
310 }
311
312 return createdDecoder;
313 }
314
createETEDecoder(const std::string & coreName,Parser::Parsed * devSrc)315 bool CreateDcdTreeFromSnapShot::createETEDecoder(const std::string &coreName, Parser::Parsed *devSrc)
316 {
317 bool createdDecoder = false;
318 bool configOK = true;
319
320 // generate the config data from the device data.
321 ocsd_ete_cfg config;
322
323 // ete regs are same names Etmv4 in places...
324 regs_to_access_t regs_to_access[] = {
325 { ETMv4RegCfg, true, &config.reg_configr, 0 },
326 { ETMv4RegIDR, true, &config.reg_traceidr, 0 },
327 { ETMv4RegIDR0, true, &config.reg_idr0, 0 },
328 { ETMv4RegIDR1, false, &config.reg_idr1, 0x4100F403 },
329 { ETMv4RegIDR2, true, &config.reg_idr2, 0 },
330 { ETMv4RegIDR8, false, &config.reg_idr8, 0 },
331 { ETERegDevArch, false, &config.reg_devarch, 0x47705A13 },
332 };
333
334 // extract registers
335 configOK = getRegisters(devSrc->regDefs, sizeof(regs_to_access) / sizeof(regs_to_access_t), regs_to_access);
336
337 // extract core profile
338 if (configOK)
339 configOK = getCoreProfile(coreName, config.arch_ver, config.core_prof);
340
341 // good config - generate the decoder on the tree.
342 if (configOK)
343 {
344 ocsd_err_t err = OCSD_OK;
345 ETEConfig configObj(&config);
346 const char *decoderName = OCSD_BUILTIN_DCD_ETE;
347
348 err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER), &configObj);
349
350 if (err == OCSD_OK)
351 createdDecoder = true;
352 else
353 {
354 std::string msg = "Snapshot processor : failed to create " + (std::string)decoderName + " decoder on decode tree.";
355 LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, msg));
356 }
357 }
358
359 return createdDecoder;
360 }
361
362 // create an ETMv3 decoder based on the register values in the deviceN.ini file.
createETMv3Decoder(const std::string & coreName,Parser::Parsed * devSrc)363 bool CreateDcdTreeFromSnapShot::createETMv3Decoder(const std::string &coreName, Parser::Parsed *devSrc)
364 {
365 bool createdDecoder = false;
366 bool configOK = true;
367
368 // generate the config data from the device data.
369 ocsd_etmv3_cfg cfg_regs;
370
371 regs_to_access_t regs_to_access[] = {
372 { ETMv3PTMRegIDR, true, &cfg_regs.reg_idr, 0 },
373 { ETMv3PTMRegCR, true, &cfg_regs.reg_ctrl, 0 },
374 { ETMv3PTMRegCCER, true, &cfg_regs.reg_ccer, 0 },
375 { ETMv3PTMRegTraceIDR, true, &cfg_regs.reg_trc_id, 0}
376 };
377
378 // extract registers
379 configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
380
381 // extract core profile
382 if(configOK)
383 configOK = getCoreProfile(coreName,cfg_regs.arch_ver,cfg_regs.core_prof);
384
385 // good config - generate the decoder on the tree.
386 if(configOK)
387 {
388 EtmV3Config config(&cfg_regs);
389 ocsd_err_t err = OCSD_OK;
390 err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_ETMV3, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&config);
391
392 if(err == OCSD_OK)
393 createdDecoder = true;
394 else
395 LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create ETMV3 decoder on decode tree."));
396 }
397 return createdDecoder;
398 }
399
createPTMDecoder(const std::string & coreName,Parser::Parsed * devSrc)400 bool CreateDcdTreeFromSnapShot::createPTMDecoder(const std::string &coreName, Parser::Parsed *devSrc)
401 {
402 bool createdDecoder = false;
403 bool configOK = true;
404
405 // generate the config data from the device data.
406
407 ocsd_ptm_cfg config;
408
409 regs_to_access_t regs_to_access[] = {
410 { ETMv3PTMRegIDR, true, &config.reg_idr, 0 },
411 { ETMv3PTMRegCR, true, &config.reg_ctrl, 0 },
412 { ETMv3PTMRegCCER, true, &config.reg_ccer, 0 },
413 { ETMv3PTMRegTraceIDR, true, &config.reg_trc_id, 0}
414 };
415
416 // extract registers
417 configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
418
419 // extract core profile
420 if(configOK)
421 configOK = getCoreProfile(coreName,config.arch_ver,config.core_prof);
422
423 // good config - generate the decoder on the tree.
424 if(configOK)
425 {
426 PtmConfig configObj(&config);
427 ocsd_err_t err = OCSD_OK;
428 err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_PTM, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&configObj);
429
430 if(err == OCSD_OK)
431 createdDecoder = true;
432 else
433 LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create PTM decoder on decode tree."));
434 }
435 return createdDecoder;
436 }
437
createSTDecoder(Parser::Parsed * devSrc)438 bool CreateDcdTreeFromSnapShot::createSTDecoder(Parser::Parsed *devSrc)
439 {
440 bool bCreatedDecoder = false;
441 std::string devTypeName = devSrc->deviceTypeName;
442
443 // split off .x from type name.
444 std::string::size_type pos = devTypeName.find_first_of('.');
445 if(pos != std::string::npos)
446 devTypeName = devTypeName.substr(0,pos);
447
448 if(devTypeName == STMProtocol)
449 {
450 bCreatedDecoder = createSTMDecoder(devSrc);
451 }
452
453 return bCreatedDecoder;
454 }
455
createSTMDecoder(Parser::Parsed * devSrc)456 bool CreateDcdTreeFromSnapShot::createSTMDecoder(Parser::Parsed *devSrc)
457 {
458 bool createdDecoder = false;
459 bool configOK = true;
460
461 // generate the config data from the device data.
462
463 ocsd_stm_cfg config;
464
465 regs_to_access_t regs_to_access[] = {
466 { STMRegTCSR, true, &config.reg_tcsr, 0 }
467 };
468
469 configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
470 if(configOK)
471 {
472 ocsd_err_t err = OCSD_OK;
473 STMConfig configObj(&config);
474
475 err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_STM, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&configObj);
476
477 if(err == OCSD_OK)
478 createdDecoder = true;
479 else
480 LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create STM decoder on decode tree."));
481 }
482
483 return createdDecoder;
484 }
485
486
487
488 // get a set of register values.
getRegisters(std::map<std::string,std::string,Util::CaseInsensitiveLess> & regDefs,int numRegs,regs_to_access_t * reg_access_array)489 bool CreateDcdTreeFromSnapShot::getRegisters(std::map<std::string, std::string, Util::CaseInsensitiveLess> ®Defs, int numRegs, regs_to_access_t *reg_access_array)
490 {
491 bool regsOK = true;
492
493 for(int rv = 0; rv < numRegs; rv++)
494 {
495 if(!getRegByPrefix( regDefs,reg_access_array[rv]))
496 regsOK = false;
497 }
498 return regsOK;
499 }
500
501 // strip out any parts with brackets
getRegByPrefix(std::map<std::string,std::string,Util::CaseInsensitiveLess> & regDefs,regs_to_access_t & reg_accessor)502 bool CreateDcdTreeFromSnapShot::getRegByPrefix(std::map<std::string, std::string, Util::CaseInsensitiveLess> ®Defs,
503 regs_to_access_t ®_accessor)
504 {
505 std::ostringstream oss;
506 bool bFound = false;
507 std::map<std::string, std::string, Util::CaseInsensitiveLess>::iterator it;
508 std::string prefix_cmp;
509 std::string::size_type pos;
510 std::string strval;
511
512 *reg_accessor.value = 0;
513
514 it = regDefs.begin();
515 while((it != regDefs.end()) && !bFound)
516 {
517 prefix_cmp = it->first;
518 pos = prefix_cmp.find_first_of('(');
519 if(pos != std::string::npos)
520 {
521 prefix_cmp = prefix_cmp.substr(0, pos);
522 }
523 if(prefix_cmp == reg_accessor.pszName)
524 {
525 strval = it->second;
526 bFound = true;
527 }
528 it++;
529 }
530
531 if(bFound)
532 *reg_accessor.value = strtoul(strval.c_str(),0,0);
533 else
534 {
535 ocsd_err_severity_t sev = OCSD_ERR_SEV_ERROR;
536 if(reg_accessor.failIfMissing)
537 {
538 oss << "Error:";
539 }
540 else
541 {
542 // no fail if missing - set any default and just warn.
543 bFound = true;
544 oss << "Warning: Default set for register. ";
545 sev = OCSD_ERR_SEV_WARN;
546 *reg_accessor.value = reg_accessor.val_default;
547 }
548 oss << "Missing " << reg_accessor.pszName << "\n";
549 m_pErrLogInterface->LogMessage(m_errlog_handle, sev, oss.str());
550 }
551 return bFound;
552 }
553
getCoreProfile(const std::string & coreName,ocsd_arch_version_t & arch_ver,ocsd_core_profile_t & core_prof)554 bool CreateDcdTreeFromSnapShot::getCoreProfile(const std::string &coreName, ocsd_arch_version_t &arch_ver, ocsd_core_profile_t &core_prof)
555 {
556 bool profileOK = true;
557 ocsd_arch_profile_t ap = m_arch_profiles.getArchProfile(coreName);
558 if(ap.arch != ARCH_UNKNOWN)
559 {
560 arch_ver = ap.arch;
561 core_prof = ap.profile;
562 }
563 else
564 {
565 std::ostringstream oss;
566 oss << "Unrecognized Core name " << coreName << ". Cannot evaluate profile or architecture.";
567 LogError(oss.str());
568 profileOK = false;
569 }
570 return profileOK;
571 }
572
573 typedef struct mem_space_keys {
574 const char* key_name;
575 ocsd_mem_space_acc_t memspace;
576 } mem_space_keys_t;
577
578 static mem_space_keys_t space_map[] = {
579 /* single spaces */
580 { "EL1S", OCSD_MEM_SPACE_EL1S },
581 { "EL1N", OCSD_MEM_SPACE_EL1N },
582 { "EL1R", OCSD_MEM_SPACE_EL1R },
583 { "EL2S", OCSD_MEM_SPACE_EL2S },
584 { "EL2" , OCSD_MEM_SPACE_EL2 }, /* old EL2 NS name - prior to EL2S existing */
585 { "EL2N", OCSD_MEM_SPACE_EL2 },
586 { "EL2R", OCSD_MEM_SPACE_EL2R },
587 { "EL3" , OCSD_MEM_SPACE_EL3 },
588 { "ROOT", OCSD_MEM_SPACE_ROOT },
589 /* multiple memory spaces */
590 { "S" , OCSD_MEM_SPACE_S},
591 { "N" , OCSD_MEM_SPACE_N},
592 { "R" , OCSD_MEM_SPACE_R},
593 { "ANY" , OCSD_MEM_SPACE_ANY},
594 /* older names - from spec but not expected to be used in future. */
595 { "H" , OCSD_MEM_SPACE_EL2 }, /* hypervisor - EL2 NS */
596 { "P" , OCSD_MEM_SPACE_EL1N }, /* privileged - EL1 NS */
597 { "NP" , OCSD_MEM_SPACE_EL1N }, /* non secure privileged - EL1 NS */
598 { "SP" , OCSD_MEM_SPACE_EL1S }, /* secure privileged - EL1 S */
599 /* table terminator */
600 { "", OCSD_MEM_SPACE_NONE},
601 };
602
603 /* get mem space from input string */
getMemSpaceFromString(const std::string & memspace)604 ocsd_mem_space_acc_t CreateDcdTreeFromSnapShot::getMemSpaceFromString(const std::string& memspace)
605 {
606
607
608 ocsd_mem_space_acc_t mem_space = OCSD_MEM_SPACE_ANY;
609 if (memspace.length() > 0) {
610 int i = 0;
611
612 while (space_map[i].memspace != OCSD_MEM_SPACE_NONE) {
613 if (space_map[i].key_name == memspace) {
614 mem_space = space_map[i].memspace;
615 break;
616 }
617 i++;
618 }
619 }
620 return mem_space;
621 }
622
processDumpfiles(std::vector<Parser::DumpDef> & dumps)623 ocsd_err_t CreateDcdTreeFromSnapShot::processDumpfiles(std::vector<Parser::DumpDef> &dumps)
624 {
625 std::string dumpFilePathName;
626 std::vector<Parser::DumpDef>::const_iterator it;
627 ocsd_mem_space_acc_t mem_space;
628 ocsd_err_t err = OCSD_OK;
629
630 it = dumps.begin();
631 while(it != dumps.end())
632 {
633 dumpFilePathName = m_pReader->getSnapShotDir() + it->path;
634 ocsd_file_mem_region_t region;
635 ocsd_err_t err = OCSD_OK;
636
637 region.start_address = it->address;
638 region.file_offset = it->offset;
639 region.region_size = it->length;
640 mem_space = getMemSpaceFromString(it->space);
641
642 // ensure we respect optional length and offset parameter and
643 // allow multiple dump entries with same file name to define regions
644 if (!TrcMemAccessorFile::isExistingFileAccessor(dumpFilePathName))
645 err = m_pDecodeTree->addBinFileRegionMemAcc(®ion, 1, mem_space, dumpFilePathName);
646 else
647 err = m_pDecodeTree->updateBinFileRegionMemAcc(®ion, 1, mem_space, dumpFilePathName);
648 if(err != OCSD_OK)
649 {
650 std::ostringstream oss;
651 oss << "Failed to create memory accessor for file " << dumpFilePathName << ".";
652 LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,oss.str()));
653 }
654 it++;
655 }
656 return err;
657 }
658
659 /* End of File ss_to_dcdtree.cpp */
660