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