1 /* 2 * \file ocsd_lib_dcd_register.cpp 3 * \brief OpenCSD : Library decoder register object 4 * 5 * \copyright Copyright (c) 2016, 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 "common/ocsd_lib_dcd_register.h" 36 37 // include built-in decode manager headers 38 #include "opencsd/etmv4/trc_dcd_mngr_etmv4i.h" 39 #include "opencsd/etmv3/trc_dcd_mngr_etmv3.h" 40 #include "opencsd/ptm/trc_dcd_mngr_ptm.h" 41 #include "opencsd/stm/trc_dcd_mngr_stm.h" 42 43 // create array of built-in decoders to register with library 44 static built_in_decoder_info_t sBuiltInArray[] = { 45 CREATE_BUILTIN_ENTRY(DecoderMngrEtmV4I,OCSD_BUILTIN_DCD_ETMV4I), 46 CREATE_BUILTIN_ENTRY(DecoderMngrEtmV3, OCSD_BUILTIN_DCD_ETMV3), 47 CREATE_BUILTIN_ENTRY(DecoderMngrPtm, OCSD_BUILTIN_DCD_PTM), 48 CREATE_BUILTIN_ENTRY(DecoderMngrStm, OCSD_BUILTIN_DCD_STM) 49 //{ 0, 0, 0} 50 }; 51 52 #define NUM_BUILTINS sizeof(sBuiltInArray) / sizeof(built_in_decoder_info_t) 53 54 55 OcsdLibDcdRegister *OcsdLibDcdRegister::m_p_libMngr = 0; 56 bool OcsdLibDcdRegister::m_b_registeredBuiltins = false; 57 ocsd_trace_protocol_t OcsdLibDcdRegister::m_nextCustomProtocolID = OCSD_PROTOCOL_CUSTOM_0; 58 59 OcsdLibDcdRegister *OcsdLibDcdRegister::getDecoderRegister() 60 { 61 if(m_p_libMngr == 0) 62 m_p_libMngr = new (std::nothrow) OcsdLibDcdRegister(); 63 return m_p_libMngr; 64 } 65 66 const ocsd_trace_protocol_t OcsdLibDcdRegister::getNextCustomProtocolID() 67 { 68 ocsd_trace_protocol_t ret = m_nextCustomProtocolID; 69 if(m_nextCustomProtocolID < OCSD_PROTOCOL_END) 70 m_nextCustomProtocolID = (ocsd_trace_protocol_t)(((int)m_nextCustomProtocolID)+1); 71 return ret; 72 } 73 74 void OcsdLibDcdRegister::releaseLastCustomProtocolID() 75 { 76 if(m_nextCustomProtocolID > OCSD_PROTOCOL_CUSTOM_0) 77 m_nextCustomProtocolID = (ocsd_trace_protocol_t)(((int)m_nextCustomProtocolID)-1); 78 } 79 80 OcsdLibDcdRegister::OcsdLibDcdRegister() 81 { 82 m_iter = m_decoder_mngrs.begin(); 83 m_pLastTypedDecoderMngr = 0; 84 } 85 86 OcsdLibDcdRegister::~OcsdLibDcdRegister() 87 { 88 m_decoder_mngrs.clear(); 89 m_typed_decoder_mngrs.clear(); 90 m_pLastTypedDecoderMngr = 0; 91 } 92 93 94 const ocsd_err_t OcsdLibDcdRegister::registerDecoderTypeByName(const std::string &name, IDecoderMngr *p_decoder_fact) 95 { 96 if(isRegisteredDecoder(name)) 97 return OCSD_ERR_DCDREG_NAME_REPEAT; 98 m_decoder_mngrs.emplace(std::pair<const std::string, IDecoderMngr *>(name,p_decoder_fact)); 99 m_typed_decoder_mngrs.emplace(std::pair<const ocsd_trace_protocol_t, IDecoderMngr *>(p_decoder_fact->getProtocolType(),p_decoder_fact)); 100 return OCSD_OK; 101 } 102 103 void OcsdLibDcdRegister::registerBuiltInDecoders() 104 { 105 bool memFail = false; 106 for(unsigned i = 0; i < NUM_BUILTINS; i++) 107 { 108 if(sBuiltInArray[i].PFn) 109 { 110 sBuiltInArray[i].pMngr = sBuiltInArray[i].PFn( sBuiltInArray[i].name); 111 if(!sBuiltInArray[i].pMngr) 112 memFail=true; 113 } 114 } 115 m_b_registeredBuiltins = !memFail; 116 } 117 118 void OcsdLibDcdRegister::deregisterAllDecoders() 119 { 120 if(m_b_registeredBuiltins) 121 { 122 for(unsigned i = 0; i < NUM_BUILTINS; i++) 123 delete sBuiltInArray[i].pMngr; 124 m_b_registeredBuiltins = false; 125 } 126 127 if(m_p_libMngr) 128 { 129 m_p_libMngr->deRegisterCustomDecoders(); 130 delete m_p_libMngr; 131 m_p_libMngr = 0; 132 } 133 } 134 135 void OcsdLibDcdRegister::deRegisterCustomDecoders() 136 { 137 std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.begin(); 138 while(iter != m_typed_decoder_mngrs.end()) 139 { 140 IDecoderMngr *pMngr = iter->second; 141 if(pMngr->getProtocolType() >= OCSD_PROTOCOL_CUSTOM_0) 142 delete pMngr; 143 iter++; 144 } 145 } 146 147 const ocsd_err_t OcsdLibDcdRegister::getDecoderMngrByName(const std::string &name, IDecoderMngr **p_decoder_mngr) 148 { 149 if(!m_b_registeredBuiltins) 150 { 151 registerBuiltInDecoders(); 152 if(!m_b_registeredBuiltins) 153 return OCSD_ERR_MEM; 154 } 155 156 std::map<const std::string, IDecoderMngr *>::const_iterator iter = m_decoder_mngrs.find(name); 157 if(iter == m_decoder_mngrs.end()) 158 return OCSD_ERR_DCDREG_NAME_UNKNOWN; 159 *p_decoder_mngr = iter->second; 160 return OCSD_OK; 161 } 162 163 const ocsd_err_t OcsdLibDcdRegister::getDecoderMngrByType(const ocsd_trace_protocol_t decoderType, IDecoderMngr **p_decoder_mngr) 164 { 165 if(!m_b_registeredBuiltins) 166 { 167 registerBuiltInDecoders(); 168 if(!m_b_registeredBuiltins) 169 return OCSD_ERR_MEM; 170 } 171 172 if (m_pLastTypedDecoderMngr && (m_pLastTypedDecoderMngr->getProtocolType() == decoderType)) 173 *p_decoder_mngr = m_pLastTypedDecoderMngr; 174 else 175 { 176 std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType); 177 if (iter == m_typed_decoder_mngrs.end()) 178 return OCSD_ERR_DCDREG_TYPE_UNKNOWN; 179 *p_decoder_mngr = m_pLastTypedDecoderMngr = iter->second; 180 } 181 return OCSD_OK; 182 } 183 184 const bool OcsdLibDcdRegister::isRegisteredDecoder(const std::string &name) 185 { 186 std::map<const std::string, IDecoderMngr *>::const_iterator iter = m_decoder_mngrs.find(name); 187 if(iter != m_decoder_mngrs.end()) 188 return true; 189 return false; 190 } 191 192 const bool OcsdLibDcdRegister::isRegisteredDecoderType(const ocsd_trace_protocol_t decoderType) 193 { 194 std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType); 195 if(iter != m_typed_decoder_mngrs.end()) 196 return true; 197 return false; 198 } 199 200 const bool OcsdLibDcdRegister::getFirstNamedDecoder(std::string &name) 201 { 202 m_iter = m_decoder_mngrs.begin(); 203 return getNextNamedDecoder(name); 204 } 205 206 const bool OcsdLibDcdRegister::getNextNamedDecoder(std::string &name) 207 { 208 if(m_iter == m_decoder_mngrs.end()) 209 return false; 210 name = m_iter->first; 211 m_iter++; 212 return true; 213 } 214 215 /* End of File ocsd_lib_dcd_register.cpp */ 216