10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include "los_trace_pri.h" 330d163575Sopenharmony_ci#include "trace_pipeline.h" 340d163575Sopenharmony_ci 350d163575Sopenharmony_ci#define BITS_NUM_FOR_TASK_ID 16 360d163575Sopenharmony_ci 370d163575Sopenharmony_ciLITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder; 380d163575Sopenharmony_ciLITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; 390d163575Sopenharmony_ci 400d163575Sopenharmony_ciUINT32 OsTraceGetMaskTid(UINT32 tid) 410d163575Sopenharmony_ci{ 420d163575Sopenharmony_ci return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */ 430d163575Sopenharmony_ci} 440d163575Sopenharmony_ci 450d163575Sopenharmony_ciUINT32 OsTraceBufInit(UINT32 size) 460d163575Sopenharmony_ci{ 470d163575Sopenharmony_ci UINT32 headSize; 480d163575Sopenharmony_ci VOID *buf = NULL; 490d163575Sopenharmony_ci headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM; 500d163575Sopenharmony_ci if (size <= headSize) { 510d163575Sopenharmony_ci TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize); 520d163575Sopenharmony_ci return LOS_ERRNO_TRACE_BUF_TOO_SMALL; 530d163575Sopenharmony_ci } 540d163575Sopenharmony_ci 550d163575Sopenharmony_ci 560d163575Sopenharmony_ci buf = LOS_MemAlloc(m_aucSysMem0, size); 570d163575Sopenharmony_ci if (buf == NULL) { 580d163575Sopenharmony_ci return LOS_ERRNO_TRACE_NO_MEMORY; 590d163575Sopenharmony_ci } 600d163575Sopenharmony_ci 610d163575Sopenharmony_ci (VOID)memset_s(buf, size, 0, size); 620d163575Sopenharmony_ci g_traceRecoder.head = (OfflineHead *)buf; 630d163575Sopenharmony_ci g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD; 640d163575Sopenharmony_ci g_traceRecoder.head->baseInfo.version = TRACE_VERSION(TRACE_MODE_OFFLINE); 650d163575Sopenharmony_ci g_traceRecoder.head->baseInfo.clockFreq = OS_SYS_CLOCK; 660d163575Sopenharmony_ci g_traceRecoder.head->objSize = sizeof(ObjData); 670d163575Sopenharmony_ci g_traceRecoder.head->frameSize = sizeof(TraceEventFrame); 680d163575Sopenharmony_ci g_traceRecoder.head->objOffset = sizeof(OfflineHead); 690d163575Sopenharmony_ci g_traceRecoder.head->frameOffset = headSize; 700d163575Sopenharmony_ci g_traceRecoder.head->totalLen = size; 710d163575Sopenharmony_ci 720d163575Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 730d163575Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex = 0; 740d163575Sopenharmony_ci g_traceRecoder.ctrl.maxObjCount = LOSCFG_TRACE_OBJ_MAX_NUM; 750d163575Sopenharmony_ci g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame); 760d163575Sopenharmony_ci g_traceRecoder.ctrl.objBuf = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset); 770d163575Sopenharmony_ci g_traceRecoder.ctrl.frameBuf = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset); 780d163575Sopenharmony_ci 790d163575Sopenharmony_ci return LOS_OK; 800d163575Sopenharmony_ci} 810d163575Sopenharmony_ci 820d163575Sopenharmony_ciVOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) 830d163575Sopenharmony_ci{ 840d163575Sopenharmony_ci UINT32 intSave; 850d163575Sopenharmony_ci UINT32 index; 860d163575Sopenharmony_ci ObjData *obj = NULL; 870d163575Sopenharmony_ci 880d163575Sopenharmony_ci TRACE_LOCK(intSave); 890d163575Sopenharmony_ci /* add obj begin */ 900d163575Sopenharmony_ci index = g_traceRecoder.ctrl.curObjIndex; 910d163575Sopenharmony_ci if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */ 920d163575Sopenharmony_ci TRACE_UNLOCK(intSave); 930d163575Sopenharmony_ci return; 940d163575Sopenharmony_ci } 950d163575Sopenharmony_ci obj = &g_traceRecoder.ctrl.objBuf[index]; 960d163575Sopenharmony_ci 970d163575Sopenharmony_ci if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) { 980d163575Sopenharmony_ci g_tidMask[taskId]++; 990d163575Sopenharmony_ci } 1000d163575Sopenharmony_ci 1010d163575Sopenharmony_ci OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId)); 1020d163575Sopenharmony_ci 1030d163575Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex++; 1040d163575Sopenharmony_ci if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) { 1050d163575Sopenharmony_ci g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */ 1060d163575Sopenharmony_ci } 1070d163575Sopenharmony_ci /* add obj end */ 1080d163575Sopenharmony_ci TRACE_UNLOCK(intSave); 1090d163575Sopenharmony_ci} 1100d163575Sopenharmony_ci 1110d163575Sopenharmony_ciVOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) 1120d163575Sopenharmony_ci{ 1130d163575Sopenharmony_ci UINT16 index; 1140d163575Sopenharmony_ci UINT32 intSave; 1150d163575Sopenharmony_ci 1160d163575Sopenharmony_ci TRACE_LOCK(intSave); 1170d163575Sopenharmony_ci index = g_traceRecoder.ctrl.curIndex; 1180d163575Sopenharmony_ci (VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame)); 1190d163575Sopenharmony_ci 1200d163575Sopenharmony_ci g_traceRecoder.ctrl.curIndex++; 1210d163575Sopenharmony_ci if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) { 1220d163575Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 1230d163575Sopenharmony_ci } 1240d163575Sopenharmony_ci TRACE_UNLOCK(intSave); 1250d163575Sopenharmony_ci} 1260d163575Sopenharmony_ci 1270d163575Sopenharmony_ciVOID OsTraceReset(VOID) 1280d163575Sopenharmony_ci{ 1290d163575Sopenharmony_ci UINT32 intSave; 1300d163575Sopenharmony_ci UINT32 bufLen; 1310d163575Sopenharmony_ci 1320d163575Sopenharmony_ci TRACE_LOCK(intSave); 1330d163575Sopenharmony_ci bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount; 1340d163575Sopenharmony_ci (VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen); 1350d163575Sopenharmony_ci g_traceRecoder.ctrl.curIndex = 0; 1360d163575Sopenharmony_ci TRACE_UNLOCK(intSave); 1370d163575Sopenharmony_ci} 1380d163575Sopenharmony_ci 1390d163575Sopenharmony_ciSTATIC VOID OsTraceInfoObj(VOID) 1400d163575Sopenharmony_ci{ 1410d163575Sopenharmony_ci UINT32 i; 1420d163575Sopenharmony_ci ObjData *obj = &g_traceRecoder.ctrl.objBuf[0]; 1430d163575Sopenharmony_ci 1440d163575Sopenharmony_ci if (g_traceRecoder.ctrl.maxObjCount > 0) { 1450d163575Sopenharmony_ci PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex); 1460d163575Sopenharmony_ci PRINTK("Index TaskID TaskPrio TaskName \n"); 1470d163575Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) { 1480d163575Sopenharmony_ci PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name); 1490d163575Sopenharmony_ci } 1500d163575Sopenharmony_ci PRINTK("\n"); 1510d163575Sopenharmony_ci } 1520d163575Sopenharmony_ci} 1530d163575Sopenharmony_ci 1540d163575Sopenharmony_ciSTATIC VOID OsTraceInfoEventTitle(VOID) 1550d163575Sopenharmony_ci{ 1560d163575Sopenharmony_ci PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex); 1570d163575Sopenharmony_ci 1580d163575Sopenharmony_ci PRINTK("Index Time(cycles) EventType CurPid CurTask Identity "); 1590d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_FRAME_CORE_MSG 1600d163575Sopenharmony_ci PRINTK("cpuid hwiActive taskLockCnt "); 1610d163575Sopenharmony_ci#endif 1620d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT 1630d163575Sopenharmony_ci PRINTK("eventCount "); 1640d163575Sopenharmony_ci#endif 1650d163575Sopenharmony_ci#ifdef LOS_TRACE_FRAME_LR 1660d163575Sopenharmony_ci UINT32 i; 1670d163575Sopenharmony_ci PRINTK("backtrace "); 1680d163575Sopenharmony_ci for (i = 0; i < LOS_TRACE_LR_RECORD; i++) { 1690d163575Sopenharmony_ci PRINTK(" "); 1700d163575Sopenharmony_ci } 1710d163575Sopenharmony_ci#endif 1720d163575Sopenharmony_ci if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) { 1730d163575Sopenharmony_ci PRINTK("params "); 1740d163575Sopenharmony_ci } 1750d163575Sopenharmony_ci PRINTK("\n"); 1760d163575Sopenharmony_ci} 1770d163575Sopenharmony_ci 1780d163575Sopenharmony_ciSTATIC VOID OsTraceInfoEventData(VOID) 1790d163575Sopenharmony_ci{ 1800d163575Sopenharmony_ci UINT32 i, j; 1810d163575Sopenharmony_ci TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0]; 1820d163575Sopenharmony_ci 1830d163575Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) { 1840d163575Sopenharmony_ci PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-7x 0x%-11x ", i, frame->curTime, frame->eventType, 1850d163575Sopenharmony_ci frame->curPid, frame->curTask, frame->identity); 1860d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_FRAME_CORE_MSG 1870d163575Sopenharmony_ci UINT32 taskLockCnt = frame->core.taskLockCnt; 1880d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP 1890d163575Sopenharmony_ci /* 1900d163575Sopenharmony_ci * For smp systems, TRACE_LOCK will request taskLock, and this counter 1910d163575Sopenharmony_ci * will increase by 1 in that case. 1920d163575Sopenharmony_ci */ 1930d163575Sopenharmony_ci taskLockCnt -= 1; 1940d163575Sopenharmony_ci#endif 1950d163575Sopenharmony_ci PRINTK("%-11u %-11u %-11u", frame->core.cpuid, frame->core.hwiActive, taskLockCnt); 1960d163575Sopenharmony_ci#endif 1970d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT 1980d163575Sopenharmony_ci PRINTK("%-11u", frame->eventCount); 1990d163575Sopenharmony_ci#endif 2000d163575Sopenharmony_ci#ifdef LOS_TRACE_FRAME_LR 2010d163575Sopenharmony_ci for (j = 0; j < LOS_TRACE_LR_RECORD; j++) { 2020d163575Sopenharmony_ci PRINTK("0x%-11x", frame->linkReg[j]); 2030d163575Sopenharmony_ci } 2040d163575Sopenharmony_ci#endif 2050d163575Sopenharmony_ci for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) { 2060d163575Sopenharmony_ci PRINTK("0x%-11x", frame->params[j]); 2070d163575Sopenharmony_ci } 2080d163575Sopenharmony_ci PRINTK("\n"); 2090d163575Sopenharmony_ci } 2100d163575Sopenharmony_ci} 2110d163575Sopenharmony_ci 2120d163575Sopenharmony_ciSTATIC VOID OsTraceInfoDisplay(VOID) 2130d163575Sopenharmony_ci{ 2140d163575Sopenharmony_ci OfflineHead *head = g_traceRecoder.head; 2150d163575Sopenharmony_ci 2160d163575Sopenharmony_ci PRINTK("*******TraceInfo begin*******\n"); 2170d163575Sopenharmony_ci PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq); 2180d163575Sopenharmony_ci 2190d163575Sopenharmony_ci OsTraceInfoObj(); 2200d163575Sopenharmony_ci 2210d163575Sopenharmony_ci OsTraceInfoEventTitle(); 2220d163575Sopenharmony_ci OsTraceInfoEventData(); 2230d163575Sopenharmony_ci 2240d163575Sopenharmony_ci PRINTK("*******TraceInfo end*******\n"); 2250d163575Sopenharmony_ci} 2260d163575Sopenharmony_ci 2270d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_CLIENT_INTERACT 2280d163575Sopenharmony_ciSTATIC VOID OsTraceSendInfo(VOID) 2290d163575Sopenharmony_ci{ 2300d163575Sopenharmony_ci UINT32 i; 2310d163575Sopenharmony_ci ObjData *obj = NULL; 2320d163575Sopenharmony_ci TraceEventFrame *frame = NULL; 2330d163575Sopenharmony_ci 2340d163575Sopenharmony_ci OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head); 2350d163575Sopenharmony_ci 2360d163575Sopenharmony_ci obj = &g_traceRecoder.ctrl.objBuf[0]; 2370d163575Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) { 2380d163575Sopenharmony_ci OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i)); 2390d163575Sopenharmony_ci } 2400d163575Sopenharmony_ci 2410d163575Sopenharmony_ci frame = &g_traceRecoder.ctrl.frameBuf[0]; 2420d163575Sopenharmony_ci for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) { 2430d163575Sopenharmony_ci OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i)); 2440d163575Sopenharmony_ci } 2450d163575Sopenharmony_ci} 2460d163575Sopenharmony_ci#endif 2470d163575Sopenharmony_ci 2480d163575Sopenharmony_ciVOID OsTraceRecordDump(BOOL toClient) 2490d163575Sopenharmony_ci{ 2500d163575Sopenharmony_ci if (!toClient) { 2510d163575Sopenharmony_ci OsTraceInfoDisplay(); 2520d163575Sopenharmony_ci return; 2530d163575Sopenharmony_ci } 2540d163575Sopenharmony_ci 2550d163575Sopenharmony_ci#ifdef LOSCFG_TRACE_CLIENT_INTERACT 2560d163575Sopenharmony_ci OsTraceSendInfo(); 2570d163575Sopenharmony_ci#endif 2580d163575Sopenharmony_ci} 2590d163575Sopenharmony_ci 2600d163575Sopenharmony_ciOfflineHead *OsTraceRecordGet(VOID) 2610d163575Sopenharmony_ci{ 2620d163575Sopenharmony_ci return g_traceRecoder.head; 2630d163575Sopenharmony_ci} 264