1c120c564SAndrew Turner /* 2c120c564SAndrew Turner * \file ocsd_dcd_tree.cpp 3c120c564SAndrew Turner * \brief OpenCSD : 4c120c564SAndrew Turner * 5c120c564SAndrew Turner * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6c120c564SAndrew Turner */ 7c120c564SAndrew Turner 8c120c564SAndrew Turner 9c120c564SAndrew Turner /* 10c120c564SAndrew Turner * Redistribution and use in source and binary forms, with or without modification, 11c120c564SAndrew Turner * are permitted provided that the following conditions are met: 12c120c564SAndrew Turner * 13c120c564SAndrew Turner * 1. Redistributions of source code must retain the above copyright notice, 14c120c564SAndrew Turner * this list of conditions and the following disclaimer. 15c120c564SAndrew Turner * 16c120c564SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright notice, 17c120c564SAndrew Turner * this list of conditions and the following disclaimer in the documentation 18c120c564SAndrew Turner * and/or other materials provided with the distribution. 19c120c564SAndrew Turner * 20c120c564SAndrew Turner * 3. Neither the name of the copyright holder nor the names of its contributors 21c120c564SAndrew Turner * may be used to endorse or promote products derived from this software without 22c120c564SAndrew Turner * specific prior written permission. 23c120c564SAndrew Turner * 24c120c564SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 25c120c564SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26c120c564SAndrew Turner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27c120c564SAndrew Turner * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28c120c564SAndrew Turner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29c120c564SAndrew Turner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30c120c564SAndrew Turner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31c120c564SAndrew Turner * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32c120c564SAndrew Turner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33c120c564SAndrew Turner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34c120c564SAndrew Turner */ 35c120c564SAndrew Turner 36c120c564SAndrew Turner #include "common/ocsd_dcd_tree.h" 37c120c564SAndrew Turner #include "common/ocsd_lib_dcd_register.h" 38c120c564SAndrew Turner #include "mem_acc/trc_mem_acc_mapper.h" 39c120c564SAndrew Turner 40c120c564SAndrew Turner /***************************************************************/ 41c120c564SAndrew Turner ITraceErrorLog *DecodeTree::s_i_error_logger = &DecodeTree::s_error_logger; 42c120c564SAndrew Turner std::list<DecodeTree *> DecodeTree::s_trace_dcd_trees; /**< list of pointers to decode tree objects */ 43c120c564SAndrew Turner ocsdDefaultErrorLogger DecodeTree::s_error_logger; /**< The library default error logger */ 44c120c564SAndrew Turner TrcIDecode DecodeTree::s_instruction_decoder; /**< default instruction decode library */ 45c120c564SAndrew Turner 46c120c564SAndrew Turner DecodeTree *DecodeTree::CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, uint32_t formatterCfgFlags) 47c120c564SAndrew Turner { 48c120c564SAndrew Turner DecodeTree *dcd_tree = new (std::nothrow) DecodeTree(); 49c120c564SAndrew Turner if(dcd_tree != 0) 50c120c564SAndrew Turner { 51c120c564SAndrew Turner if(dcd_tree->initialise(src_type, formatterCfgFlags)) 52c120c564SAndrew Turner { 53c120c564SAndrew Turner s_trace_dcd_trees.push_back(dcd_tree); 54c120c564SAndrew Turner } 55c120c564SAndrew Turner else 56c120c564SAndrew Turner { 57c120c564SAndrew Turner delete dcd_tree; 58c120c564SAndrew Turner dcd_tree = 0; 59c120c564SAndrew Turner } 60c120c564SAndrew Turner } 61c120c564SAndrew Turner return dcd_tree; 62c120c564SAndrew Turner } 63c120c564SAndrew Turner 64c120c564SAndrew Turner void DecodeTree::DestroyDecodeTree(DecodeTree *p_dcd_tree) 65c120c564SAndrew Turner { 66c120c564SAndrew Turner std::list<DecodeTree *>::iterator it; 67c120c564SAndrew Turner bool bDestroyed = false; 68c120c564SAndrew Turner it = s_trace_dcd_trees.begin(); 69c120c564SAndrew Turner while(!bDestroyed && (it != s_trace_dcd_trees.end())) 70c120c564SAndrew Turner { 71c120c564SAndrew Turner if(*it == p_dcd_tree) 72c120c564SAndrew Turner { 73c120c564SAndrew Turner s_trace_dcd_trees.erase(it); 74c120c564SAndrew Turner delete p_dcd_tree; 75c120c564SAndrew Turner bDestroyed = true; 76c120c564SAndrew Turner } 77c120c564SAndrew Turner else 78c120c564SAndrew Turner it++; 79c120c564SAndrew Turner } 80c120c564SAndrew Turner } 81c120c564SAndrew Turner 82c120c564SAndrew Turner void DecodeTree::setAlternateErrorLogger(ITraceErrorLog *p_error_logger) 83c120c564SAndrew Turner { 84c120c564SAndrew Turner if(p_error_logger) 85c120c564SAndrew Turner s_i_error_logger = p_error_logger; 86c120c564SAndrew Turner else 87c120c564SAndrew Turner s_i_error_logger = &s_error_logger; 88c120c564SAndrew Turner } 89c120c564SAndrew Turner 90c120c564SAndrew Turner /***************************************************************/ 91c120c564SAndrew Turner 92c120c564SAndrew Turner DecodeTree::DecodeTree() : 93c120c564SAndrew Turner m_i_instr_decode(&s_instruction_decoder), 94c120c564SAndrew Turner m_i_mem_access(0), 95c120c564SAndrew Turner m_i_gen_elem_out(0), 96c120c564SAndrew Turner m_i_decoder_root(0), 97c120c564SAndrew Turner m_frame_deformatter_root(0), 98c120c564SAndrew Turner m_decode_elem_iter(0), 99c120c564SAndrew Turner m_default_mapper(0), 100c120c564SAndrew Turner m_created_mapper(false) 101c120c564SAndrew Turner { 102c120c564SAndrew Turner for(int i = 0; i < 0x80; i++) 103c120c564SAndrew Turner m_decode_elements[i] = 0; 104c120c564SAndrew Turner } 105c120c564SAndrew Turner 106c120c564SAndrew Turner DecodeTree::~DecodeTree() 107c120c564SAndrew Turner { 108c120c564SAndrew Turner destroyMemAccMapper(); 109c120c564SAndrew Turner for(uint8_t i = 0; i < 0x80; i++) 110c120c564SAndrew Turner { 111c120c564SAndrew Turner destroyDecodeElement(i); 112c120c564SAndrew Turner } 113c120c564SAndrew Turner PktPrinterFact::destroyAllPrinters(m_printer_list); 114*b6aadd18SAndrew Turner delete m_frame_deformatter_root; 115c120c564SAndrew Turner } 116c120c564SAndrew Turner 117c120c564SAndrew Turner 118c120c564SAndrew Turner 119c120c564SAndrew Turner ocsd_datapath_resp_t DecodeTree::TraceDataIn( const ocsd_datapath_op_t op, 120c120c564SAndrew Turner const ocsd_trc_index_t index, 121c120c564SAndrew Turner const uint32_t dataBlockSize, 122c120c564SAndrew Turner const uint8_t *pDataBlock, 123c120c564SAndrew Turner uint32_t *numBytesProcessed) 124c120c564SAndrew Turner { 125c120c564SAndrew Turner if(m_i_decoder_root) 126c120c564SAndrew Turner return m_i_decoder_root->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed); 127c120c564SAndrew Turner *numBytesProcessed = 0; 128c120c564SAndrew Turner return OCSD_RESP_FATAL_NOT_INIT; 129c120c564SAndrew Turner } 130c120c564SAndrew Turner 131c120c564SAndrew Turner /* set key interfaces - attach / replace on any existing tree components */ 132c120c564SAndrew Turner void DecodeTree::setInstrDecoder(IInstrDecode *i_instr_decode) 133c120c564SAndrew Turner { 134c120c564SAndrew Turner uint8_t elemID; 135c120c564SAndrew Turner DecodeTreeElement *pElem = 0; 136c120c564SAndrew Turner 137c120c564SAndrew Turner pElem = getFirstElement(elemID); 138c120c564SAndrew Turner while(pElem != 0) 139c120c564SAndrew Turner { 140c120c564SAndrew Turner pElem->getDecoderMngr()->attachInstrDecoder(pElem->getDecoderHandle(),i_instr_decode); 141c120c564SAndrew Turner pElem = getNextElement(elemID); 142c120c564SAndrew Turner } 143c120c564SAndrew Turner } 144c120c564SAndrew Turner 145c120c564SAndrew Turner void DecodeTree::setMemAccessI(ITargetMemAccess *i_mem_access) 146c120c564SAndrew Turner { 147c120c564SAndrew Turner uint8_t elemID; 148c120c564SAndrew Turner DecodeTreeElement *pElem = 0; 149c120c564SAndrew Turner 150c120c564SAndrew Turner pElem = getFirstElement(elemID); 151c120c564SAndrew Turner while(pElem != 0) 152c120c564SAndrew Turner { 153c120c564SAndrew Turner pElem->getDecoderMngr()->attachMemAccessor(pElem->getDecoderHandle(),i_mem_access); 154c120c564SAndrew Turner pElem = getNextElement(elemID); 155c120c564SAndrew Turner } 156c120c564SAndrew Turner m_i_mem_access = i_mem_access; 157c120c564SAndrew Turner } 158c120c564SAndrew Turner 159c120c564SAndrew Turner void DecodeTree::setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem) 160c120c564SAndrew Turner { 161c120c564SAndrew Turner uint8_t elemID; 162c120c564SAndrew Turner DecodeTreeElement *pElem = 0; 163c120c564SAndrew Turner 164c120c564SAndrew Turner pElem = getFirstElement(elemID); 165c120c564SAndrew Turner while(pElem != 0) 166c120c564SAndrew Turner { 167c120c564SAndrew Turner pElem->getDecoderMngr()->attachOutputSink(pElem->getDecoderHandle(),i_gen_trace_elem); 168c120c564SAndrew Turner pElem = getNextElement(elemID); 169c120c564SAndrew Turner } 170c120c564SAndrew Turner } 171c120c564SAndrew Turner 172c120c564SAndrew Turner ocsd_err_t DecodeTree::createMemAccMapper(memacc_mapper_t type /* = MEMACC_MAP_GLOBAL*/ ) 173c120c564SAndrew Turner { 174c120c564SAndrew Turner // clean up any old one 175c120c564SAndrew Turner destroyMemAccMapper(); 176c120c564SAndrew Turner 177c120c564SAndrew Turner // make a new one 178c120c564SAndrew Turner switch(type) 179c120c564SAndrew Turner { 180c120c564SAndrew Turner default: 181c120c564SAndrew Turner case MEMACC_MAP_GLOBAL: 182c120c564SAndrew Turner m_default_mapper = new (std::nothrow) TrcMemAccMapGlobalSpace(); 183c120c564SAndrew Turner break; 184c120c564SAndrew Turner } 185c120c564SAndrew Turner 186c120c564SAndrew Turner // set the access interface 187c120c564SAndrew Turner if(m_default_mapper) 188c120c564SAndrew Turner { 189c120c564SAndrew Turner m_created_mapper = true; 190c120c564SAndrew Turner setMemAccessI(m_default_mapper); 191c120c564SAndrew Turner m_default_mapper->setErrorLog(s_i_error_logger); 192c120c564SAndrew Turner } 193c120c564SAndrew Turner 194c120c564SAndrew Turner return (m_default_mapper != 0) ? OCSD_OK : OCSD_ERR_MEM; 195c120c564SAndrew Turner } 196c120c564SAndrew Turner 197c120c564SAndrew Turner void DecodeTree::setExternMemAccMapper(TrcMemAccMapper* pMapper) 198c120c564SAndrew Turner { 199c120c564SAndrew Turner destroyMemAccMapper(); // destroy any existing mapper - if decode tree created it. 200c120c564SAndrew Turner m_default_mapper = pMapper; 201c120c564SAndrew Turner } 202c120c564SAndrew Turner 203c120c564SAndrew Turner void DecodeTree::destroyMemAccMapper() 204c120c564SAndrew Turner { 205c120c564SAndrew Turner if(m_default_mapper && m_created_mapper) 206c120c564SAndrew Turner { 207c120c564SAndrew Turner m_default_mapper->RemoveAllAccessors(); 208c120c564SAndrew Turner delete m_default_mapper; 209c120c564SAndrew Turner m_default_mapper = 0; 210c120c564SAndrew Turner m_created_mapper = false; 211c120c564SAndrew Turner } 212c120c564SAndrew Turner } 213c120c564SAndrew Turner 214c120c564SAndrew Turner void DecodeTree::logMappedRanges() 215c120c564SAndrew Turner { 216c120c564SAndrew Turner if(m_default_mapper) 217c120c564SAndrew Turner m_default_mapper->logMappedRanges(); 218c120c564SAndrew Turner } 219c120c564SAndrew Turner 220c120c564SAndrew Turner /* Memory accessor creation - all on default mem accessor using the 0 CSID for global core space. */ 221c120c564SAndrew Turner ocsd_err_t DecodeTree::addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length) 222c120c564SAndrew Turner { 223c120c564SAndrew Turner if(!hasMemAccMapper()) 224c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 225c120c564SAndrew Turner 226c120c564SAndrew Turner // need a valid memory buffer, and a least enough bytes for one opcode. 227c120c564SAndrew Turner if((p_mem_buffer == 0) || (mem_length < 4)) 228c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 229c120c564SAndrew Turner 230c120c564SAndrew Turner TrcMemAccessorBase *p_accessor; 231c120c564SAndrew Turner ocsd_err_t err = TrcMemAccFactory::CreateBufferAccessor(&p_accessor, address, p_mem_buffer, mem_length); 232c120c564SAndrew Turner if(err == OCSD_OK) 233c120c564SAndrew Turner { 234c120c564SAndrew Turner TrcMemAccBufPtr *pMBuffAcc = dynamic_cast<TrcMemAccBufPtr *>(p_accessor); 235c120c564SAndrew Turner if(pMBuffAcc) 236c120c564SAndrew Turner { 237c120c564SAndrew Turner pMBuffAcc->setMemSpace(mem_space); 238c120c564SAndrew Turner err = m_default_mapper->AddAccessor(p_accessor,0); 239c120c564SAndrew Turner } 240c120c564SAndrew Turner else 241c120c564SAndrew Turner err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 242c120c564SAndrew Turner 243c120c564SAndrew Turner if(err != OCSD_OK) 244c120c564SAndrew Turner TrcMemAccFactory::DestroyAccessor(p_accessor); 245c120c564SAndrew Turner } 246c120c564SAndrew Turner return err; 247c120c564SAndrew Turner } 248c120c564SAndrew Turner 249c120c564SAndrew Turner ocsd_err_t DecodeTree::addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 250c120c564SAndrew Turner { 251c120c564SAndrew Turner if(!hasMemAccMapper()) 252c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 253c120c564SAndrew Turner 254c120c564SAndrew Turner if(filepath.length() == 0) 255c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 256c120c564SAndrew Turner 257c120c564SAndrew Turner TrcMemAccessorBase *p_accessor; 258c120c564SAndrew Turner ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,address); 259c120c564SAndrew Turner 260c120c564SAndrew Turner if(err == OCSD_OK) 261c120c564SAndrew Turner { 262c120c564SAndrew Turner TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 263c120c564SAndrew Turner if(pAcc) 264c120c564SAndrew Turner { 265c120c564SAndrew Turner pAcc->setMemSpace(mem_space); 266c120c564SAndrew Turner err = m_default_mapper->AddAccessor(pAcc,0); 267c120c564SAndrew Turner } 268c120c564SAndrew Turner else 269c120c564SAndrew Turner err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 270c120c564SAndrew Turner 271c120c564SAndrew Turner if(err != OCSD_OK) 272c120c564SAndrew Turner TrcMemAccFactory::DestroyAccessor(p_accessor); 273c120c564SAndrew Turner } 274c120c564SAndrew Turner return err; 275c120c564SAndrew Turner 276c120c564SAndrew Turner } 277c120c564SAndrew Turner 278c120c564SAndrew Turner ocsd_err_t DecodeTree::addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 279c120c564SAndrew Turner { 280c120c564SAndrew Turner if(!hasMemAccMapper()) 281c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 282c120c564SAndrew Turner 283c120c564SAndrew Turner if((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 284c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 285c120c564SAndrew Turner 286c120c564SAndrew Turner TrcMemAccessorBase *p_accessor; 287c120c564SAndrew Turner int curr_region_idx = 0; 288c120c564SAndrew Turner 289c120c564SAndrew Turner // add first region during the creation of the file accessor. 290c120c564SAndrew Turner ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,region_array[curr_region_idx].start_address,region_array[curr_region_idx].file_offset, region_array[curr_region_idx].region_size); 291c120c564SAndrew Turner if(err == OCSD_OK) 292c120c564SAndrew Turner { 293c120c564SAndrew Turner TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 294c120c564SAndrew Turner if(pAcc) 295c120c564SAndrew Turner { 296c120c564SAndrew Turner // add additional regions to the file accessor. 297c120c564SAndrew Turner curr_region_idx++; 298c120c564SAndrew Turner while(curr_region_idx < num_regions) 299c120c564SAndrew Turner { 300c120c564SAndrew Turner pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 301c120c564SAndrew Turner region_array[curr_region_idx].region_size, 302c120c564SAndrew Turner region_array[curr_region_idx].file_offset); 303c120c564SAndrew Turner curr_region_idx++; 304c120c564SAndrew Turner } 305c120c564SAndrew Turner pAcc->setMemSpace(mem_space); 306c120c564SAndrew Turner 307c120c564SAndrew Turner // add the accessor to the map. 308c120c564SAndrew Turner err = m_default_mapper->AddAccessor(pAcc,0); 309c120c564SAndrew Turner } 310c120c564SAndrew Turner else 311c120c564SAndrew Turner err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 312c120c564SAndrew Turner 313c120c564SAndrew Turner if(err != OCSD_OK) 314c120c564SAndrew Turner TrcMemAccFactory::DestroyAccessor(p_accessor); 315c120c564SAndrew Turner } 316c120c564SAndrew Turner return err; 317c120c564SAndrew Turner } 318c120c564SAndrew Turner 319c120c564SAndrew Turner ocsd_err_t DecodeTree::updateBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 320c120c564SAndrew Turner { 321c120c564SAndrew Turner if (!hasMemAccMapper()) 322c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 323c120c564SAndrew Turner 324c120c564SAndrew Turner if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 325c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 326c120c564SAndrew Turner 327c120c564SAndrew Turner TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath); 328c120c564SAndrew Turner if (!pAcc) 329c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 330c120c564SAndrew Turner 331c120c564SAndrew Turner int curr_region_idx = 0; 332c120c564SAndrew Turner while (curr_region_idx < num_regions) 333c120c564SAndrew Turner { 334c120c564SAndrew Turner // check "new" range 335c120c564SAndrew Turner if (!pAcc->addrStartOfRange(region_array[curr_region_idx].start_address)) 336c120c564SAndrew Turner { 337c120c564SAndrew Turner // ensure adds cleanly 338c120c564SAndrew Turner if (!pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 339c120c564SAndrew Turner region_array[curr_region_idx].region_size, 340c120c564SAndrew Turner region_array[curr_region_idx].file_offset)) 341c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; // otherwise bail out 342c120c564SAndrew Turner } 343c120c564SAndrew Turner curr_region_idx++; 344c120c564SAndrew Turner } 345c120c564SAndrew Turner return OCSD_OK; 346c120c564SAndrew Turner } 347c120c564SAndrew Turner ocsd_err_t DecodeTree::initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, 348c120c564SAndrew Turner const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context) 349c120c564SAndrew Turner { 350c120c564SAndrew Turner if(!hasMemAccMapper()) 351c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 352c120c564SAndrew Turner 353c120c564SAndrew Turner if(p_cb_func == 0) 354c120c564SAndrew Turner return OCSD_ERR_INVALID_PARAM_VAL; 355c120c564SAndrew Turner 356c120c564SAndrew Turner TrcMemAccessorBase *p_accessor; 357c120c564SAndrew Turner ocsd_err_t err = TrcMemAccFactory::CreateCBAccessor(&p_accessor, st_address, en_address, mem_space); 358c120c564SAndrew Turner if(err == OCSD_OK) 359c120c564SAndrew Turner { 360c120c564SAndrew Turner TrcMemAccCB *pCBAcc = dynamic_cast<TrcMemAccCB *>(p_accessor); 361c120c564SAndrew Turner if(pCBAcc) 362c120c564SAndrew Turner { 363c120c564SAndrew Turner if (IDfn) 364c120c564SAndrew Turner pCBAcc->setCBIDIfFn((Fn_MemAccID_CB)p_cb_func, p_context); 365c120c564SAndrew Turner else 366c120c564SAndrew Turner pCBAcc->setCBIfFn((Fn_MemAcc_CB)p_cb_func, p_context); 367c120c564SAndrew Turner 368c120c564SAndrew Turner err = m_default_mapper->AddAccessor(p_accessor,0); 369c120c564SAndrew Turner } 370c120c564SAndrew Turner else 371c120c564SAndrew Turner err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 372c120c564SAndrew Turner 373c120c564SAndrew Turner if(err != OCSD_OK) 374c120c564SAndrew Turner TrcMemAccFactory::DestroyAccessor(p_accessor); 375c120c564SAndrew Turner } 376c120c564SAndrew Turner return err; 377c120c564SAndrew Turner } 378c120c564SAndrew Turner 379c120c564SAndrew Turner ocsd_err_t DecodeTree::addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context) 380c120c564SAndrew Turner { 381c120c564SAndrew Turner return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, false, p_context); 382c120c564SAndrew Turner } 383c120c564SAndrew Turner 384c120c564SAndrew Turner ocsd_err_t DecodeTree::addCallbackIDMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAccID_CB p_cb_func, const void *p_context) 385c120c564SAndrew Turner { 386c120c564SAndrew Turner return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, true, p_context); 387c120c564SAndrew Turner } 388c120c564SAndrew Turner 389c120c564SAndrew Turner ocsd_err_t DecodeTree::removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space) 390c120c564SAndrew Turner { 391c120c564SAndrew Turner if(!hasMemAccMapper()) 392c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 393c120c564SAndrew Turner return m_default_mapper->RemoveAccessorByAddress(address,mem_space,0); 394c120c564SAndrew Turner } 395c120c564SAndrew Turner 396c120c564SAndrew Turner ocsd_err_t DecodeTree::createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig) 397c120c564SAndrew Turner { 398c120c564SAndrew Turner ocsd_err_t err = OCSD_OK; 399c120c564SAndrew Turner IDecoderMngr *pDecoderMngr = 0; 400c120c564SAndrew Turner TraceComponent *pTraceComp = 0; 401c120c564SAndrew Turner int crtFlags = createFlags; 402c120c564SAndrew Turner 403c120c564SAndrew Turner uint8_t CSID = 0; // default for single stream decoder (no deformatter) - we ignore the ID 404c120c564SAndrew Turner if(usingFormatter()) 405c120c564SAndrew Turner { 406c120c564SAndrew Turner CSID = pConfig->getTraceID(); 407c120c564SAndrew Turner crtFlags |= OCSD_CREATE_FLG_INST_ID; 408c120c564SAndrew Turner } 409c120c564SAndrew Turner 410c120c564SAndrew Turner // create the decode element to attach to the channel. 411c120c564SAndrew Turner if((err = createDecodeElement(CSID)) != OCSD_OK) 412c120c564SAndrew Turner return err; 413c120c564SAndrew Turner 414c120c564SAndrew Turner // get the libary decoder register. 415c120c564SAndrew Turner OcsdLibDcdRegister * lib_reg = OcsdLibDcdRegister::getDecoderRegister(); 416c120c564SAndrew Turner if(lib_reg == 0) 417c120c564SAndrew Turner return OCSD_ERR_NOT_INIT; 418c120c564SAndrew Turner 419c120c564SAndrew Turner // find the named decoder 420c120c564SAndrew Turner if((err = lib_reg->getDecoderMngrByName(decoderName,&pDecoderMngr)) != OCSD_OK) 421c120c564SAndrew Turner return err; 422c120c564SAndrew Turner 423c120c564SAndrew Turner // got the decoder... 424c120c564SAndrew Turner if((err = pDecoderMngr->createDecoder(crtFlags,(int)CSID,pConfig,&pTraceComp)) != OCSD_OK) 425c120c564SAndrew Turner return err; 426c120c564SAndrew Turner 427c120c564SAndrew Turner m_decode_elements[CSID]->SetDecoderElement(decoderName, pDecoderMngr, pTraceComp, true); 428c120c564SAndrew Turner 429c120c564SAndrew Turner // always attach an error logger 430c120c564SAndrew Turner if(err == OCSD_OK) 431c120c564SAndrew Turner err = pDecoderMngr->attachErrorLogger(pTraceComp,DecodeTree::s_i_error_logger); 432c120c564SAndrew Turner 433c120c564SAndrew Turner // if we created a packet decoder it may need additional components. 434c120c564SAndrew Turner if(crtFlags & OCSD_CREATE_FLG_FULL_DECODER) 435c120c564SAndrew Turner { 436c120c564SAndrew Turner if(m_i_instr_decode && (err == OCSD_OK)) 437c120c564SAndrew Turner err = pDecoderMngr->attachInstrDecoder(pTraceComp,m_i_instr_decode); 438c120c564SAndrew Turner 439c120c564SAndrew Turner if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if instruction decoder refused 440c120c564SAndrew Turner err = OCSD_OK; 441c120c564SAndrew Turner 442c120c564SAndrew Turner if(m_i_mem_access && (err == OCSD_OK)) 443c120c564SAndrew Turner err = pDecoderMngr->attachMemAccessor(pTraceComp,m_i_mem_access); 444c120c564SAndrew Turner 445c120c564SAndrew Turner if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if mem accessor refused 446c120c564SAndrew Turner err = OCSD_OK; 447c120c564SAndrew Turner 448c120c564SAndrew Turner if( m_i_gen_elem_out && (err == OCSD_OK)) 449c120c564SAndrew Turner err = pDecoderMngr->attachOutputSink(pTraceComp,m_i_gen_elem_out); 450c120c564SAndrew Turner } 451c120c564SAndrew Turner 452c120c564SAndrew Turner // finally attach the packet processor input to the demux output channel 453c120c564SAndrew Turner if(err == OCSD_OK) 454c120c564SAndrew Turner { 455c120c564SAndrew Turner ITrcDataIn *pDataIn = 0; 456c120c564SAndrew Turner if((err = pDecoderMngr->getDataInputI(pTraceComp,&pDataIn)) == OCSD_OK) 457c120c564SAndrew Turner { 458c120c564SAndrew Turner // got the interface -> attach to demux, or direct to input of decode tree 459c120c564SAndrew Turner if(usingFormatter()) 460c120c564SAndrew Turner err = m_frame_deformatter_root->getIDStreamAttachPt(CSID)->attach(pDataIn); 461c120c564SAndrew Turner else 462c120c564SAndrew Turner m_i_decoder_root = pDataIn; 463c120c564SAndrew Turner } 464c120c564SAndrew Turner } 465c120c564SAndrew Turner 466c120c564SAndrew Turner if(err != OCSD_OK) 467c120c564SAndrew Turner { 468c120c564SAndrew Turner destroyDecodeElement(CSID); // will destroy decoder as well. 469c120c564SAndrew Turner } 470c120c564SAndrew Turner return err; 471c120c564SAndrew Turner } 472c120c564SAndrew Turner 473c120c564SAndrew Turner ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID) 474c120c564SAndrew Turner { 475c120c564SAndrew Turner ocsd_err_t err = OCSD_OK; 476c120c564SAndrew Turner uint8_t localID = CSID; 477c120c564SAndrew Turner if(!usingFormatter()) 478c120c564SAndrew Turner localID = 0; 479c120c564SAndrew Turner 480c120c564SAndrew Turner if(usingFormatter() && !OCSD_IS_VALID_CS_SRC_ID(CSID)) 481c120c564SAndrew Turner err = OCSD_ERR_INVALID_ID; 482c120c564SAndrew Turner else 483c120c564SAndrew Turner { 484c120c564SAndrew Turner destroyDecodeElement(localID); 485c120c564SAndrew Turner } 486c120c564SAndrew Turner return err; 487c120c564SAndrew Turner } 488c120c564SAndrew Turner 489c120c564SAndrew Turner DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const 490c120c564SAndrew Turner { 491c120c564SAndrew Turner DecodeTreeElement *ret_elem = 0; 492c120c564SAndrew Turner if(usingFormatter() && OCSD_IS_VALID_CS_SRC_ID(CSID)) 493c120c564SAndrew Turner { 494c120c564SAndrew Turner ret_elem = m_decode_elements[CSID]; 495c120c564SAndrew Turner } 496c120c564SAndrew Turner else 497c120c564SAndrew Turner ret_elem = m_decode_elements[0]; // ID 0 is used if single leaf tree. 498c120c564SAndrew Turner return ret_elem; 499c120c564SAndrew Turner } 500c120c564SAndrew Turner 501c120c564SAndrew Turner DecodeTreeElement *DecodeTree::getFirstElement(uint8_t &elemID) 502c120c564SAndrew Turner { 503c120c564SAndrew Turner m_decode_elem_iter = 0; 504c120c564SAndrew Turner return getNextElement(elemID); 505c120c564SAndrew Turner } 506c120c564SAndrew Turner 507c120c564SAndrew Turner DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID) 508c120c564SAndrew Turner { 509c120c564SAndrew Turner DecodeTreeElement *ret_elem = 0; 510c120c564SAndrew Turner 511c120c564SAndrew Turner if(m_decode_elem_iter < 0x80) 512c120c564SAndrew Turner { 513c120c564SAndrew Turner // find a none zero entry or end of range 514c120c564SAndrew Turner while((m_decode_elements[m_decode_elem_iter] == 0) && (m_decode_elem_iter < 0x80)) 515c120c564SAndrew Turner m_decode_elem_iter++; 516c120c564SAndrew Turner 517c120c564SAndrew Turner // return entry unless end of range 518c120c564SAndrew Turner if(m_decode_elem_iter < 0x80) 519c120c564SAndrew Turner { 520c120c564SAndrew Turner ret_elem = m_decode_elements[m_decode_elem_iter]; 521c120c564SAndrew Turner elemID = m_decode_elem_iter; 522c120c564SAndrew Turner m_decode_elem_iter++; 523c120c564SAndrew Turner } 524c120c564SAndrew Turner } 525c120c564SAndrew Turner return ret_elem; 526c120c564SAndrew Turner } 527c120c564SAndrew Turner 528c120c564SAndrew Turner bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags) 529c120c564SAndrew Turner { 530c120c564SAndrew Turner bool initOK = true; 531c120c564SAndrew Turner m_dcd_tree_type = type; 532c120c564SAndrew Turner if(type == OCSD_TRC_SRC_FRAME_FORMATTED) 533c120c564SAndrew Turner { 534c120c564SAndrew Turner // frame formatted - we want to create the deformatter and hook it up 535c120c564SAndrew Turner m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder(); 536c120c564SAndrew Turner if(m_frame_deformatter_root) 537c120c564SAndrew Turner { 538c120c564SAndrew Turner m_frame_deformatter_root->Configure(formatterCfgFlags); 539c120c564SAndrew Turner m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger); 540c120c564SAndrew Turner m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root); 541c120c564SAndrew Turner } 542c120c564SAndrew Turner else 543c120c564SAndrew Turner initOK = false; 544c120c564SAndrew Turner } 545c120c564SAndrew Turner return initOK; 546c120c564SAndrew Turner } 547c120c564SAndrew Turner 548c120c564SAndrew Turner void DecodeTree::setSingleRoot(TrcPktProcI *pComp) 549c120c564SAndrew Turner { 550c120c564SAndrew Turner m_i_decoder_root = static_cast<ITrcDataIn*>(pComp); 551c120c564SAndrew Turner } 552c120c564SAndrew Turner 553c120c564SAndrew Turner ocsd_err_t DecodeTree::createDecodeElement(const uint8_t CSID) 554c120c564SAndrew Turner { 555c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_INVALID_ID; 556c120c564SAndrew Turner if(CSID < 0x80) 557c120c564SAndrew Turner { 558c120c564SAndrew Turner if(m_decode_elements[CSID] == 0) 559c120c564SAndrew Turner { 560c120c564SAndrew Turner m_decode_elements[CSID] = new (std::nothrow) DecodeTreeElement(); 561c120c564SAndrew Turner if(m_decode_elements[CSID] == 0) 562c120c564SAndrew Turner err = OCSD_ERR_MEM; 563c120c564SAndrew Turner else 564c120c564SAndrew Turner err = OCSD_OK; 565c120c564SAndrew Turner } 566c120c564SAndrew Turner else 567c120c564SAndrew Turner err = OCSD_ERR_ATTACH_TOO_MANY; 568c120c564SAndrew Turner } 569c120c564SAndrew Turner return err; 570c120c564SAndrew Turner } 571c120c564SAndrew Turner 572c120c564SAndrew Turner void DecodeTree::destroyDecodeElement(const uint8_t CSID) 573c120c564SAndrew Turner { 574c120c564SAndrew Turner if(CSID < 0x80) 575c120c564SAndrew Turner { 576c120c564SAndrew Turner if(m_decode_elements[CSID] != 0) 577c120c564SAndrew Turner { 578c120c564SAndrew Turner m_decode_elements[CSID]->DestroyElem(); 579c120c564SAndrew Turner delete m_decode_elements[CSID]; 580c120c564SAndrew Turner m_decode_elements[CSID] = 0; 581c120c564SAndrew Turner } 582c120c564SAndrew Turner } 583c120c564SAndrew Turner } 584c120c564SAndrew Turner 585c120c564SAndrew Turner ocsd_err_t DecodeTree::setIDFilter(std::vector<uint8_t> &ids) 586c120c564SAndrew Turner { 587c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 588c120c564SAndrew Turner if(usingFormatter()) 589c120c564SAndrew Turner { 590c120c564SAndrew Turner err = m_frame_deformatter_root->OutputFilterAllIDs(false); 591c120c564SAndrew Turner if(err == OCSD_OK) 592c120c564SAndrew Turner err = m_frame_deformatter_root->OutputFilterIDs(ids,true); 593c120c564SAndrew Turner } 594c120c564SAndrew Turner return err; 595c120c564SAndrew Turner } 596c120c564SAndrew Turner 597c120c564SAndrew Turner ocsd_err_t DecodeTree::clearIDFilter() 598c120c564SAndrew Turner { 599c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 600c120c564SAndrew Turner if(usingFormatter()) 601c120c564SAndrew Turner { 602c120c564SAndrew Turner err = m_frame_deformatter_root->OutputFilterAllIDs(true); 603c120c564SAndrew Turner } 604c120c564SAndrew Turner return err; 605c120c564SAndrew Turner } 606c120c564SAndrew Turner 607c120c564SAndrew Turner /** add a protocol packet printer */ 608c120c564SAndrew Turner ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter) 609c120c564SAndrew Turner { 610c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL; 611c120c564SAndrew Turner DecodeTreeElement *pElement = getDecoderElement(CSID); 612c120c564SAndrew Turner if (pElement) 613c120c564SAndrew Turner { 614c120c564SAndrew Turner ocsd_trace_protocol_t protocol = pElement->getProtocol(); 615c120c564SAndrew Turner ItemPrinter *pPrinter; 616c120c564SAndrew Turner 617c120c564SAndrew Turner pPrinter = PktPrinterFact::createProtocolPrinter(getPrinterList(), protocol, CSID); 618c120c564SAndrew Turner if (pPrinter) 619c120c564SAndrew Turner { 620c120c564SAndrew Turner pPrinter->setMessageLogger(getCurrentErrorLogI()->getOutputLogger()); 621c120c564SAndrew Turner switch (protocol) 622c120c564SAndrew Turner { 623c120c564SAndrew Turner case OCSD_PROTOCOL_ETMV4I: 624c120c564SAndrew Turner { 625c120c564SAndrew Turner PacketPrinter<EtmV4ITrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV4ITrcPacket> *>(pPrinter); 626c120c564SAndrew Turner if (bMonitor) 627c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV4ITrcPacket> *)pTPrinter); 628c120c564SAndrew Turner else 629c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV4ITrcPacket> *)pTPrinter); 630c120c564SAndrew Turner } 631c120c564SAndrew Turner break; 632c120c564SAndrew Turner 633c120c564SAndrew Turner case OCSD_PROTOCOL_ETMV3: 634c120c564SAndrew Turner { 635c120c564SAndrew Turner PacketPrinter<EtmV3TrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV3TrcPacket> *>(pPrinter); 636c120c564SAndrew Turner if (bMonitor) 637c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV3TrcPacket> *)pTPrinter); 638c120c564SAndrew Turner else 639c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV3TrcPacket> *)pTPrinter); 640c120c564SAndrew Turner } 641c120c564SAndrew Turner break; 642c120c564SAndrew Turner 643c120c564SAndrew Turner case OCSD_PROTOCOL_PTM: 644c120c564SAndrew Turner { 645c120c564SAndrew Turner PacketPrinter<PtmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<PtmTrcPacket> *>(pPrinter); 646c120c564SAndrew Turner if (bMonitor) 647c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<PtmTrcPacket> *)pTPrinter); 648c120c564SAndrew Turner else 649c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<PtmTrcPacket> *)pTPrinter); 650c120c564SAndrew Turner } 651c120c564SAndrew Turner break; 652c120c564SAndrew Turner 653c120c564SAndrew Turner case OCSD_PROTOCOL_STM: 654c120c564SAndrew Turner { 655c120c564SAndrew Turner PacketPrinter<StmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<StmTrcPacket> *>(pPrinter); 656c120c564SAndrew Turner if (bMonitor) 657c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<StmTrcPacket> *)pTPrinter); 658c120c564SAndrew Turner else 659c120c564SAndrew Turner err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<StmTrcPacket> *)pTPrinter); 660c120c564SAndrew Turner } 661c120c564SAndrew Turner break; 662c120c564SAndrew Turner 663c120c564SAndrew Turner default: 664c120c564SAndrew Turner err = OCSD_ERR_NO_PROTOCOL; 665c120c564SAndrew Turner break; 666c120c564SAndrew Turner } 667c120c564SAndrew Turner 668c120c564SAndrew Turner if (err == OCSD_OK) 669c120c564SAndrew Turner { 670c120c564SAndrew Turner if (ppPrinter) 671c120c564SAndrew Turner *ppPrinter = pPrinter; 672c120c564SAndrew Turner } 673c120c564SAndrew Turner else 674c120c564SAndrew Turner PktPrinterFact::destroyPrinter(getPrinterList(), pPrinter); 675c120c564SAndrew Turner } 676c120c564SAndrew Turner } 677c120c564SAndrew Turner return err; 678c120c564SAndrew Turner } 679c120c564SAndrew Turner 680c120c564SAndrew Turner /** add a raw frame printer */ 681c120c564SAndrew Turner ocsd_err_t DecodeTree::addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags) 682c120c564SAndrew Turner { 683c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_MEM; 684c120c564SAndrew Turner RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(getPrinterList()); 685c120c564SAndrew Turner if (pPrinter) 686c120c564SAndrew Turner { 687c120c564SAndrew Turner pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 688c120c564SAndrew Turner TraceFormatterFrameDecoder *pFrameDecoder = getFrameDeformatter(); 689c120c564SAndrew Turner uint32_t cfgFlags = pFrameDecoder->getConfigFlags(); 690c120c564SAndrew Turner cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT)); 691c120c564SAndrew Turner pFrameDecoder->Configure(cfgFlags); 692c120c564SAndrew Turner err = pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter); 693c120c564SAndrew Turner if (ppPrinter && (err==OCSD_OK)) 694c120c564SAndrew Turner *ppPrinter = pPrinter; 695c120c564SAndrew Turner } 696c120c564SAndrew Turner return err; 697c120c564SAndrew Turner } 698c120c564SAndrew Turner 699c120c564SAndrew Turner /** add a generic element output printer */ 700c120c564SAndrew Turner ocsd_err_t DecodeTree::addGenElemPrinter(TrcGenericElementPrinter **ppPrinter) 701c120c564SAndrew Turner { 702c120c564SAndrew Turner ocsd_err_t err = OCSD_ERR_MEM; 703c120c564SAndrew Turner TrcGenericElementPrinter *pPrinter = PktPrinterFact::createGenElemPrinter(getPrinterList()); 704c120c564SAndrew Turner if (pPrinter) 705c120c564SAndrew Turner { 706c120c564SAndrew Turner pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 707c120c564SAndrew Turner setGenTraceElemOutI(pPrinter); 708c120c564SAndrew Turner err = OCSD_OK; 709c120c564SAndrew Turner if (ppPrinter) 710c120c564SAndrew Turner *ppPrinter = pPrinter; 711c120c564SAndrew Turner } 712c120c564SAndrew Turner return err; 713c120c564SAndrew Turner 714c120c564SAndrew Turner } 715c120c564SAndrew Turner 716c120c564SAndrew Turner /* End of File ocsd_dcd_tree.cpp */ 717