You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
5.4 KiB
197 lines
5.4 KiB
/*
|
|
* \file ocsd_gen_elem_stack.cpp
|
|
* \brief OpenCSD : List of Generic trace elements for output.
|
|
*
|
|
* \copyright Copyright (c) 2020, ARM Limited. All Rights Reserved.
|
|
*/
|
|
|
|
|
|
/*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "common/ocsd_gen_elem_stack.h"
|
|
|
|
OcsdGenElemStack::OcsdGenElemStack() :
|
|
m_pElemArray(0),
|
|
m_elemArraySize(0),
|
|
m_elem_to_send(0),
|
|
m_curr_elem_idx(0),
|
|
m_send_elem_idx(0),
|
|
m_CSID(0),
|
|
m_is_init(false)
|
|
{
|
|
|
|
}
|
|
|
|
OcsdGenElemStack::~OcsdGenElemStack()
|
|
{
|
|
for (int i = 0; i<m_elemArraySize; i++)
|
|
{
|
|
delete m_pElemArray[i].pElem;
|
|
}
|
|
delete [] m_pElemArray;
|
|
m_pElemArray = 0;
|
|
}
|
|
|
|
ocsd_err_t OcsdGenElemStack::addElem(const ocsd_trc_index_t trc_pkt_idx)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
|
|
if (((m_curr_elem_idx + 1) == m_elemArraySize) || !m_pElemArray)
|
|
{
|
|
err = growArray();
|
|
if (err)
|
|
return err;
|
|
}
|
|
|
|
// if there is a least one element then copy and increment
|
|
// otherwise we are at base of stack.
|
|
if (m_elem_to_send)
|
|
{
|
|
copyPersistentData(m_curr_elem_idx, m_curr_elem_idx + 1);
|
|
m_curr_elem_idx++;
|
|
}
|
|
m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx;
|
|
m_elem_to_send++;
|
|
return err;
|
|
}
|
|
|
|
ocsd_err_t OcsdGenElemStack::addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type)
|
|
{
|
|
ocsd_err_t err = addElem(trc_pkt_idx);
|
|
if (!err)
|
|
getCurrElem().setType(elem_type);
|
|
return err;
|
|
}
|
|
|
|
ocsd_err_t OcsdGenElemStack::resetElemStack()
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
if (!m_pElemArray)
|
|
{
|
|
err = growArray();
|
|
if (err)
|
|
return err;
|
|
}
|
|
|
|
if (!isInit())
|
|
return OCSD_ERR_NOT_INIT;
|
|
|
|
resetIndexes();
|
|
return err;
|
|
}
|
|
|
|
void OcsdGenElemStack::resetIndexes()
|
|
{
|
|
// last time there was more than one element on stack
|
|
if (m_curr_elem_idx > 0)
|
|
copyPersistentData(m_curr_elem_idx, 0);
|
|
|
|
// indexes to bottom of stack, nothing in use at present
|
|
m_curr_elem_idx = 0;
|
|
m_send_elem_idx = 0;
|
|
m_elem_to_send = 0;
|
|
}
|
|
|
|
ocsd_datapath_resp_t OcsdGenElemStack::sendElements()
|
|
{
|
|
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
|
|
if (!isInit())
|
|
return OCSD_RESP_FATAL_NOT_INIT;
|
|
|
|
while (m_elem_to_send && OCSD_DATA_RESP_IS_CONT(resp))
|
|
{
|
|
resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_send_elem_idx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_send_elem_idx].pElem));
|
|
m_send_elem_idx++;
|
|
m_elem_to_send--;
|
|
}
|
|
|
|
// clear the indexes if we are done.
|
|
if (!m_elem_to_send)
|
|
resetIndexes();
|
|
return resp;
|
|
}
|
|
|
|
ocsd_err_t OcsdGenElemStack::growArray()
|
|
{
|
|
elemPtr_t *p_new_array = 0;
|
|
const int increment = 4;
|
|
|
|
p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize + increment];
|
|
|
|
if (p_new_array != 0)
|
|
{
|
|
OcsdTraceElement *pElem = 0;
|
|
|
|
// fill the last increment elements with new objects
|
|
for (int i = 0; i < increment; i++)
|
|
{
|
|
pElem = new (std::nothrow) OcsdTraceElement();
|
|
if (!pElem)
|
|
return OCSD_ERR_MEM;
|
|
pElem->init();
|
|
p_new_array[m_elemArraySize + i].pElem = pElem;
|
|
}
|
|
|
|
// copy the existing objects from the old array to the start of the new one
|
|
if (m_elemArraySize > 0)
|
|
{
|
|
for (int i = 0; i < m_elemArraySize; i++)
|
|
{
|
|
p_new_array[i].pElem = m_pElemArray[i].pElem;
|
|
p_new_array[i].trc_pkt_idx = m_pElemArray[i].trc_pkt_idx;
|
|
}
|
|
}
|
|
|
|
// delete the old pointer array.
|
|
delete[] m_pElemArray;
|
|
m_elemArraySize += increment;
|
|
m_pElemArray = p_new_array;
|
|
}
|
|
else
|
|
return OCSD_ERR_MEM;
|
|
|
|
return OCSD_OK;
|
|
}
|
|
|
|
void OcsdGenElemStack::copyPersistentData(int src, int dst)
|
|
{
|
|
m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem));
|
|
}
|
|
|
|
const bool OcsdGenElemStack::isInit()
|
|
{
|
|
if (!m_is_init) {
|
|
if (m_elemArraySize && m_pElemArray && m_sendIf)
|
|
m_is_init = true;
|
|
}
|
|
return m_is_init;
|
|
}
|
|
|
|
|
|
/* End of File ocsd_gen_elem_stack.cpp */
|