1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 *    conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 *    of conditions and the following disclaimer in the documentation and/or other materials
13 *    provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 *    to endorse or promote products derived from this software without specific prior written
17 *    permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "trace_pipeline.h"
33#include "trace_tlv.h"
34#include "los_trace_pri.h"
35
36#if (LOSCFG_KERNEL_SMP == 1)
37LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_pipeSpin);
38#define PIPE_LOCK(state)                   LOS_SpinLockSave(&g_pipeSpin, &(state))
39#define PIPE_UNLOCK(state)                 LOS_SpinUnlockRestore(&g_pipeSpin, (state))
40#else
41#define PIPE_LOCK(state) 		   (state) = LOS_IntLock()
42#define PIPE_UNLOCK(state)		   LOS_IntRestore(state)
43#endif
44
45STATIC TlvTable g_traceTlvTblNotify[] = {
46    { CMD,    LOS_OFF_SET_OF(TraceNotifyFrame, cmd),   sizeof(UINT32) },
47    { PARAMS, LOS_OFF_SET_OF(TraceNotifyFrame, param), sizeof(UINT32) },
48    { TRACE_TLV_TYPE_NULL, 0, 0 },
49};
50
51STATIC TlvTable g_traceTlvTblHead[] = {
52    { ENDIAN,     LOS_OFF_SET_OF(TraceBaseHeaderInfo, bigLittleEndian), sizeof(UINT32) },
53    { VERSION,    LOS_OFF_SET_OF(TraceBaseHeaderInfo, version),         sizeof(UINT32) },
54    { CLOCK_FREQ, LOS_OFF_SET_OF(TraceBaseHeaderInfo, clockFreq),       sizeof(UINT32) },
55    { TRACE_TLV_TYPE_NULL, 0, 0 },
56};
57
58STATIC TlvTable g_traceTlvTblObj[] = {
59    { ADDR, LOS_OFF_SET_OF(ObjData, id),   sizeof(UINT32) },
60    { PRIO, LOS_OFF_SET_OF(ObjData, prio), sizeof(UINT32) },
61    { NAME, LOS_OFF_SET_OF(ObjData, name), sizeof(CHAR) * LOSCFG_TRACE_OBJ_MAX_NAME_SIZE },
62    { TRACE_TLV_TYPE_NULL, 0, 0 },
63};
64
65STATIC TlvTable g_traceTlvTblEvent[] = {
66#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1)
67    { CORE,         LOS_OFF_SET_OF(TraceEventFrame, core),       sizeof(UINT32) },
68#endif
69    { EVENT_CODE,   LOS_OFF_SET_OF(TraceEventFrame, eventType),  sizeof(UINT32) },
70    { CUR_TIME,     LOS_OFF_SET_OF(TraceEventFrame, curTime),    sizeof(UINT64) },
71
72#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1)
73    { EVENT_COUNT,  LOS_OFF_SET_OF(TraceEventFrame, eventCount), sizeof(UINT32) },
74#endif
75    { CUR_TASK,     LOS_OFF_SET_OF(TraceEventFrame, curTask),    sizeof(UINT32) },
76    { IDENTITY,     LOS_OFF_SET_OF(TraceEventFrame, identity),   sizeof(UINTPTR) },
77    { EVENT_PARAMS, LOS_OFF_SET_OF(TraceEventFrame, params),     sizeof(UINTPTR) * LOSCFG_TRACE_FRAME_MAX_PARAMS },
78    { TRACE_TLV_TYPE_NULL, 0, 0 },
79};
80
81STATIC TlvTable *g_traceTlvTbl[] = {
82    g_traceTlvTblNotify,
83    g_traceTlvTblHead,
84    g_traceTlvTblObj,
85    g_traceTlvTblEvent
86};
87
88STATIC UINT32 DefaultPipelineInit(VOID)
89{
90    return LOS_OK;
91}
92
93STATIC VOID DefaultDataSend(UINT16 len, UINT8 *data)
94{
95    (VOID)len;
96    (VOID)data;
97}
98
99STATIC UINT32 DefaultDataReceive(UINT8 *data, UINT32 size, UINT32 timeout)
100{
101    (VOID)data;
102    (VOID)size;
103    (VOID)timeout;
104    return LOS_OK;
105}
106
107STATIC UINT32 DefaultWait(VOID)
108{
109    return LOS_OK;
110}
111
112STATIC TracePipelineOps g_defaultOps = {
113    .init = DefaultPipelineInit,
114    .dataSend = DefaultDataSend,
115    .dataRecv = DefaultDataReceive,
116    .wait = DefaultWait,
117};
118
119STATIC const TracePipelineOps *g_tracePipelineOps = &g_defaultOps;
120
121VOID OsTracePipelineReg(const TracePipelineOps *ops)
122{
123    g_tracePipelineOps = ops;
124}
125
126VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data)
127{
128    UINT32 intSave;
129    UINT8 outBuf[LOSCFG_TRACE_TLV_BUF_SIZE] = {0};
130
131    if ((type >= TRACE_MSG_MAX) || (len > LOSCFG_TRACE_TLV_BUF_SIZE)) {
132        return;
133    }
134
135    len = OsTraceDataEncode(type, g_traceTlvTbl[type], data, &outBuf[0], sizeof(outBuf));
136
137    PIPE_LOCK(intSave);
138    g_tracePipelineOps->dataSend(len, &outBuf[0]);
139    PIPE_UNLOCK(intSave);
140}
141
142UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout)
143{
144    return g_tracePipelineOps->dataRecv(data, size, timeout);
145}
146
147UINT32 OsTraceDataWait(VOID)
148{
149    return g_tracePipelineOps->wait();
150}
151