13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 43d8536b4Sopenharmony_ci * 53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 73d8536b4Sopenharmony_ci * 83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 93d8536b4Sopenharmony_ci * conditions and the following disclaimer. 103d8536b4Sopenharmony_ci * 113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 123d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 133d8536b4Sopenharmony_ci * provided with the distribution. 143d8536b4Sopenharmony_ci * 153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 163d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 173d8536b4Sopenharmony_ci * permission. 183d8536b4Sopenharmony_ci * 193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d8536b4Sopenharmony_ci */ 313d8536b4Sopenharmony_ci 323d8536b4Sopenharmony_ci#include "los_trace_pri.h" 333d8536b4Sopenharmony_ci#include "trace_pipeline.h" 343d8536b4Sopenharmony_ci#include "los_memory.h" 353d8536b4Sopenharmony_ci#include "securec.h" 363d8536b4Sopenharmony_ci 373d8536b4Sopenharmony_ci#if (LOSCFG_RECORDER_MODE_OFFLINE == 1) 383d8536b4Sopenharmony_ci#define BITS_NUM_FOR_TASK_ID 16 393d8536b4Sopenharmony_ci 403d8536b4Sopenharmony_ciLITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder; 413d8536b4Sopenharmony_ciLITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; 423d8536b4Sopenharmony_ci 433d8536b4Sopenharmony_ciUINT32 OsTraceGetMaskTid(UINT32 tid) 443d8536b4Sopenharmony_ci{ 453d8536b4Sopenharmony_ci return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */ 463d8536b4Sopenharmony_ci} 473d8536b4Sopenharmony_ci 483d8536b4Sopenharmony_ciUINT32 OsTraceBufInit(UINT32 size) 493d8536b4Sopenharmony_ci{ 503d8536b4Sopenharmony_ci UINT32 headSize; 513d8536b4Sopenharmony_ci VOID *buf = NULL; 523d8536b4Sopenharmony_ci headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM; 533d8536b4Sopenharmony_ci if (size <= headSize) { 543d8536b4Sopenharmony_ci TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize); 553d8536b4Sopenharmony_ci return LOS_ERRNO_TRACE_BUF_TOO_SMALL; 563d8536b4Sopenharmony_ci } 573d8536b4Sopenharmony_ci 583d8536b4Sopenharmony_ci buf = LOS_MemAlloc(m_aucSysMem0, size); 593d8536b4Sopenharmony_ci if (buf == NULL) { 603d8536b4Sopenharmony_ci return LOS_ERRNO_TRACE_NO_MEMORY; 613d8536b4Sopenharmony_ci } 623d8536b4Sopenharmony_ci 633d8536b4Sopenharmony_ci (VOID)memset_s(buf, size, 0, size); 643d8536b4Sopenharmony_ci g_traceRecoder.head = (OfflineHead *)buf; 653d8536b4Sopenharmony_ci g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD; 663d8536b4Sopenharmony_ci g_traceRecoder.head->baseInfo.version = TRACE_VERSION(TRACE_MODE_OFFLINE); 673d8536b4Sopenharmony_ci g_traceRecoder.head->baseInfo.clockFreq = g_sysClock; 683d8536b4Sopenharmony_ci g_traceRecoder.head->objSize = sizeof(ObjData); 693d8536b4Sopenharmony_ci g_traceRecoder.head->frameSize = sizeof(TraceEventFrame); 703d8536b4Sopenharmony_ci g_traceRecoder.head->objOffset = sizeof(OfflineHead); 713d8536b4Sopenharmony_ci g_traceRecoder.head->frameOffset = headSize; 723d8536b4Sopenharmony_ci g_traceRecoder.head->totalLen = size; 733d8536b4Sopenharmony_ci 743d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 753d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex = 0; 763d8536b4Sopenharmony_ci g_traceRecoder.ctrl.maxObjCount = LOSCFG_TRACE_OBJ_MAX_NUM; 773d8536b4Sopenharmony_ci g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame); 783d8536b4Sopenharmony_ci g_traceRecoder.ctrl.objBuf = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset); 793d8536b4Sopenharmony_ci g_traceRecoder.ctrl.frameBuf = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset); 803d8536b4Sopenharmony_ci 813d8536b4Sopenharmony_ci return LOS_OK; 823d8536b4Sopenharmony_ci} 833d8536b4Sopenharmony_ci 843d8536b4Sopenharmony_ciVOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) 853d8536b4Sopenharmony_ci{ 863d8536b4Sopenharmony_ci UINT32 intSave; 873d8536b4Sopenharmony_ci UINT32 index; 883d8536b4Sopenharmony_ci ObjData *obj = NULL; 893d8536b4Sopenharmony_ci 903d8536b4Sopenharmony_ci TRACE_LOCK(intSave); 913d8536b4Sopenharmony_ci /* add obj begin */ 923d8536b4Sopenharmony_ci index = g_traceRecoder.ctrl.curObjIndex; 933d8536b4Sopenharmony_ci if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */ 943d8536b4Sopenharmony_ci TRACE_UNLOCK(intSave); 953d8536b4Sopenharmony_ci return; 963d8536b4Sopenharmony_ci } 973d8536b4Sopenharmony_ci obj = &g_traceRecoder.ctrl.objBuf[index]; 983d8536b4Sopenharmony_ci 993d8536b4Sopenharmony_ci if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) { 1003d8536b4Sopenharmony_ci g_tidMask[taskId]++; 1013d8536b4Sopenharmony_ci } 1023d8536b4Sopenharmony_ci 1033d8536b4Sopenharmony_ci OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId)); 1043d8536b4Sopenharmony_ci 1053d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex++; 1063d8536b4Sopenharmony_ci if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) { 1073d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */ 1083d8536b4Sopenharmony_ci } 1093d8536b4Sopenharmony_ci /* add obj end */ 1103d8536b4Sopenharmony_ci TRACE_UNLOCK(intSave); 1113d8536b4Sopenharmony_ci} 1123d8536b4Sopenharmony_ci 1133d8536b4Sopenharmony_ciVOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) 1143d8536b4Sopenharmony_ci{ 1153d8536b4Sopenharmony_ci UINT16 index; 1163d8536b4Sopenharmony_ci UINT32 intSave; 1173d8536b4Sopenharmony_ci 1183d8536b4Sopenharmony_ci TRACE_LOCK(intSave); 1193d8536b4Sopenharmony_ci index = g_traceRecoder.ctrl.curIndex; 1203d8536b4Sopenharmony_ci (VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame)); 1213d8536b4Sopenharmony_ci 1223d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curIndex++; 1233d8536b4Sopenharmony_ci if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) { 1243d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 1253d8536b4Sopenharmony_ci } 1263d8536b4Sopenharmony_ci TRACE_UNLOCK(intSave); 1273d8536b4Sopenharmony_ci} 1283d8536b4Sopenharmony_ci 1293d8536b4Sopenharmony_ciVOID OsTraceReset(VOID) 1303d8536b4Sopenharmony_ci{ 1313d8536b4Sopenharmony_ci UINT32 intSave; 1323d8536b4Sopenharmony_ci UINT32 bufLen; 1333d8536b4Sopenharmony_ci 1343d8536b4Sopenharmony_ci TRACE_LOCK(intSave); 1353d8536b4Sopenharmony_ci bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount; 1363d8536b4Sopenharmony_ci (VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen); 1373d8536b4Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 1383d8536b4Sopenharmony_ci TRACE_UNLOCK(intSave); 1393d8536b4Sopenharmony_ci} 1403d8536b4Sopenharmony_ci 1413d8536b4Sopenharmony_ciSTATIC VOID OsTraceInfoObj(VOID) 1423d8536b4Sopenharmony_ci{ 1433d8536b4Sopenharmony_ci UINT32 i; 1443d8536b4Sopenharmony_ci ObjData *obj = &g_traceRecoder.ctrl.objBuf[0]; 1453d8536b4Sopenharmony_ci 1463d8536b4Sopenharmony_ci if (g_traceRecoder.ctrl.maxObjCount > 0) { 1473d8536b4Sopenharmony_ci PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex); 1483d8536b4Sopenharmony_ci PRINTK("Index TaskID TaskPrio TaskName \n"); 1493d8536b4Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) { 1503d8536b4Sopenharmony_ci PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name); 1513d8536b4Sopenharmony_ci } 1523d8536b4Sopenharmony_ci PRINTK("\n"); 1533d8536b4Sopenharmony_ci } 1543d8536b4Sopenharmony_ci} 1553d8536b4Sopenharmony_ci 1563d8536b4Sopenharmony_ciSTATIC VOID OsTraceInfoEventTitle(VOID) 1573d8536b4Sopenharmony_ci{ 1583d8536b4Sopenharmony_ci PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex); 1593d8536b4Sopenharmony_ci 1603d8536b4Sopenharmony_ci PRINTK("Index Time(cycles) EventType CurTask Identity "); 1613d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1) 1623d8536b4Sopenharmony_ci PRINTK("cpuId hwiActive taskLockCnt "); 1633d8536b4Sopenharmony_ci#endif 1643d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1) 1653d8536b4Sopenharmony_ci PRINTK("eventCount "); 1663d8536b4Sopenharmony_ci#endif 1673d8536b4Sopenharmony_ci if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) { 1683d8536b4Sopenharmony_ci PRINTK("params "); 1693d8536b4Sopenharmony_ci } 1703d8536b4Sopenharmony_ci PRINTK("\n"); 1713d8536b4Sopenharmony_ci} 1723d8536b4Sopenharmony_ci 1733d8536b4Sopenharmony_ciSTATIC VOID OsTraceInfoEventData(VOID) 1743d8536b4Sopenharmony_ci{ 1753d8536b4Sopenharmony_ci UINT32 i, j; 1763d8536b4Sopenharmony_ci TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0]; 1773d8536b4Sopenharmony_ci 1783d8536b4Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) { 1793d8536b4Sopenharmony_ci PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-11x ", i, (UINT32)frame->curTime, frame->eventType, 1803d8536b4Sopenharmony_ci frame->curTask, frame->identity); 1813d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_FRAME_CORE_MSG == 1) 1823d8536b4Sopenharmony_ci UINT32 taskLockCnt = frame->core.taskLockCnt; 1833d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_SMP == 1) 1843d8536b4Sopenharmony_ci /* 1853d8536b4Sopenharmony_ci * For smp systems, TRACE_LOCK will request taskLock, and this counter 1863d8536b4Sopenharmony_ci * will increase by 1 in that case. 1873d8536b4Sopenharmony_ci */ 1883d8536b4Sopenharmony_ci taskLockCnt -= 1; 1893d8536b4Sopenharmony_ci#endif 1903d8536b4Sopenharmony_ci PRINTK("%-11u %-11u %-11u", frame->core.cpuId, frame->core.hwiActive, taskLockCnt); 1913d8536b4Sopenharmony_ci#endif 1923d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_FRAME_EVENT_COUNT == 1) 1933d8536b4Sopenharmony_ci PRINTK("%-11u", frame->eventCount); 1943d8536b4Sopenharmony_ci#endif 1953d8536b4Sopenharmony_ci for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) { 1963d8536b4Sopenharmony_ci PRINTK("0x%-11x", frame->params[j]); 1973d8536b4Sopenharmony_ci } 1983d8536b4Sopenharmony_ci PRINTK("\n"); 1993d8536b4Sopenharmony_ci } 2003d8536b4Sopenharmony_ci} 2013d8536b4Sopenharmony_ci 2023d8536b4Sopenharmony_ciSTATIC VOID OsTraceInfoDisplay(VOID) 2033d8536b4Sopenharmony_ci{ 2043d8536b4Sopenharmony_ci OfflineHead *head = g_traceRecoder.head; 2053d8536b4Sopenharmony_ci 2063d8536b4Sopenharmony_ci PRINTK("*******TraceInfo begin*******\n"); 2073d8536b4Sopenharmony_ci PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq); 2083d8536b4Sopenharmony_ci 2093d8536b4Sopenharmony_ci OsTraceInfoObj(); 2103d8536b4Sopenharmony_ci 2113d8536b4Sopenharmony_ci OsTraceInfoEventTitle(); 2123d8536b4Sopenharmony_ci OsTraceInfoEventData(); 2133d8536b4Sopenharmony_ci 2143d8536b4Sopenharmony_ci PRINTK("*******TraceInfo end*******\n"); 2153d8536b4Sopenharmony_ci} 2163d8536b4Sopenharmony_ci 2173d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_CLIENT_INTERACT == 1) 2183d8536b4Sopenharmony_ciSTATIC VOID OsTraceSendInfo(VOID) 2193d8536b4Sopenharmony_ci{ 2203d8536b4Sopenharmony_ci UINT32 i; 2213d8536b4Sopenharmony_ci ObjData *obj = NULL; 2223d8536b4Sopenharmony_ci TraceEventFrame *frame = NULL; 2233d8536b4Sopenharmony_ci 2243d8536b4Sopenharmony_ci OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head); 2253d8536b4Sopenharmony_ci 2263d8536b4Sopenharmony_ci obj = &g_traceRecoder.ctrl.objBuf[0]; 2273d8536b4Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) { 2283d8536b4Sopenharmony_ci OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i)); 2293d8536b4Sopenharmony_ci } 2303d8536b4Sopenharmony_ci 2313d8536b4Sopenharmony_ci frame = &g_traceRecoder.ctrl.frameBuf[0]; 2323d8536b4Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) { 2333d8536b4Sopenharmony_ci OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i)); 2343d8536b4Sopenharmony_ci } 2353d8536b4Sopenharmony_ci} 2363d8536b4Sopenharmony_ci#endif 2373d8536b4Sopenharmony_ci 2383d8536b4Sopenharmony_ciVOID OsTraceRecordDump(BOOL toClient) 2393d8536b4Sopenharmony_ci{ 2403d8536b4Sopenharmony_ci if (!toClient) { 2413d8536b4Sopenharmony_ci OsTraceInfoDisplay(); 2423d8536b4Sopenharmony_ci return; 2433d8536b4Sopenharmony_ci } 2443d8536b4Sopenharmony_ci 2453d8536b4Sopenharmony_ci#if (LOSCFG_TRACE_CLIENT_INTERACT == 1) 2463d8536b4Sopenharmony_ci OsTraceSendInfo(); 2473d8536b4Sopenharmony_ci#endif 2483d8536b4Sopenharmony_ci} 2493d8536b4Sopenharmony_ci 2503d8536b4Sopenharmony_ciOfflineHead *OsTraceRecordGet(VOID) 2513d8536b4Sopenharmony_ci{ 2523d8536b4Sopenharmony_ci return g_traceRecoder.head; 2533d8536b4Sopenharmony_ci} 2543d8536b4Sopenharmony_ci 2553d8536b4Sopenharmony_ci#endif /* LOSCFG_RECORDER_MODE_OFFLINE == 1 */ 256