diff --git a/Kconfig b/Kconfig index 2eb6b244..4296a0bb 100644 --- a/Kconfig +++ b/Kconfig @@ -340,6 +340,7 @@ source "drivers/char/mem/Kconfig" source "drivers/char/quickstart/Kconfig" source "drivers/char/random/Kconfig" source "drivers/char/video/Kconfig" +source "drivers/char/trace/Kconfig" source "../../drivers/liteos/tzdriver/Kconfig" source "../../drivers/liteos/hievent/Kconfig" diff --git a/apps/BUILD.gn b/apps/BUILD.gn index 2edc1d0c..6cc40b20 100644 --- a/apps/BUILD.gn +++ b/apps/BUILD.gn @@ -47,4 +47,8 @@ group("apps") { if (defined(LOSCFG_NET_LWIP_SACK_TFTP)) { deps += [ "tftp" ] } + + if (defined(LOSCFG_DRIVERS_TRACE)) { + deps += [ "trace" ] + } } diff --git a/apps/config.mk b/apps/config.mk index 098e352c..bf0c698e 100644 --- a/apps/config.mk +++ b/apps/config.mk @@ -66,6 +66,10 @@ ifeq ($(LOSCFG_NET_LWIP_SACK_TFTP), y) APP_SUBDIRS += tftp endif +ifeq ($(LOSCFG_DRIVERS_TRACE), y) +APP_SUBDIRS += trace +endif + # clear all local variables LOCAL_FLAGS := LOCAL_CFLAGS := diff --git a/apps/trace/BUILD.gn b/apps/trace/BUILD.gn new file mode 100644 index 00000000..d1427f16 --- /dev/null +++ b/apps/trace/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + +import("//kernel/liteos_a/liteos.gni") + +executable("trace") { + sources = [ "src/trace.c" ] +} \ No newline at end of file diff --git a/apps/trace/Makefile b/apps/trace/Makefile new file mode 100644 index 00000000..1c93f79a --- /dev/null +++ b/apps/trace/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := src/trace.c + +include $(APP) \ No newline at end of file diff --git a/apps/trace/src/trace.c b/apps/trace/src/trace.c new file mode 100644 index 00000000..ab307f79 --- /dev/null +++ b/apps/trace/src/trace.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) + +#define TRACE_USR_MAX_PARAMS 3 +typedef struct { + unsigned int eventType; + uintptr_t identity; + uintptr_t params[TRACE_USR_MAX_PARAMS]; +} UsrEventInfo; + +static void TraceUsage(void) +{ + printf("\nUsage: ./trace [start] Start to trace events.\n"); + printf("\nUsage: ./trace [stop] Stop trace.\n"); + printf("\nUsage: ./trace [reset] Clear the trace record buffer.\n"); + printf("\nUsage: ./trace [dump 0/1] Format printf trace data," + "0/1 stands for whether to send data to studio for analysis.\n"); + printf("\nUsage: ./trace [mask num] Set trace filter event mask.\n"); + printf("\nUsage: ./trace [read nBytes] Read nBytes raw data from trace buffer.\n"); + printf("\nUsage: ./trace [write type id params..] Write a user event, no more than 3 parameters.\n"); +} + +static void TraceRead(int fd, size_t size) +{ + ssize_t i; + ssize_t len; + char *buffer = (char *)malloc(size); + if (buffer == NULL) { + printf("Read buffer malloc failed.\n"); + return; + } + + len = read(fd, buffer, size); + for (i = 0; i < len; i++) { + printf("%02x ", buffer[i] & 0xFF); + } + printf("\n"); + free(buffer); +} + +static void TraceWrite(int fd, int argc, char **argv) +{ + int i; + UsrEventInfo info = {0}; + info.eventType = strtoul(argv[2], NULL, 0); + info.identity = strtoul(argv[3], NULL, 0); + int paramNum = (argc - 4) > TRACE_USR_MAX_PARAMS ? TRACE_USR_MAX_PARAMS : (argc - 4); + + for (i = 0; i < paramNum; i++) { + info.params[i] = strtoul(argv[4 + i], NULL, 0); + } + (void)write(fd, &info, sizeof(UsrEventInfo)); +} + +int main(int argc, char **argv) +{ + int fd = open("/dev/trace", O_RDWR); + if (fd == -1) { + printf("Trace open failed.\n"); + exit(EXIT_FAILURE); + } + + if (argc == 1) { + TraceUsage(); + } else if (argc == 2 && strcmp(argv[1], "start") == 0) { + ioctl(fd, TRACE_START, NULL); + } else if (argc == 2 && strcmp(argv[1], "stop") == 0) { + ioctl(fd, TRACE_STOP, NULL); + } else if (argc == 2 && strcmp(argv[1], "reset") == 0) { + ioctl(fd, TRACE_RESET, NULL); + } else if (argc == 3 && strcmp(argv[1], "mask") == 0) { + size_t mask = strtoul(argv[2], NULL, 0); + ioctl(fd, TRACE_SET_MASK, mask); + } else if (argc == 3 && strcmp(argv[1], "dump") == 0) { + size_t flag = strtoul(argv[2], NULL, 0); + ioctl(fd, TRACE_DUMP, flag); + } else if (argc == 3 && strcmp(argv[1], "read") == 0) { + size_t size = strtoul(argv[2], NULL, 0); + TraceRead(fd, size); + } else if (argc >= 4 && strcmp(argv[1], "write") == 0) { + TraceWrite(fd, argc, argv); + } else { + printf("Unsupported trace command.\n"); + TraceUsage(); + } + + close(fd); + return 0; +} diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index 5ad2f836..0fd86da5 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -36,7 +36,7 @@ #include "los_cpup_pri.h" #endif #include "los_sched_pri.h" - +#include "los_hook.h" /* spinlock for hwi module, only available on SMP mode */ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hwiSpin); @@ -84,7 +84,7 @@ VOID OsInterrupt(UINT32 intNum) #ifdef LOSCFG_CPUP_INCLUDE_IRQ OsCpupIrqStart(); #endif - + OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, intNum); hwiForm = (&g_hwiForm[intNum]); #ifndef LOSCFG_NO_SHARED_IRQ while (hwiForm->pstNext != NULL) { @@ -107,6 +107,7 @@ VOID OsInterrupt(UINT32 intNum) #endif ++g_hwiFormCnt[intNum]; + OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, intNum); #ifdef LOSCFG_CPUP_INCLUDE_IRQ OsCpupIrqEnd(intNum); #endif diff --git a/drivers/BUILD.gn b/drivers/BUILD.gn index a4344b9d..b723778b 100644 --- a/drivers/BUILD.gn +++ b/drivers/BUILD.gn @@ -36,6 +36,7 @@ group("drivers") { "char/mem", "char/quickstart", "char/random", + "char/trace", "char/video", "mtd/multi_partition", ] @@ -49,6 +50,7 @@ config("public") { "char/quickstart:public", "char/random:public", "char/video:public", + "char/trace:public", "mtd/multi_partition:public", ] } diff --git a/drivers/char/trace/BUILD.gn b/drivers/char/trace/BUILD.gn new file mode 100644 index 00000000..4411dbe8 --- /dev/null +++ b/drivers/char/trace/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_DRIVERS_TRACE) +module_name = "trace_dev" +kernel_module(module_name) { + sources = [ "src/trace.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/drivers/char/trace/Kconfig b/drivers/char/trace/Kconfig new file mode 100644 index 00000000..70cc87cb --- /dev/null +++ b/drivers/char/trace/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_TRACE + bool "Enable TRACE DRIVER" + default y + depends on DRIVERS && FS_VFS && KERNEL_TRACE + help + Answer Y to enable LiteOS support trace in userspace. \ No newline at end of file diff --git a/drivers/char/trace/Makefile b/drivers/char/trace/Makefile new file mode 100644 index 00000000..a79a9cf3 --- /dev/null +++ b/drivers/char/trace/Makefile @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := trace_dev + +LOCAL_SRCS := $(wildcard src/*.c) + +LOCAL_INCLUDE := -I $(LITEOSTOPDIR)/drivers/char/trace/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) + +include $(MODULE) diff --git a/fs/proc/os_adapt/kernel_trace_proc.c b/drivers/char/trace/include/los_dev_trace.h similarity index 69% rename from fs/proc/os_adapt/kernel_trace_proc.c rename to drivers/char/trace/include/los_dev_trace.h index 16445b81..da9901eb 100644 --- a/fs/proc/os_adapt/kernel_trace_proc.c +++ b/drivers/char/trace/include/los_dev_trace.h @@ -29,40 +29,21 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include "proc_fs.h" +#ifndef __LOS_DEV_TRACE_H__ +#define __LOS_DEV_TRACE_H__ -#ifdef LOSCFG_KERNEL_TRACE -#include "los_trace.h" -static int KernelTraceProcFill(struct SeqBuf *m, void *v) -{ - (void)v; - if (m == NULL) { - return -LOS_EPERM; - } +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ - if (m->buf == NULL) { - m->buf = (char *)LOS_TraceBufDataGet(&(m->size), &(m->count)); - } - return 0; +int DevTraceRegister(void); + +#ifdef __cplusplus +#if __cplusplus } +#endif /* __cplusplus */ +#endif /* __cplusplus */ -static const struct ProcFileOperations KERNEL_TRACE_PROC_FOPS = { - .read = KernelTraceProcFill, -}; #endif - -void ProcKernelTraceInit(void) -{ -#ifdef LOSCFG_KERNEL_TRACE - struct ProcDirEntry *pde = CreateProcEntry("ktrace", 0, NULL); - if (pde == NULL) { - PRINT_ERR("create /proc/ktrace error!\n"); - return; - } - - pde->procFileOps = &KERNEL_TRACE_PROC_FOPS; -#endif -} - diff --git a/drivers/char/trace/src/trace.c b/drivers/char/trace/src/trace.c new file mode 100644 index 00000000..f45e7f3a --- /dev/null +++ b/drivers/char/trace/src/trace.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "fcntl.h" +#include "linux/kernel.h" +#include "sys/ioctl.h" +#include "fs/driver.h" +#include "los_dev_trace.h" +#include "los_trace.h" +#include "los_hook.h" + +#define TRACE_DRIVER "/dev/trace" +#define TRACE_DRIVER_MODE 0666 + +/* trace ioctl */ +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) + +static int TraceOpen(struct file *filep) +{ + return 0; +} + +static int TraceClose(struct file *filep) +{ + return 0; +} + +static ssize_t TraceRead(struct file *filep, char *buffer, size_t buflen) +{ + /* trace record buffer read */ + ssize_t len = buflen; + OfflineHead *records; + int ret; + int realLen; + + if (len % sizeof(unsigned int)) { + PRINT_ERR("Buffer size not aligned by 4 bytes\n"); + return -EINVAL; + } + + records = LOS_TraceRecordGet(); + if (records == NULL) { + PRINT_ERR("Trace read failed, check whether trace mode is set to offline\n"); + return -EINVAL; + } + + realLen = buflen < records->totalLen ? buflen : records->totalLen; + ret = LOS_CopyFromKernel((void *)buffer, buflen, (void *)records, realLen); + if (ret != 0) { + return -EINVAL; + } + + return realLen; +} + +static ssize_t TraceWrite(struct file *filep, const char *buffer, size_t buflen) +{ + /* trace usr event here */ + int ret; + UsrEventInfo *info = NULL; + int infoLen = sizeof(UsrEventInfo); + + if (buflen != infoLen) { + PRINT_ERR("Buffer size not %d bytes\n", infoLen); + return -EINVAL; + } + + info = LOS_MemAlloc(m_aucSysMem0, infoLen); + if (info == NULL) { + return -ENOMEM; + } + memset_s(info, infoLen, 0, infoLen); + + ret = LOS_CopyToKernel(info, infoLen, buffer, buflen); + if (ret != 0) { + LOS_MemFree(m_aucSysMem0, info); + return -EINVAL; + } + OsHookCall(LOS_HOOK_TYPE_USR_EVENT, info, infoLen); + return 0; +} + +static int TraceIoctl(struct file *filep, int cmd, unsigned long arg) +{ + switch (cmd) { + case TRACE_START: + return LOS_TraceStart(); + case TRACE_STOP: + LOS_TraceStop(); + break; + case TRACE_RESET: + LOS_TraceReset(); + break; + case TRACE_DUMP: + LOS_TraceRecordDump((BOOL)arg); + break; + case TRACE_SET_MASK: + LOS_TraceEventMaskSet((UINT32)arg); + break; + default: + PRINT_ERR("Unknown trace ioctl cmd:%d\n", cmd); + return -EINVAL; + } + return 0; +} + +static const struct file_operations_vfs g_traceDevOps = { + TraceOpen, /* open */ + TraceClose, /* close */ + TraceRead, /* read */ + TraceWrite, /* write */ + NULL, /* seek */ + TraceIoctl, /* ioctl */ + NULL, /* mmap */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif + NULL, /* unlink */ +}; + +int DevTraceRegister(void) +{ + return register_driver(TRACE_DRIVER, &g_traceDevOps, TRACE_DRIVER_MODE, 0); /* 0666: file mode */ +} diff --git a/fs/proc/BUILD.gn b/fs/proc/BUILD.gn index 2c133512..d20b5d2e 100644 --- a/fs/proc/BUILD.gn +++ b/fs/proc/BUILD.gn @@ -35,7 +35,6 @@ kernel_module(module_name) { sources = [ "os_adapt/fd_proc.c", "os_adapt/fs_cache_proc.c", - "os_adapt/kernel_trace_proc.c", "os_adapt/mounts_proc.c", "os_adapt/power_proc.c", "os_adapt/proc_init.c", diff --git a/fs/proc/include/internal.h b/fs/proc/include/internal.h index b436cf68..0cf4b35a 100644 --- a/fs/proc/include/internal.h +++ b/fs/proc/include/internal.h @@ -51,8 +51,6 @@ void ProcVmmInit(void); void ProcProcessInit(void); -void ProcKernelTraceInit(void); - int ProcMatch(unsigned int len, const char *name, struct ProcDirEntry *pde); struct ProcDirEntry *ProcFindEntry(const char *path); diff --git a/fs/proc/os_adapt/proc_init.c b/fs/proc/os_adapt/proc_init.c index f44627f8..ec47b295 100644 --- a/fs/proc/os_adapt/proc_init.c +++ b/fs/proc/os_adapt/proc_init.c @@ -63,7 +63,6 @@ void ProcFsInit(void) #endif ProcProcessInit(); ProcUptimeInit(); - ProcKernelTraceInit(); ProcFsCacheInit(); ProcFdInit(); #ifdef LOSCFG_KERNEL_PM diff --git a/kernel/Kconfig b/kernel/Kconfig index 300cbea9..8c3f4cf7 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -110,12 +110,88 @@ config KERNEL_VDSO help If you wish to speed up some system calls. +config KERNEL_HOOK + bool "Enable Hook Feature" + default n + depends on KERNEL_EXTKERNEL && DEBUG_VERSION + config KERNEL_TRACE bool "Enable Trace Feature" default n - depends on KERNEL_EXTKERNEL && DEBUG_VERSION + depends on KERNEL_HOOK + +config TRACE_MSG_EXTEND + bool "Enable Record more extended content" + default n + depends on KERNEL_TRACE + +config TRACE_FRAME_CORE_MSG + bool "Record cpuid, hardware interrupt status, task lock status" + default n + depends on TRACE_MSG_EXTEND + +config TRACE_FRAME_EVENT_COUNT + bool "Record event count, which indicate the sequence of happend events" + default n + depends on TRACE_MSG_EXTEND + +config TRACE_FRAME_MAX_PARAMS + int "Record max params" + default 3 + depends on KERNEL_TRACE help - If you wish to record LiteOS's task and interrupt switch trace. + Make sure the max value is bigger than the number defined by each #MODULE#_#TYPE#_PARMAS in los_trace.h, e.g. TASK_SWITCH_PARAMS + +choice + prompt "Trace work mode" + default RECORDER_MODE_OFFLINE + depends on KERNEL_TRACE + +config RECORDER_MODE_ONLINE + bool "Online mode" + select TRACE_CLIENT_INTERACT + +config RECORDER_MODE_OFFLINE + bool "Offline mode" + +endchoice + +config TRACE_BUFFER_SIZE + int "Trace record buffer size" + default 10000 + +config TRACE_CLIENT_INTERACT + bool "Enable Trace Client Visualization and Control" + default n + depends on KERNEL_TRACE + +choice + prompt "Trace Pipeline for Data Transmission" + depends on TRACE_CLIENT_INTERACT + +config TRACE_PIPELINE_SERIAL + bool "Via Serial" + +endchoice + +choice + prompt "Trace Control" + default TRACE_CONTROL_VIA_SHELL + depends on TRACE_CLIENT_INTERACT + help + If you wish to control Trace's start/stop etc.,dynamically by Trace Client. + +config TRACE_CONTROL_VIA_SHELL + bool "Via Shell" + select LOSCFG_SHELL + +config TRACE_CONTROL_AGENT + bool "Via Trace Agent Task" + +config TRACE_NO_CONTROL + bool "No Control" + +endchoice config KERNEL_SHM bool "Enable Shared Memory" diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 687c79e5..dde50c66 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -36,7 +36,7 @@ #include "los_sched_pri.h" #include "los_sortlink_pri.h" #include "los_task_pri.h" - +#include "los_hook.h" #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE #if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0) @@ -268,7 +268,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) swtmr->startTime = GET_SORTLIST_VALUE(sortList); OsDeleteNodeSortLink(swtmrSortLink, sortList); LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - + + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); OsWakePendTimeSwtmr(cpu, currTime, swtmr); LOS_SpinLock(&cpu->swtmrSortLinkSpin); @@ -362,7 +363,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, swtmr->ucState = OS_SWTMR_STATUS_CREATED; SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); *swtmrID = swtmr->usTimerID; - + OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); return LOS_OK; } @@ -407,6 +408,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) } SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); return ret; } @@ -446,6 +448,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) } SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); return ret; } @@ -526,6 +529,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) } SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr); return ret; } diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index fc02b832..0ff89df5 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -47,6 +47,7 @@ #include "los_vm_map.h" #include "los_vm_syscall.h" #include "los_signal.h" +#include "los_hook.h" #ifdef LOSCFG_KERNEL_CPUP #include "los_cpup_pri.h" @@ -208,10 +209,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID) LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList); } -#ifdef LOSCFG_KERNEL_TRACE - LOS_TraceReg(LOS_TRACE_TASK, OsTaskTrace, LOS_TRACE_TASK_NAME, LOS_TRACE_ENABLE); -#endif - ret = OsSchedInit(); EXIT: @@ -652,6 +649,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S } *taskID = taskCB->taskID; + OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB); return LOS_OK; LOS_ERREND_TCB_INIT: @@ -820,7 +818,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB) } taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; - + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); if (taskCB == OsCurrTaskGet()) { OsSchedResched(); } @@ -990,7 +988,7 @@ LITE_OS_SEC_TEXT UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UIN OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE); return errRet; } - + OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB); if (mode == OS_USER_MODE) { SCHEDULER_UNLOCK(intSave); OsTaskResourcesToFree(taskCB); @@ -1075,13 +1073,14 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) if (!OsPreemptable()) { return LOS_ERRNO_TSK_DELAY_IN_LOCK; } - + OsHookCall(LOS_HOOK_TYPE_TASK_DELAY, tick); if (tick == 0) { return LOS_TaskYield(); } SCHEDULER_LOCK(intSave); OsSchedDelay(runTask, tick); + OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, runTask); SCHEDULER_UNLOCK(intSave); return LOS_OK; diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index e2e33c02..b907004b 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -45,10 +45,6 @@ #include "los_cpup_pri.h" #endif -#ifdef LOSCFG_KERNEL_TRACE -#include "los_trace.h" -#endif - #ifdef __cplusplus #if __cplusplus extern "C" { @@ -505,24 +501,12 @@ STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 tim runTask->waitID = lockID; runTask->waitFlag = mask; (VOID)timeout; -#ifdef LOSCFG_KERNEL_TRACE - UINT16 status = OS_TASK_STATUS_PENDING; - if (timeout != LOS_WAIT_FOREVER) { - status |= OS_TASK_STATUS_PEND_TIME; - } - LOS_Trace(LOS_TRACE_TASK, runTask->taskEntry, status, mask, lockID); -#endif } STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask) { resumeTask->waitID = 0; resumeTask->waitFlag = 0; -#ifdef LOSCFG_KERNEL_TRACE - LosTaskCB *runTask = OsCurrTaskGet(); - LOS_Trace(LOS_TRACE_TASK, resumeTask->taskEntry, (UINT16)OS_TASK_STATUS_READY, - runTask->taskStatus, runTask->taskEntry); -#endif } extern UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB); @@ -559,23 +543,6 @@ extern VOID OsWriteResourceEvent(UINT32 events); extern VOID OsWriteResourceEventUnsafe(UINT32 events); extern UINT32 OsResourceFreeTaskCreate(VOID); -#ifdef LOSCFG_DEBUG_VERSION -STATIC INLINE VOID OsTraceTaskSchedule(LosTaskCB *newTask, LosTaskCB *runTask) -{ - (VOID)newTask; - (VOID)runTask; -#ifdef LOSCFG_KERNEL_TRACE - LOS_Trace(LOS_TRACE_TASK, newTask->taskEntry, (UINT16)OS_TASK_STATUS_RUNNING, - runTask->taskStatus, runTask->taskEntry); -#endif -} - -#else - -#define OsTraceTaskSchedule(newTask, runTask) - -#endif - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/ipc/los_event.c b/kernel/base/ipc/los_event.c index 4b745f88..635283cb 100644 --- a/kernel/base/ipc/los_event.c +++ b/kernel/base/ipc/los_event.c @@ -35,6 +35,7 @@ #include "los_mp.h" #include "los_percpu_pri.h" #include "los_sched_pri.h" +#include "los_hook.h" #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE #include "los_exc.h" #endif @@ -51,6 +52,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) eventCB->uwEventID = 0; LOS_ListInit(&eventCB->stEventList); LOS_IntRestore(intSave); + OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB); return LOS_OK; } @@ -126,6 +128,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM { UINT32 ret = 0; LosTaskCB *runTask = OsCurrTaskGet(); + OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeout); if (once == FALSE) { ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); @@ -193,7 +196,7 @@ LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOO LosTaskCB *resumedTask = NULL; LosTaskCB *nextTask = NULL; BOOL schedFlag = FALSE; - + OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE, eventCB, events); eventCB->uwEventID |= events; if (!LOS_ListEmpty(&eventCB->stEventList)) { for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList); @@ -292,7 +295,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) eventCB->uwEventID = 0; LOS_ListDelInit(&eventCB->stEventList); SCHEDULER_UNLOCK(intSave); - + OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY, eventCB); return LOS_OK; } @@ -303,6 +306,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMa if (eventCB == NULL) { return LOS_ERRNO_EVENT_PTR_NULL; } + OsHookCall(LOS_HOOK_TYPE_EVENT_CLEAR, eventCB, eventMask); SCHEDULER_LOCK(intSave); eventCB->uwEventID &= eventMask; SCHEDULER_UNLOCK(intSave); diff --git a/kernel/base/ipc/los_queue.c b/kernel/base/ipc/los_queue.c index be4d176f..871a1004 100644 --- a/kernel/base/ipc/los_queue.c +++ b/kernel/base/ipc/los_queue.c @@ -36,7 +36,7 @@ #include "los_spinlock.h" #include "los_mp.h" #include "los_percpu_pri.h" - +#include "los_hook.h" #ifdef LOSCFG_BASE_IPC_QUEUE #if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0) @@ -137,6 +137,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 SCHEDULER_UNLOCK(intSave); *queueID = queueCB->queueID; + OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB); return LOS_OK; } @@ -263,6 +264,7 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT UINT32 ret; UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); UINT32 intSave; + OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout); SCHEDULER_LOCK(intSave); queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); @@ -435,7 +437,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) LOS_ListTailInsert(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]); SCHEDULER_UNLOCK(intSave); - + OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB); ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue); return ret; diff --git a/kernel/base/ipc/los_sem.c b/kernel/base/ipc/los_sem.c index a6f10a80..f6633b92 100644 --- a/kernel/base/ipc/los_sem.c +++ b/kernel/base/ipc/los_sem.c @@ -38,7 +38,7 @@ #include "los_spinlock.h" #include "los_mp.h" #include "los_percpu_pri.h" - +#include "los_hook.h" #ifdef LOSCFG_BASE_IPC_SEM @@ -118,7 +118,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 * semCreated->maxSemCount = maxCount; LOS_ListInit(&semCreated->semList); *semHandle = semCreated->semID; - + OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated); OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); return LOS_OK; @@ -165,6 +165,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) semDeleted->semStat = OS_SEM_UNUSED; semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID)); + OsHookCall(LOS_HOOK_TYPE_SEM_DELETE, semDeleted); OsSemDbgUpdateHook(semDeleted->semID, NULL, 0); SCHEDULER_UNLOCK(intSave); @@ -203,12 +204,12 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) retErr = LOS_ERRNO_SEM_INVALID; goto OUT; } - /* Update the operate time, no matter the actual Pend success or not */ OsSemDbgTimeUpdateHook(semHandle); if (semPended->semCount > 0) { semPended->semCount--; + OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); goto OUT; } else if (!timeout) { retErr = LOS_ERRNO_SEM_UNAVAILABLE; @@ -222,6 +223,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) goto OUT; } + OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout); OsTaskWaitSetPendMask(OS_TASK_WAIT_SEM, semPended->semID, timeout); retErr = OsSchedTaskWait(&semPended->semList, timeout, TRUE); if (retErr == LOS_ERRNO_TSK_TIMEOUT) { @@ -259,7 +261,7 @@ LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) } else { semPosted->semCount++; } - + OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask); return LOS_OK; } diff --git a/kernel/base/mem/tlsf/los_memory.c b/kernel/base/mem/tlsf/los_memory.c index 0642a692..d5e5b99a 100644 --- a/kernel/base/mem/tlsf/los_memory.c +++ b/kernel/base/mem/tlsf/los_memory.c @@ -37,11 +37,7 @@ #include "los_vm_boot.h" #include "los_vm_filemap.h" #include "los_task_pri.h" -#ifdef LOSCFG_KERNEL_TRACE -#include "los_trace_frame.h" -#include "los_trace.h" -#endif - +#include "los_hook.h" /* Used to cut non-essential functions. */ #define OS_MEM_FREE_BY_TASKID 0 @@ -865,11 +861,7 @@ UINT32 LOS_MemInit(VOID *pool, UINT32 size) } #endif -#ifdef LOSCFG_KERNEL_TRACE - LOS_TraceReg(LOS_TRACE_MEM_TIME, OsMemTimeTrace, LOS_TRACE_MEM_TIME_NAME, LOS_TRACE_ENABLE); - LOS_TraceReg(LOS_TRACE_MEM_INFO, OsMemInfoTrace, LOS_TRACE_MEM_INFO_NAME, LOS_TRACE_ENABLE); -#endif - + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); return LOS_OK; } @@ -886,11 +878,7 @@ UINT32 LOS_MemDeInit(VOID *pool) OsMemPoolDeinit(pool); -#ifdef LOSCFG_KERNEL_TRACE - LOS_TraceUnreg(LOS_TRACE_MEM_TIME); - LOS_TraceUnreg(LOS_TRACE_MEM_INFO); -#endif - + OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, pool); return LOS_OK; } @@ -958,10 +946,6 @@ retry: VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { -#ifdef LOSCFG_KERNEL_TRACE - UINT64 start = HalClockGetCycles(); -#endif - if ((pool == NULL) || (size == 0)) { return (size > 0) ? OsVmBootMemAlloc(size) : NULL; } @@ -983,28 +967,12 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) MEM_UNLOCK(poolHead, intSave); } while (0); -#ifdef LOSCFG_KERNEL_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_MALLOC, timeUsed); - - LOS_MEM_POOL_STATUS poolStatus = {0}; - (VOID)LOS_MemInfoGet(pool, &poolStatus); - UINT8 fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; /* 100: percent denominator. */ - UINT8 usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); /* 100: percent denominator. */ - LOS_Trace(LOS_TRACE_MEM_INFO, (UINTPTR)pool & MEM_POOL_ADDR_MASK, fragment, usage, poolStatus.totalFreeSize, - poolStatus.maxFreeNodeSize, poolStatus.usedNodeNum, poolStatus.freeNodeNum); -#endif - + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); return ptr; } VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { -#ifdef LOSCFG_KERNEL_TRACE - UINT64 start = HalClockGetCycles(); -#endif - UINT32 gapSize; if ((pool == NULL) || (size == 0) || (boundary == 0) || !OS_MEM_IS_POW_TWO(boundary) || @@ -1053,12 +1021,7 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) ptr = alignedPtr; } while (0); -#ifdef LOSCFG_KERNEL_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_MEMALIGN, timeUsed); -#endif - + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); return ptr; } @@ -1209,14 +1172,11 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { -#ifdef LOSCFG_KERNEL_TRACE - UINT64 start = HalClockGetCycles(); -#endif - if ((pool == NULL) || (ptr == NULL) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *)) || !OS_MEM_IS_ALIGNED(ptr, sizeof(VOID *))) { return LOS_NOK; } + OsHookCall(LOS_HOOK_TYPE_MEM_FREE, pool, ptr); UINT32 ret = LOS_NOK; struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -1245,12 +1205,6 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) MEM_UNLOCK(poolHead, intSave); } while (0); -#ifdef LOSCFG_KERNEL_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_FREE, timeUsed); -#endif - return ret; } @@ -1345,14 +1299,10 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { -#ifdef LOSCFG_KERNEL_TRACE - UINT64 start = HalClockGetCycles(); -#endif - if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { return NULL; } - + OsHookCall(LOS_HOOK_TYPE_MEM_REALLOC, pool, ptr, size); if (size < OS_MEM_MIN_ALLOC_SIZE) { size = OS_MEM_MIN_ALLOC_SIZE; } @@ -1387,12 +1337,6 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) } while (0); MEM_UNLOCK(poolHead, intSave); -#ifdef LOSCFG_KERNEL_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_REALLOC, timeUsed); -#endif - return newPtr; } diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index c3338fb0..dab0291c 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -34,6 +34,7 @@ #include "los_task_pri.h" #include "los_process_pri.h" #include "los_arch_mmu.h" +#include "los_hook.h" #ifdef LOSCFG_KERNEL_CPUP #include "los_cpup_pri.h" #endif @@ -724,6 +725,7 @@ BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priori } taskCB->priority = priority; + OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, taskCB->priority); if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { OsSchedTaskEnQueue(taskCB); return TRUE; @@ -953,8 +955,7 @@ STATIC INLINE VOID OsSchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) #ifdef LOSCFG_BASE_CORE_TSK_MONITOR OsTaskStackCheck(runTask, newTask); #endif /* LOSCFG_BASE_CORE_TSK_MONITOR */ - - OsTraceTaskSchedule(newTask, runTask); + OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); } STATIC INLINE VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB *newProcess) diff --git a/kernel/extended/BUILD.gn b/kernel/extended/BUILD.gn index d171bc1f..2acf20b9 100644 --- a/kernel/extended/BUILD.gn +++ b/kernel/extended/BUILD.gn @@ -38,6 +38,7 @@ group("extended") { "liteipc", "pipes", "power", + "hook", "trace", "vdso", ] @@ -48,7 +49,7 @@ config("public") { "cpup:public", "dynload:public", "vdso:public", - "trace:public", + "hook:public", "liteipc:public", "pipes:public", "hilog:public", diff --git a/kernel/extended/hook/BUILD.gn b/kernel/extended/hook/BUILD.gn new file mode 100644 index 00000000..71a4fa4e --- /dev/null +++ b/kernel/extended/hook/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + +import("//kernel/liteos_a/liteos.gni") + +module_switch = defined(LOSCFG_KERNEL_HOOK) +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_hook.c" ] + + public_configs = [ ":public" ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/kernel/extended/hook/Makefile b/kernel/extended/hook/Makefile new file mode 100644 index 00000000..8d11bbf2 --- /dev/null +++ b/kernel/extended/hook/Makefile @@ -0,0 +1,36 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard *.c) + +include $(MODULE) diff --git a/kernel/extended/hook/include/los_hook_types.h b/kernel/extended/hook/include/los_hook_types.h new file mode 100644 index 00000000..a36a4bb1 --- /dev/null +++ b/kernel/extended/hook/include/los_hook_types.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _LOS_HOOK_TYPES_H +#define _LOS_HOOK_TYPES_H + +#include "los_config.h" +#include "los_event_pri.h" +#include "los_mux_pri.h" +#include "los_queue_pri.h" +#include "los_sem_pri.h" +#include "los_task_pri.h" +#include "los_swtmr_pri.h" +#include "hm_liteipc.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_HOOK +#define LOS_HOOK_ALL_TYPES_DEF \ + /* Hook types supported by memory modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_INIT, (VOID *pool, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_DEINIT, (VOID *pool)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_ALLOC, (VOID *pool, VOID *ptr, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_FREE, (VOID *pool, VOID *ptr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_REALLOC, (VOID *pool, VOID *ptr, UINT32 size)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MEM_ALLOCALIGN, (VOID *pool, VOID *ptr, UINT32 size, UINT32 boundary)) \ + /* Hook types supported by event modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_INIT, (PEVENT_CB_S eventCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_READ, (PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, \ + UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_WRITE, (PEVENT_CB_S eventCB, UINT32 events)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_CLEAR, (PEVENT_CB_S eventCB, UINT32 events)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_EVENT_DESTROY, (PEVENT_CB_S eventCB)) \ + /* Hook types supported by queue modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_CREATE, (const LosQueueCB *queueCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_READ, (const LosQueueCB *queueCB, UINT32 operateType, \ + UINT32 bufferSize, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_WRITE, (const LosQueueCB *queueCB, UINT32 operateType, \ + UINT32 bufferSize, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_QUEUE_DELETE, (const LosQueueCB *queueCB)) \ + /* Hook types supported by semphore modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_CREATE, (const LosSemCB *semCreated)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_POST, (const LosSemCB *semPosted, const LosTaskCB *resumedTask)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_PEND, (const LosSemCB *semPended, const LosTaskCB *runningTask, \ + UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SEM_DELETE, (const LosSemCB *semDeleted)) \ + /* Hook types supported by mutex modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_CREATE, (const LosMux *muxCreated)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_POST, (const LosMux *muxPosted)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_PEND, (const LosMux *muxPended, UINT32 timeout)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MUX_DELETE, (const LosMux *muxDeleted)) \ + /* Hook types supported by task modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_CREATE, (const LosTaskCB *taskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_DELAY, (UINT32 tick)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_PRIMODIFY, (const LosTaskCB *pxTask, UINT32 uxNewPriority)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_DELETE, (const LosTaskCB *taskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_TASK_SWITCHEDIN, (const LosTaskCB *newTask, const LosTaskCB *runTask)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, (const LosTaskCB *pstTaskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, (const LosTaskCB *pstTaskCB)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, (const LosTaskCB *pstTaskCB)) \ + /* Hook types supported by interrupt modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_EXITTOSCHEDULER, (VOID)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_ENTER, (UINT32 hwiIndex)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_ISR_EXIT, (UINT32 hwiIndex)) \ + /* Hook types supported by swtmr modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_CREATE, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_DELETE, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_EXPIRED, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_START, (const SWTMR_CTRL_S *swtmr)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_SWTMR_STOP, (const SWTMR_CTRL_S *swtmr)) \ + /* Hook types supported by liteipc modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_WRITE_DROP, (const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, \ + UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_WRITE, (const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, \ + UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ_DROP, (const IpcMsg *msg, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ, (const IpcMsg *msg, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_TRY_READ, (UINT32 msgType, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, (UINT32 msgType, UINT32 ipcStatus)) \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_IPC_KILL, (UINT32 msgType, UINT32 ipcStatus)) \ + /* Hook types supported by usr modules */ \ + LOS_HOOK_TYPE_DEF(LOS_HOOK_TYPE_USR_EVENT, (VOID *buffer, UINT32 len)) + +/** + * Defines the types of all hooks. + */ +#define LOS_HOOK_TYPE_DEF(type, paramList) type, + +typedef enum { + /* Used to manage hook pools */ + LOS_HOOK_TYPE_START = 0, + /* All supported hook types */ + LOS_HOOK_ALL_TYPES_DEF + /* Used to manage hook pools */ + LOS_HOOK_TYPE_END +} HookType; + +#undef LOS_HOOK_TYPE_DEF + +/** + * Declare the type and interface of the hook functions. + */ +#define LOS_HOOK_TYPE_DEF(type, paramList) \ + typedef VOID (*type##_FN) paramList; \ + extern UINT32 type##_RegHook(type##_FN func); \ + extern UINT32 type##_UnRegHook(type##_FN func); \ + extern VOID type##_CallHook paramList; + +LOS_HOOK_ALL_TYPES_DEF + +#undef LOS_HOOK_TYPE_DEF + +#endif /* LOSCFG_KERNEL_HOOK */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HOOK_TYPES_H */ diff --git a/kernel/extended/hook/include/los_hook_types_parse.h b/kernel/extended/hook/include/los_hook_types_parse.h new file mode 100644 index 00000000..ad082c1b --- /dev/null +++ b/kernel/extended/hook/include/los_hook_types_parse.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _LOS_HOOK_TYPES_PARSE_H +#define _LOS_HOOK_TYPES_PARSE_H + +#define ADDR(a) (&(a)) +#define ARGS(a) (a) +#define ADDRn(...) _CONCAT(ADDR, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define ARGSn(...) _CONCAT(ARGS, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define ARGS0() +#define ADDR0() +#define ARGS1(a) ARGS(a) +#define ADDR1(a) ADDR(a) + +#define ARG_const _ARG_const( +#define _ARG_const(a) ARG_CP_##a) +#define ARG_CP_LosSemCB ADDR( +#define ARG_CP_LosTaskCB ADDR( +#define ARG_CP_UINT32 ADDR( +#define ARG_CP_LosMux ADDR( +#define ARG_CP_LosQueueCB ADDR( +#define ARG_CP_SWTMR_CTRL_S ADDR( +#define ARG_CP_IpcMsg ADDR( +#define ARG_UINT32 ARGS( +#define ARG_PEVENT_CB_S ARGS( +#define ARG_void ADDRn( +#define ARG(a) ARG_##a) + +#define PARAM_TO_ARGS1(a) ARG(a) +#define PARAM_TO_ARGS2(a, b) ARG(a), PARAM_TO_ARGS1(b) +#define PARAM_TO_ARGS3(a, b, c) ARG(a), PARAM_TO_ARGS2(b, c) +#define PARAM_TO_ARGS4(a, b, c, d) ARG(a), PARAM_TO_ARGS3(b, c, d) +#define PARAM_TO_ARGS5(a, b, c, d, e) ARG(a), PARAM_TO_ARGS4(b, c, d, e) +#define PARAM_TO_ARGS6(a, b, c, d, e, f) ARG(a), PARAM_TO_ARGS5(b, c, d, e, f) +#define PARAM_TO_ARGS7(a, b, c, d, e, f, g) ARG(a), PARAM_TO_ARGS6(b, c, d, e, f, g) + +#define _ZERO_ARGS 7, 6, 5, 4, 3, 2, 1, 0 +#define ___NARGS(a, b, c, d, e, f, g, h, n, ...) n +#define __NARGS(...) ___NARGS(__VA_ARGS__) +#define _NARGS(...) __NARGS(x, __VA_ARGS__##_ZERO_ARGS, 7, 6, 5, 4, 3, 2, 1, 0) +#define __CONCAT(a, b) a##b +#define _CONCAT(a, b) __CONCAT(a, b) + +#define PARAM_TO_ARGS(...) _CONCAT(PARAM_TO_ARGS, _NARGS(__VA_ARGS__))(__VA_ARGS__) +#define OS_HOOK_PARAM_TO_ARGS(paramList) (PARAM_TO_ARGS paramList) + +#endif /* _LOS_HOOK_TYPES_PARSE_H */ diff --git a/kernel/extended/hook/los_hook.c b/kernel/extended/hook/los_hook.c new file mode 100644 index 00000000..82d97246 --- /dev/null +++ b/kernel/extended/hook/los_hook.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "los_hook.h" +#include "los_hook_types_parse.h" + +#ifdef LOSCFG_KERNEL_HOOK +#define LOS_HOOK_TYPE_DEF(type, paramList) \ + STATIC type##_FN g_fn##type; \ + UINT32 type##_RegHook(type##_FN func) { \ + if ((func) == NULL) { \ + return LOS_ERRNO_HOOK_REG_INVALID; \ + } \ + if (g_fn##type) { \ + return LOS_ERRNO_HOOK_POOL_IS_FULL; \ + } \ + g_fn##type = (func); \ + return LOS_OK; \ + } \ + UINT32 type##_UnRegHook(type##_FN func) { \ + if (((func) == NULL) || (g_fn##type != (func))) { \ + return LOS_ERRNO_HOOK_UNREG_INVALID; \ + } \ + g_fn##type = NULL; \ + return LOS_OK; \ + } \ + VOID type##_CallHook paramList { \ + if (g_fn##type) { \ + g_fn##type(PARAM_TO_ARGS paramList); \ + } \ + } + +LOS_HOOK_ALL_TYPES_DEF; + +#undef LOS_HOOK_TYPE_DEF + +#endif /* LOSCFG_DEBUG_HOOK */ + diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c index 14ead789..a4a99fbe 100644 --- a/kernel/extended/liteipc/hm_liteipc.c +++ b/kernel/extended/liteipc/hm_liteipc.c @@ -40,14 +40,11 @@ #include "los_sched_pri.h" #include "los_spinlock.h" #include "los_task_pri.h" -#ifdef LOSCFG_KERNEL_TRACE -#include "los_trace.h" -#include "los_trace_frame.h" -#endif #include "los_vm_lock.h" #include "los_vm_map.h" #include "los_vm_page.h" #include "los_vm_phys.h" +#include "los_hook.h" #define USE_TASKID_AS_HANDLE YES #define USE_MMAP YES @@ -93,7 +90,6 @@ STATIC UINT32 LiteIpcWrite(IpcContent *content); STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID); STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback); - STATIC const struct file_operations_vfs g_liteIpcFops = { .open = LiteIpcOpen, /* open */ .close = LiteIpcClose, /* close */ @@ -101,47 +97,6 @@ STATIC const struct file_operations_vfs g_liteIpcFops = { .mmap = LiteIpcMmap, /* mmap */ }; -#ifdef LOSCFG_KERNEL_TRACE -typedef enum { - WRITE, - WRITE_DROP, - TRY_READ, - READ, - READ_DROP, - READ_TIMEOUT, - KILL, - OPERATION_NUM -} IpcOpertion; - -const char *g_operStr[OPERATION_NUM] = {"WRITE", "WRITE_DROP", "TRY_READ", "READ", "READ_DROP", "READ_TIMEOUT"}; -const char *g_msgTypeStr[MT_NUM] = {"REQUEST", "REPLY", "FAILED_REPLY", "DEATH_NOTIFY"}; -const char *g_ipcStatusStr[2] = {"NOT_PEND", "PEND"}; - -LITE_OS_SEC_TEXT STATIC VOID IpcTrace(IpcMsg *msg, UINT32 operation, UINT32 ipcStatus, UINT32 msgType) -{ - UINT32 curTid = LOS_CurTaskIDGet(); - UINT32 curPid = LOS_GetCurrProcessID(); - UINT32 srcTid; - UINT32 srcPid; - UINT32 dstTid; - UINT32 dstPid; - UINT32 ret = (msg == NULL) ? INVAILD_ID : GetTid(msg->target.handle, &dstTid); - if (operation <= WRITE_DROP) { - srcTid = curTid; - srcPid = curPid; - dstTid = ret ? INVAILD_ID : dstTid; - dstPid = ret ? INVAILD_ID : OS_TCB_FROM_TID(dstTid)->processID; - } else { - srcTid = (msg == NULL) ? INVAILD_ID : msg->taskID; - srcPid = (msg == NULL) ? INVAILD_ID : msg->processID; - dstTid = curTid; - dstPid = curPid; - } - UINT8 code = (msg == NULL) ? INVAILD_ID : (UINT8)msg->code; - LOS_Trace(LOS_TRACE_IPC, srcTid, srcPid, dstTid, dstPid, msgType, code, operation, ipcStatus); -} -#endif - LITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID) { UINT32 ret, i; @@ -162,12 +117,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID) for (i = 0; i < LOSCFG_BASE_CORE_PROCESS_LIMIT; i++) { LOS_ListInit(&(g_ipcUsedNodelist[i])); } -#ifdef LOSCFG_KERNEL_TRACE - ret = LOS_TraceReg(LOS_TRACE_IPC, OsIpcTrace, LOS_TRACE_IPC_NAME, LOS_TRACE_ENABLE); - if (ret != LOS_OK) { - PRINT_ERR("liteipc LOS_TraceReg failed:%d\n", ret); - } -#endif + return ret; } @@ -941,9 +891,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid) } #if (USE_TIMESTAMP == YES) if (now > msg->timestamp + LITEIPC_TIMEOUT_NS) { -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(msg, WRITE_DROP, 0, msg->type); +#ifdef LOSCFG_KERNEL_HOOK + ret = GetTid(msg->target.handle, dstTid); + if (ret != LOS_OK) { + *dstTid = INVAILD_ID; + } #endif + OsHookCall(LOS_HOOK_TYPE_IPC_WRITE_DROP, msg, *dstTid, + (*dstTid == INVAILD_ID) ? INVAILD_ID : OS_TCB_FROM_TID(*dstTid)->processID, 0); PRINT_ERR("A timeout reply, request timestamp:%lld, now:%lld\n", msg->timestamp, now); return -ETIME; } @@ -999,9 +954,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content) SCHEDULER_LOCK(intSave); LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid); LOS_ListTailInsert(&(tcb->msgListHead), &(buf->listNode)); -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(&buf->msg, WRITE, tcb->ipcStatus, buf->msg.type); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, tcb->processID, tcb->ipcStatus); if (tcb->ipcStatus & IPC_THREAD_STATUS_PEND) { tcb->ipcStatus &= ~IPC_THREAD_STATUS_PEND; OsTaskWakeClearPendMask(tcb); @@ -1059,15 +1012,11 @@ LITE_OS_SEC_TEXT STATIC UINT32 CheckRecievedMsg(IpcListNode *node, IpcContent *c ret = -EINVAL; } if (ret != LOS_OK) { -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(&node->msg, READ_DROP, tcb->ipcStatus, node->msg.type); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_READ_DROP, &node->msg, tcb->ipcStatus); (VOID)HandleSpecialObjects(LOS_CurTaskIDGet(), node, TRUE); (VOID)LiteIpcNodeFree(LOS_GetCurrProcessID(), (VOID *)node); } else { -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(&node->msg, READ, tcb->ipcStatus, node->msg.type); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_READ, &node->msg, tcb->ipcStatus); } return ret; } @@ -1087,24 +1036,18 @@ LITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content) do { SCHEDULER_LOCK(intSave); if (LOS_ListEmpty(listHead)) { -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(NULL, TRY_READ, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus); tcb->ipcStatus |= IPC_THREAD_STATUS_PEND; OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout); ret = OsSchedTaskWait(&g_ipcPendlist, timeout, TRUE); if (ret == LOS_ERRNO_TSK_TIMEOUT) { -#ifdef LOSCFG_KERNEL_TRACE - IpcTrace(NULL, READ_TIMEOUT, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus); SCHEDULER_UNLOCK(intSave); return -ETIME; } if (OsTaskIsKilled(tcb)) { -#if (LOSCFG_KERNEL_TRACE == YES) - IpcTrace(NULL, KILL, tcb->ipcStatus, syncFlag ? MT_REPLY : MT_REQUEST); -#endif + OsHookCall(LOS_HOOK_TYPE_IPC_KILL, syncFlag ? MT_REPLY : MT_REQUEST, tcb->ipcStatus); SCHEDULER_UNLOCK(intSave); return -ERFKILL; } diff --git a/kernel/extended/trace/BUILD.gn b/kernel/extended/trace/BUILD.gn index ac772b6e..5d1e4dcb 100644 --- a/kernel/extended/trace/BUILD.gn +++ b/kernel/extended/trace/BUILD.gn @@ -34,12 +34,32 @@ module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { sources = [ "los_trace.c", - "los_trace_frame.c", + "cnv/trace_cnv.c", ] - public_configs = [ ":public" ] -} + include_dirs = [ + ".", + "cnv", + "pipeline", + ] -config("public") { - include_dirs = [ "." ] + if (defined(LOSCFG_RECORDER_MODE_OFFLINE)){ + sources += [ "trace_offline.c" ] + } + + if (defined(LOSCFG_RECORDER_MODE_ONLINE)){ + sources += [ "trace_online.c" ] + } + + if (defined(LOSCFG_TRACE_CLIENT_INTERACT)) { + sources += [ + "pipeline/trace_pipeline.c", + "pipeline/trace_tlv.c", + ] + } + + if (defined(LOSCFG_TRACE_PIPELINE_SERIAL)) { + sources += [ "pipeline/serial/trace_pipeline_serial.c" ] + include_dirs += [ "pipeline/serial" ] + } } diff --git a/kernel/extended/trace/Makefile b/kernel/extended/trace/Makefile index c6ceffcd..2fe469d8 100644 --- a/kernel/extended/trace/Makefile +++ b/kernel/extended/trace/Makefile @@ -31,12 +31,32 @@ include $(LITEOSTOPDIR)/config.mk MODULE_NAME := $(notdir $(shell pwd)) -LOCAL_SRCS := $(wildcard *.c) +LOCAL_SRCS := los_trace.c +LOCAL_SRCS += $(wildcard cnv/*.c) LOCAL_INCLUDE := \ - -I $(LITEOSTOPDIR)/kernel/base/include -I $(LITEOSTOPDIR)/kernel/extended/include + -I $(LITEOSTOPDIR)/kernel/extended/trace \ + -I $(LITEOSTOPDIR)/kernel/extended/trace/pipeline \ + -I $(LITEOSTOPDIR)/kernel/extended/trace/cnv -LOCAL_FLAGS := $(LOCAL_INCLUDE) +ifeq ($(LOSCFG_RECORDER_MODE_OFFLINE), y) +LOCAL_SRCS += trace_offline.c +endif + +ifeq ($(LOSCFG_RECORDER_MODE_ONLINE), y) +LOCAL_SRCS += trace_online.c +endif + +ifeq ($(LOSCFG_TRACE_CLIENT_INTERACT), y) +LOCAL_SRCS += $(wildcard pipeline/*.c) +endif + +ifeq ($(LOSCFG_TRACE_PIPELINE_SERIAL), y) +LOCAL_SRCS += $(wildcard pipeline/serial/*.c) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/trace/pipeline/serial +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) include $(MODULE) diff --git a/kernel/extended/trace/cnv/trace_cnv.c b/kernel/extended/trace/cnv/trace_cnv.c new file mode 100644 index 00000000..6d94eeed --- /dev/null +++ b/kernel/extended/trace/cnv/trace_cnv.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "trace_cnv.h" +#include "los_trace.h" +#include "los_task.h" +#include "los_sem.h" +#include "los_mux.h" +#include "los_queue.h" +#include "los_event.h" +#include "los_swtmr.h" +#include "hm_liteipc.h" +#include "los_hook.h" + +STATIC VOID LOS_TraceMemInit(VOID *pool, UINT32 size) +{ + LOS_TRACE(MEM_INFO_REQ, pool); +} + +STATIC VOID LOS_TraceMemAlloc(VOID *pool, VOID *ptr, UINT32 size) +{ + LOS_TRACE(MEM_ALLOC, pool, (UINTPTR)ptr, size); +} + +STATIC VOID LOS_TraceMemFree(VOID *pool, VOID *ptr) +{ + LOS_TRACE(MEM_FREE, pool, (UINTPTR)ptr); +} + +STATIC VOID LOS_TraceMemRealloc(VOID *pool, VOID *ptr, UINT32 size) +{ + LOS_TRACE(MEM_REALLOC, pool, (UINTPTR)ptr, size); +} + +STATIC VOID LOS_TraceMemAllocAlign(VOID *pool, VOID *ptr, UINT32 size, UINT32 boundary) +{ + LOS_TRACE(MEM_ALLOC_ALIGN, pool, (UINTPTR)ptr, size, boundary); +} + +STATIC VOID LOS_TraceEventInit(PEVENT_CB_S eventCB) +{ + LOS_TRACE(EVENT_CREATE, (UINTPTR)eventCB); +} + +STATIC VOID LOS_TraceEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + LOS_TRACE(EVENT_READ, (UINTPTR)eventCB, eventCB->uwEventID, eventMask, mode, timeout); +} + +STATIC VOID LOS_TraceEventWrite(PEVENT_CB_S eventCB, UINT32 events) +{ + LOS_TRACE(EVENT_WRITE, (UINTPTR)eventCB, eventCB->uwEventID, events); +} + +STATIC VOID LOS_TraceEventClear(PEVENT_CB_S eventCB, UINT32 events) +{ + LOS_TRACE(EVENT_CLEAR, (UINTPTR)eventCB, eventCB->uwEventID, events); +} + +STATIC VOID LOS_TraceEventDestroy(PEVENT_CB_S eventCB) +{ + LOS_TRACE(EVENT_DELETE, (UINTPTR)eventCB, LOS_OK); +} + +STATIC VOID LOS_TraceQueueCreate(const LosQueueCB *queueCB) +{ + LOS_TRACE(QUEUE_CREATE, queueCB->queueID, queueCB->queueLen, queueCB->queueSize - sizeof(UINT32), + (UINTPTR)queueCB, 0); +} + +STATIC VOID LOS_TraceQueueRW(const LosQueueCB *queueCB, UINT32 operateType, + UINT32 bufferSize, UINT32 timeout) +{ + LOS_TRACE(QUEUE_RW, queueCB->queueID, queueCB->queueSize, bufferSize, operateType, + queueCB->readWriteableCnt[OS_QUEUE_READ], queueCB->readWriteableCnt[OS_QUEUE_WRITE], timeout); +} + +STATIC VOID LOS_TraceQueueDelete(const LosQueueCB *queueCB) +{ + LOS_TRACE(QUEUE_DELETE, queueCB->queueID, queueCB->queueState, queueCB->readWriteableCnt[OS_QUEUE_READ]); +} + +STATIC VOID LOS_TraceSemCreate(const LosSemCB *semCB) +{ + LOS_TRACE(SEM_CREATE, semCB->semID, 0, semCB->semCount); +} + +STATIC VOID LOS_TraceSemPost(const LosSemCB *semCB, const LosTaskCB *resumedTask) +{ + (VOID)resumedTask; + LOS_TRACE(SEM_POST, semCB->semID, 0, semCB->semCount); +} + +STATIC VOID LOS_TraceSemPend(const LosSemCB *semCB, const LosTaskCB *runningTask, UINT32 timeout) +{ + (VOID)runningTask; + LOS_TRACE(SEM_PEND, semCB->semID, semCB->semCount, timeout); +} + +STATIC VOID LOS_TraceSemDelete(const LosSemCB *semCB) +{ + LOS_TRACE(SEM_DELETE, semCB->semID, LOS_OK); +} + +STATIC VOID LOS_TraceMuxCreate(const LosMux *muxCB) +{ + LOS_TRACE(MUX_CREATE, (UINTPTR)muxCB); +} + +STATIC VOID LOS_TraceMuxPost(const LosMux *muxCB) +{ + LOS_TRACE(MUX_POST, (UINTPTR)muxCB, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID); +} + +STATIC VOID LOS_TraceMuxPend(const LosMux *muxCB, UINT32 timeout) +{ + LOS_TRACE(MUX_PEND, (UINTPTR)muxCB, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID, timeout); +} + +STATIC VOID LOS_TraceMuxDelete(const LosMux *muxCB) +{ + LOS_TRACE(MUX_DELETE, (UINTPTR)muxCB, muxCB->attr.type, muxCB->muxCount, + (muxCB->owner == NULL) ? 0xffffffff : ((LosTaskCB *)muxCB->owner)->taskID); +} + +STATIC VOID LOS_TraceTaskCreate(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_CREATE, taskCB->taskID, taskCB->taskStatus, taskCB->priority); +} + +STATIC VOID LOS_TraceTaskPriModify(const LosTaskCB *taskCB, UINT32 prio) +{ + LOS_TRACE(TASK_PRIOSET, taskCB->taskID, taskCB->taskStatus, taskCB->priority, prio); +} + +STATIC VOID LOS_TraceTaskDelete(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_DELETE, taskCB->taskID, taskCB->taskStatus, (UINTPTR)taskCB->stackPointer); +} + +STATIC VOID LOS_TraceTaskSwitchedIn(const LosTaskCB *newTask, const LosTaskCB *runTask) +{ + LOS_TRACE(TASK_SWITCH, newTask->taskID, runTask->priority, runTask->taskStatus, + newTask->priority, newTask->taskStatus); +} + +STATIC VOID LOS_TraceTaskResume(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_RESUME, taskCB->taskID, taskCB->taskStatus, taskCB->priority); +} + +STATIC VOID LOS_TraceTaskSuspend(const LosTaskCB *taskCB) +{ + LOS_TRACE(TASK_SUSPEND, taskCB->taskID, taskCB->taskStatus,OsCurrTaskGet()->taskID); +} + +STATIC VOID LOS_TraceIsrEnter(UINT32 hwiNum) +{ + LOS_TRACE(HWI_RESPONSE_IN, hwiNum); +} + +STATIC VOID LOS_TraceIsrExit(UINT32 hwiNum) +{ + LOS_TRACE(HWI_RESPONSE_OUT, hwiNum); +} + +STATIC VOID LOS_TraceSwtmrCreate(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_CREATE, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrDelete(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_DELETE, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrExpired(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_EXPIRED, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceSwtmrStart(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_START, swtmr->usTimerID, swtmr->ucMode, swtmr->uwCount, swtmr->uwInterval, 0); +} + +STATIC VOID LOS_TraceSwtmrStop(const SWTMR_CTRL_S *swtmr) +{ + LOS_TRACE(SWTMR_STOP, swtmr->usTimerID); +} + +STATIC VOID LOS_TraceIpcWriteDrop(const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_WRITE_DROP, dstTid, dstPid, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcWrite(const IpcMsg *msg, UINT32 dstTid, UINT32 dstPid, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_WRITE, dstTid, dstPid, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcReadDrop(const IpcMsg *msg, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_DROP, msg->taskID, msg->processID, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcRead(const IpcMsg *msg, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_DROP, msg->taskID, msg->processID, msg->type, msg->code, ipcStatus); +} + +STATIC VOID LOS_TraceIpcTryRead(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_TRY_READ, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceIpcReadTimeout(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_READ_TIMEOUT, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceIpcKill(UINT32 msgType, UINT32 ipcStatus) +{ + LOS_TRACE(IPC_KILL, msgType, ipcStatus); +} + +STATIC VOID LOS_TraceUsrEvent(VOID *buffer, UINT32 len) +{ +#ifdef LOSCFG_DRIVERS_TRACE + UsrEventInfo *info = (UsrEventInfo *)buffer; + if ((info == NULL) || (len != sizeof(UsrEventInfo))) { + return; + } + LOS_TRACE_EASY(info->eventType & (~TRACE_USER_DEFAULT_FLAG), info->identity, info->params[0], info->params[1], + info->params[2]); + LOS_MemFree(m_aucSysMem0, buffer); +#endif +} + +VOID OsTraceCnvInit(VOID) +{ + LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, LOS_TraceMemAlloc); + LOS_HookReg(LOS_HOOK_TYPE_MEM_FREE, LOS_TraceMemFree); + LOS_HookReg(LOS_HOOK_TYPE_MEM_INIT, LOS_TraceMemInit); + LOS_HookReg(LOS_HOOK_TYPE_MEM_REALLOC, LOS_TraceMemRealloc); + LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOCALIGN, LOS_TraceMemAllocAlign); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_INIT, LOS_TraceEventInit); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_READ, LOS_TraceEventRead); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_WRITE, LOS_TraceEventWrite); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_CLEAR, LOS_TraceEventClear); + LOS_HookReg(LOS_HOOK_TYPE_EVENT_DESTROY, LOS_TraceEventDestroy); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_CREATE, LOS_TraceQueueCreate); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_DELETE, LOS_TraceQueueDelete); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_READ, LOS_TraceQueueRW); + LOS_HookReg(LOS_HOOK_TYPE_QUEUE_WRITE, LOS_TraceQueueRW); + LOS_HookReg(LOS_HOOK_TYPE_SEM_CREATE, LOS_TraceSemCreate); + LOS_HookReg(LOS_HOOK_TYPE_SEM_DELETE, LOS_TraceSemDelete); + LOS_HookReg(LOS_HOOK_TYPE_SEM_POST, LOS_TraceSemPost); + LOS_HookReg(LOS_HOOK_TYPE_SEM_PEND, LOS_TraceSemPend); + LOS_HookReg(LOS_HOOK_TYPE_MUX_CREATE, LOS_TraceMuxCreate); + LOS_HookReg(LOS_HOOK_TYPE_MUX_POST, LOS_TraceMuxPost); + LOS_HookReg(LOS_HOOK_TYPE_MUX_PEND, LOS_TraceMuxPend); + LOS_HookReg(LOS_HOOK_TYPE_MUX_DELETE, LOS_TraceMuxDelete); + LOS_HookReg(LOS_HOOK_TYPE_TASK_PRIMODIFY, LOS_TraceTaskPriModify); + LOS_HookReg(LOS_HOOK_TYPE_TASK_DELETE, LOS_TraceTaskDelete); + LOS_HookReg(LOS_HOOK_TYPE_TASK_CREATE, LOS_TraceTaskCreate); + LOS_HookReg(LOS_HOOK_TYPE_TASK_SWITCHEDIN, LOS_TraceTaskSwitchedIn); + LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, LOS_TraceTaskResume); + LOS_HookReg(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, LOS_TraceTaskSuspend); + LOS_HookReg(LOS_HOOK_TYPE_ISR_ENTER, LOS_TraceIsrEnter); + LOS_HookReg(LOS_HOOK_TYPE_ISR_EXIT, LOS_TraceIsrExit); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_CREATE, LOS_TraceSwtmrCreate); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_DELETE, LOS_TraceSwtmrDelete); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_EXPIRED, LOS_TraceSwtmrExpired); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_START, LOS_TraceSwtmrStart); + LOS_HookReg(LOS_HOOK_TYPE_SWTMR_STOP, LOS_TraceSwtmrStop); + LOS_HookReg(LOS_HOOK_TYPE_USR_EVENT, LOS_TraceUsrEvent); + LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE_DROP, LOS_TraceIpcWriteDrop); + LOS_HookReg(LOS_HOOK_TYPE_IPC_WRITE, LOS_TraceIpcWrite); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ_DROP, LOS_TraceIpcReadDrop); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ, LOS_TraceIpcRead); + LOS_HookReg(LOS_HOOK_TYPE_IPC_TRY_READ, LOS_TraceIpcTryRead); + LOS_HookReg(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, LOS_TraceIpcReadTimeout); + LOS_HookReg(LOS_HOOK_TYPE_IPC_KILL, LOS_TraceIpcKill); +} + diff --git a/kernel/extended/trace/cnv/trace_cnv.h b/kernel/extended/trace/cnv/trace_cnv.h new file mode 100644 index 00000000..f9f27b59 --- /dev/null +++ b/kernel/extended/trace/cnv/trace_cnv.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _TRACE_CNV_H +#define _TRACE_CNV_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID OsTraceCnvInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_CNV_H */ diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c index 7a9284a2..4088b0be 100644 --- a/kernel/extended/trace/los_trace.c +++ b/kernel/extended/trace/los_trace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,485 +30,394 @@ */ #include "los_trace_pri.h" -#include "ctype.h" +#include "trace_pipeline.h" +#include "los_memory.h" +#include "los_config.h" #include "securec.h" +#include "trace_cnv.h" #include "los_init.h" -#include "los_task_pri.h" -#include "los_typedef.h" +#include "los_process.h" + +#ifdef LOSCFG_KERNEL_SMP +#include "los_mp.h" +#endif #ifdef LOSCFG_SHELL #include "shcmd.h" #include "shell.h" -#include "stdlib.h" -#include "unistd.h" #endif -#ifndef LOSCFG_KERNEL_TRACE -UINT32 OsTraceInit(VOID) -{ - return LOS_OK; -} +LITE_OS_SEC_BSS STATIC UINT32 g_traceEventCount; +LITE_OS_SEC_BSS STATIC volatile enum TraceState g_traceState = TRACE_UNINIT; +LITE_OS_SEC_DATA_INIT STATIC volatile BOOL g_enableTrace = FALSE; +LITE_OS_SEC_BSS STATIC UINT32 g_traceMask = TRACE_DEFAULT_MASK; -UINT32 LOS_TraceReg(TraceType traceType, WriteHook inHook, const CHAR *typeStr, TraceSwitch onOff) -{ - (VOID)traceType; - (VOID)inHook; - (VOID)onOff; - (VOID)typeStr; - return LOS_OK; -} +TRACE_EVENT_HOOK g_traceEventHook = NULL; +TRACE_DUMP_HOOK g_traceDumpHook = NULL; -UINT32 LOS_TraceUnreg(TraceType traceType) -{ - (VOID)traceType; - return LOS_OK; -} - -VOID LOS_Trace(TraceType traceType, ...) -{ - (VOID)traceType; - return; -} - -VOID LOS_TraceSwitch(TraceSwitch onOff) -{ - (VOID)onOff; -} - -UINT32 LOS_TraceTypeSwitch(TraceType traceType, TraceSwitch onOff) -{ - (VOID)traceType; - (VOID)onOff; - return LOS_OK; -} - -VOID LOS_TracePrint(VOID) -{ - return; -} - -INT32 LOS_Trace2File(const CHAR *filename) -{ - (VOID)filename; - return 0; -} - -UINT8 *LOS_TraceBufDataGet(UINT32 *desLen, UINT32 *relLen) -{ - (VOID)desLen; - (VOID)relLen; - return NULL; -} - -#else - -SPIN_LOCK_INIT(g_traceSpin); -#define TRACE_LOCK(state) LOS_SpinLockSave(&g_traceSpin, &(state)) -#define TRACE_UNLOCK(state) LOS_SpinUnlockRestore(&g_traceSpin, (state)) - -#define TMP_DATALEN 128 - -STATIC UINT8 traceBufArray[LOS_TRACE_BUFFER_SIZE]; -STATIC TraceBufferCtl traceBufCtl; -STATIC TraceHook traceFunc[LOS_TRACE_TYPE_MAX + 1]; - -UINT32 OsTraceInit(VOID) -{ - UINT32 intSave; - - /* Initialize the global variable. */ - (VOID)memset_s((VOID *)traceBufArray, LOS_TRACE_BUFFER_SIZE, 0, LOS_TRACE_BUFFER_SIZE); - (VOID)memset_s(&traceBufCtl, sizeof(traceBufCtl), 0, sizeof(traceBufCtl)); - (VOID)memset_s((VOID *)traceFunc, sizeof(traceFunc), 0, sizeof(traceFunc)); - - TRACE_LOCK(intSave); - - /* Initialize trace contrl. */ - traceBufCtl.bufLen = LOS_TRACE_BUFFER_SIZE; - traceBufCtl.dataBuf = traceBufArray; - traceBufCtl.onOff = LOS_TRACE_ENABLE; - - TRACE_UNLOCK(intSave); - - return LOS_OK; -} - -UINT32 LOS_TraceReg(TraceType traceType, WriteHook inHook, const CHAR *typeStr, TraceSwitch onOff) -{ - UINT32 intSave; - INT32 i; - - if ((traceType < LOS_TRACE_TYPE_MIN) || (traceType > LOS_TRACE_TYPE_MAX)) { - return LOS_ERRNO_TRACE_TYPE_INVALID; - } - - if (inHook == NULL) { - return LOS_ERRNO_TRACE_FUNCTION_NULL; - } - - TRACE_LOCK(intSave); - /* if inputHook is NULL,return failed. */ - if (traceFunc[traceType].inputHook != NULL) { - PRINT_ERR("Registered Failed!\n"); - for (i = 0; i <= LOS_TRACE_TYPE_MAX; i++) { - if (traceFunc[i].inputHook == NULL) { - PRINTK("type:%d ", i); - } - } - PRINTK("could be registered\n"); - TRACE_UNLOCK(intSave); - return LOS_ERRNO_TRACE_TYPE_EXISTED; - } else { - traceFunc[traceType].inputHook = inHook; - traceFunc[traceType].onOff = onOff; - traceFunc[traceType].typeStr = typeStr; - } - TRACE_UNLOCK(intSave); - return LOS_OK; -} - -UINT32 LOS_TraceUnreg(TraceType traceType) -{ - UINT32 intSave; - - if ((traceType < LOS_TRACE_TYPE_MIN) || (traceType > LOS_TRACE_TYPE_MAX)) { - return LOS_ERRNO_TRACE_TYPE_INVALID; - } - - TRACE_LOCK(intSave); - /* if inputHook is NULL,return failed. */ - if (traceFunc[traceType].inputHook == NULL) { - PRINT_ERR("Trace not exist!\n"); - TRACE_UNLOCK(intSave); - return LOS_ERRNO_TRACE_TYPE_NOT_EXISTED; - } else { - traceFunc[traceType].inputHook = NULL; - traceFunc[traceType].onOff = LOS_TRACE_DISABLE; - traceFunc[traceType].typeStr = NULL; - } - TRACE_UNLOCK(intSave); - return LOS_OK; -} - - -VOID LOS_TraceSwitch(TraceSwitch onOff) -{ - traceBufCtl.onOff = onOff; -} - -UINT32 LOS_TraceTypeSwitch(TraceType traceType, TraceSwitch onOff) -{ - UINT32 intSave; - if (traceType < LOS_TRACE_TYPE_MIN || traceType > LOS_TRACE_TYPE_MAX) { - return LOS_ERRNO_TRACE_TYPE_INVALID; - } - TRACE_LOCK(intSave); - if (traceFunc[traceType].inputHook != NULL) { - traceFunc[traceType].onOff = onOff; - TRACE_UNLOCK(intSave); - return LOS_OK; - } - TRACE_UNLOCK(intSave); - return LOS_ERRNO_TRACE_TYPE_NOT_EXISTED; -} - -STATIC UINT32 OsFindReadFrameHead(UINT32 readIndex, UINT32 dataSize) -{ - UINT32 historySize = 0; - UINT32 index = readIndex; - while (historySize < dataSize) { - historySize += ((FrameHead *)&(traceBufCtl.dataBuf[index]))->frameSize; - index = readIndex + historySize; - if (index >= traceBufCtl.bufLen) { - index = index - traceBufCtl.bufLen; - } - } - return index; -} - -STATIC VOID OsAddData2Buf(UINT8 *buf, UINT32 dataSize) -{ - UINT32 intSave; - UINT32 ret; - - TRACE_LOCK(intSave); - - UINT32 desLen = traceBufCtl.bufLen; - UINT32 writeIndex = traceBufCtl.writeIndex; - UINT32 readIndex = traceBufCtl.readIndex; - UINT32 writeRange = writeIndex + dataSize; - UINT8 *des = traceBufCtl.dataBuf + writeIndex; - - /* update readIndex */ - if ((readIndex > writeIndex) && (writeRange > readIndex)) { - traceBufCtl.readIndex = OsFindReadFrameHead(readIndex, writeRange - readIndex); - } else if ((readIndex <= writeIndex) && (writeRange > desLen + readIndex)) { - traceBufCtl.readIndex = OsFindReadFrameHead(readIndex, writeRange - readIndex - desLen); - } - - /* copy the data and update writeIndex */ - UINT32 tmpLen = desLen - writeIndex; - if (tmpLen >= dataSize) { - ret = (UINT32)memcpy_s(des, tmpLen, buf, dataSize); - if (ret != 0) { - goto EXIT; - } - traceBufCtl.writeIndex = writeIndex + dataSize; - } else { - ret = (UINT32)memcpy_s(des, tmpLen, buf, tmpLen); /* tmpLen: The length of ringbuf that can be written */ - if (ret != 0) { - goto EXIT; - } - ret = (UINT32)memcpy_s(traceBufCtl.dataBuf, desLen, buf + tmpLen, dataSize - tmpLen); - if (ret != 0) { - goto EXIT; - } - traceBufCtl.writeIndex = dataSize - tmpLen; - } - -EXIT: - TRACE_UNLOCK(intSave); -} - -VOID LOS_Trace(TraceType traceType, ...) -{ - va_list ap; - if ((traceType > LOS_TRACE_TYPE_MAX) || (traceType < LOS_TRACE_TYPE_MIN) || - (traceFunc[traceType].inputHook == NULL)) { - return; - } - if ((traceBufCtl.onOff == LOS_TRACE_DISABLE) || (traceFunc[traceType].onOff == LOS_TRACE_DISABLE)) { - return; - } - /* Set the trace frame head */ - UINT8 buf[TMP_DATALEN]; - FrameHead *frameHead = (FrameHead *)buf; - frameHead->type = traceType; - frameHead->cpuID = ArchCurrCpuid(); - frameHead->taskID = LOS_CurTaskIDGet(); - frameHead->timestamp = HalClockGetCycles(); - -#ifdef LOSCFG_TRACE_LR - /* Get the linkreg from stack fp and storage to frameHead */ - LOS_RecordLR(frameHead->linkReg, LOSCFG_TRACE_LR_RECORD, LOSCFG_TRACE_LR_RECORD, LOSCFG_TRACE_LR_IGNOR); +#ifdef LOSCFG_TRACE_CONTROL_AGENT +LITE_OS_SEC_BSS STATIC UINT32 g_traceTaskId; #endif - /* Get the trace message */ - va_start(ap, traceType); - INT32 dataSize = (traceFunc[traceType].inputHook)(buf + sizeof(FrameHead), TMP_DATALEN - sizeof(FrameHead), ap); - va_end(ap); - if (dataSize <= 0) { - return; - } - frameHead->frameSize = sizeof(FrameHead) + dataSize; - OsAddData2Buf(buf, frameHead->frameSize); -} +#define EVENT_MASK 0xFFFFFFF0 +#define MIN(x, y) ((x) < (y) ? (x) : (y)) -UINT8 *LOS_TraceBufDataGet(UINT32 *desLen, UINT32 *relLen) +LITE_OS_SEC_BSS STATIC TRACE_HWI_FILTER_HOOK g_traceHwiFliterHook = NULL; + +#ifdef LOSCFG_KERNEL_SMP +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_traceSpin); +#endif + +STATIC_INLINE BOOL OsTraceHwiFilter(UINT32 hwiNum) { - UINT32 traceSwitch = traceBufCtl.onOff; - - if (desLen == NULL || relLen == NULL) { - return NULL; - } - - if (traceSwitch != LOS_TRACE_DISABLE) { - LOS_TraceSwitch(LOS_TRACE_DISABLE); - } - - UINT32 writeIndex = traceBufCtl.writeIndex; - UINT32 readIndex = traceBufCtl.readIndex; - UINT32 srcLen = traceBufCtl.bufLen; - UINT8 *des = (UINT8 *)malloc(srcLen * sizeof(UINT8)); - if (des == NULL) { - *desLen = 0; - *relLen = 0; - if (traceSwitch != LOS_TRACE_DISABLE) { - LOS_TraceSwitch(LOS_TRACE_DISABLE); - } - return NULL; - } - *desLen = LOS_TRACE_BUFFER_SIZE; - if (EOK != memset_s(des, srcLen * sizeof(UINT8), 0, LOS_TRACE_BUFFER_SIZE)) { - *desLen = 0; - *relLen = 0; - free(des); - return NULL; - } - if (writeIndex > readIndex) { - *relLen = readIndex - writeIndex; - (VOID)memcpy_s(des, *desLen, &(traceBufArray[readIndex]), *relLen); - } else { - UINT32 sumLen = srcLen - readIndex; - (VOID)memcpy_s(des, *desLen, &(traceBufArray[readIndex]), sumLen); - (VOID)memcpy_s(&(des[sumLen]), *desLen - sumLen, traceBufArray, writeIndex); - *relLen = sumLen + writeIndex; - } - - if (traceSwitch != LOS_TRACE_DISABLE) { - LOS_TraceSwitch(LOS_TRACE_ENABLE); - } - - return des; -} - -#ifdef LOSCFG_FS_VFS -INT32 LOS_Trace2File(const CHAR *filename) -{ - INT32 ret; - CHAR *fullpath = NULL; - CHAR *shellWorkingDirectory = OsShellGetWorkingDirtectory(); - UINT32 traceSwitch = traceBufCtl.onOff; - - ret = vfs_normalize_path(shellWorkingDirectory, filename, &fullpath); - if (ret != 0) { - return -1; - } - - if (traceSwitch != LOS_TRACE_DISABLE) { - LOS_TraceSwitch(LOS_TRACE_DISABLE); - } - - INT32 fd = open(fullpath, O_CREAT | O_RDWR | O_APPEND, 0644); /* 0644:file right */ - if (fd < 0) { - return -1; - } - - UINT32 writeIndex = traceBufCtl.writeIndex; - UINT32 readIndex = traceBufCtl.readIndex; - - if (writeIndex > readIndex) { - ret = write(fd, &(traceBufArray[readIndex]), writeIndex - readIndex); - } else { - ret = write(fd, &(traceBufArray[readIndex]), traceBufCtl.bufLen - readIndex); - ret += write(fd, traceBufArray, writeIndex); - } - - (VOID)close(fd); - - free(fullpath); - - if (traceSwitch != LOS_TRACE_DISABLE) { - LOS_TraceSwitch(LOS_TRACE_ENABLE); + BOOL ret = ((hwiNum == NUM_HAL_INTERRUPT_UART) || (hwiNum == OS_TICK_INT_NUM)); +#ifdef LOSCFG_KERNEL_SMP + ret |= (hwiNum == LOS_MP_IPI_SCHEDULE); +#endif + if (g_traceHwiFliterHook != NULL) { + ret |= g_traceHwiFliterHook(hwiNum); } return ret; } + +STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR identity, const UINTPTR *params, + UINT16 paramCount) +{ + INT32 i; + UINT32 intSave; + + (VOID)memset_s(frame, sizeof(TraceEventFrame), 0, sizeof(TraceEventFrame)); + + if (paramCount > LOSCFG_TRACE_FRAME_MAX_PARAMS) { + paramCount = LOSCFG_TRACE_FRAME_MAX_PARAMS; + } + + TRACE_LOCK(intSave); + frame->curTask = OsTraceGetMaskTid(LOS_CurTaskIDGet()); + frame->curPid = LOS_GetCurrProcessID(); + frame->identity = identity; + frame->curTime = HalClockGetCycles(); + frame->eventType = eventType; + +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + frame->core.cpuId = ArchCurrCpuid(); + frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE; + frame->core.taskLockCnt = MIN(OsPercpuGet()->taskLockCnt, 0xF); /* taskLockCnt is 4 bits, max vaule = 0xF */ + frame->core.paramCount = paramCount; #endif +#ifdef LOS_TRACE_FRAME_LR + /* Get the linkreg from stack fp and storage to frame */ + LOS_RecordLR(frame->linkReg, LOS_TRACE_LR_RECORD, LOS_TRACE_LR_RECORD, LOS_TRACE_LR_IGNOR); +#endif + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + frame->eventCount = g_traceEventCount; + g_traceEventCount++; +#endif + TRACE_UNLOCK(intSave); + + for (i = 0; i < paramCount; i++) { + frame->params[i] = params[i]; + } +} + +VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb) +{ + errno_t ret; + (VOID)memset_s(obj, sizeof(ObjData), 0, sizeof(ObjData)); + + obj->id = OsTraceGetMaskTid(tcb->taskID); + obj->prio = tcb->priority; + + ret = strncpy_s(obj->name, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE, tcb->taskName, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE - 1); + if (ret != EOK) { + TRACE_ERROR("Task name copy failed!\n"); + } +} + +VOID OsTraceHook(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount) +{ + TraceEventFrame frame; + if ((eventType == TASK_CREATE) || (eventType == TASK_PRIOSET)) { + OsTraceObjAdd(eventType, identity); /* handle important obj info, these can not be filtered */ + } + + if ((g_enableTrace == TRUE) && (eventType & g_traceMask)) { + UINTPTR id = identity; + if (TRACE_GET_MODE_FLAG(eventType) == TRACE_HWI_FLAG) { + if (OsTraceHwiFilter(identity)) { + return; + } + } else if (TRACE_GET_MODE_FLAG(eventType) == TRACE_TASK_FLAG) { + id = OsTraceGetMaskTid(identity); + } else if (eventType == MEM_INFO_REQ) { + LOS_MEM_POOL_STATUS status; + LOS_MemInfoGet((VOID *)identity, &status); + LOS_TRACE(MEM_INFO, identity, status.totalUsedSize, status.totalFreeSize); + return; + } + + OsTraceSetFrame(&frame, eventType, id, params, paramCount); + OsTraceWriteOrSendEvent(&frame); + } +} + +BOOL OsTraceIsEnable(VOID) +{ + return g_enableTrace; +} + +STATIC VOID OsTraceHookInstall(VOID) +{ + g_traceEventHook = OsTraceHook; +#ifdef LOSCFG_RECORDER_MODE_OFFLINE + g_traceDumpHook = OsTraceRecordDump; +#endif +} + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +STATIC BOOL OsTraceCmdIsValid(const TraceClientCmd *msg) +{ + return ((msg->end == TRACE_CMD_END_CHAR) && (msg->cmd < TRACE_CMD_MAX_CODE)); +} + +STATIC VOID OsTraceCmdHandle(const TraceClientCmd *msg) +{ + if (!OsTraceCmdIsValid(msg)) { + return; + } + + switch (msg->cmd) { + case TRACE_CMD_START: + LOS_TraceStart(); + break; + case TRACE_CMD_STOP: + LOS_TraceStop(); + break; + case TRACE_CMD_SET_EVENT_MASK: + /* 4 params(UINT8) composition the mask(UINT32) */ + LOS_TraceEventMaskSet(TRACE_MASK_COMBINE(msg->param1, msg->param2, msg->param3, msg->param4)); + break; + case TRACE_CMD_RECODE_DUMP: + LOS_TraceRecordDump(TRUE); + break; + default: + break; + } +} + +VOID TraceAgent(VOID) +{ + UINT32 ret; + TraceClientCmd msg; + + while (1) { + (VOID)memset_s(&msg, sizeof(TraceClientCmd), 0, sizeof(TraceClientCmd)); + ret = OsTraceDataWait(); + if (ret == LOS_OK) { + OsTraceDataRecv((UINT8 *)&msg, sizeof(TraceClientCmd), 0); + OsTraceCmdHandle(&msg); + } + } +} + +STATIC UINT32 OsCreateTraceAgentTask(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S taskInitParam; + + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TraceAgent; + taskInitParam.usTaskPrio = LOSCFG_TRACE_TASK_PRIORITY; + taskInitParam.pcName = "TraceAgent"; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; +#ifdef LOSCFG_KERNEL_SMP + taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); +#endif + ret = LOS_TaskCreate(&g_traceTaskId, &taskInitParam); + return ret; +} +#endif + +STATIC UINT32 OsTraceInit(VOID) +{ + UINT32 ret; + + if (g_traceState != TRACE_UNINIT) { + TRACE_ERROR("trace has been initialized already, the current state is :%d\n", g_traceState); + ret = LOS_ERRNO_TRACE_ERROR_STATUS; + goto LOS_ERREND; + } + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT + ret = OsTracePipelineInit(); + if (ret != LOS_OK) { + goto LOS_ERREND; + } +#endif + +#ifdef LOSCFG_TRACE_CONTROL_AGENT + ret = OsCreateTraceAgentTask(); + if (ret != LOS_OK) { + TRACE_ERROR("trace init create agentTask error :0x%x\n", ret); + goto LOS_ERREND; + } +#endif + + ret = OsTraceBufInit(LOSCFG_TRACE_BUFFER_SIZE); + if (ret != LOS_OK) { + goto LOS_RELEASE; + } + + OsTraceHookInstall(); + OsTraceCnvInit(); + + g_traceEventCount = 0; + +#ifdef LOSCFG_RECORDER_MODE_ONLINE /* Wait trace client to start trace */ + g_enableTrace = FALSE; + g_traceState = TRACE_INITED; +#else + g_enableTrace = TRUE; + g_traceState = TRACE_STARTED; +#endif + return LOS_OK; +LOS_RELEASE: +#ifdef LOSCFG_TRACE_CONTROL_AGENT + LOS_TaskDelete(g_traceTaskId); +#endif +LOS_ERREND: + return ret; +} + +UINT32 LOS_TraceStart(VOID) +{ + UINT32 intSave; + UINT32 ret = LOS_OK; + + TRACE_LOCK(intSave); + if (g_traceState == TRACE_STARTED) { + goto START_END; + } + + if (g_traceState == TRACE_UNINIT) { + TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); + ret = LOS_ERRNO_TRACE_ERROR_STATUS; + goto START_END; + } + + OsTraceNotifyStart(); + + g_enableTrace = TRUE; + g_traceState = TRACE_STARTED; + + TRACE_UNLOCK(intSave); + LOS_TRACE(MEM_INFO_REQ, m_aucSysMem0); + return ret; +START_END: + TRACE_UNLOCK(intSave); + return ret; +} + +VOID LOS_TraceStop(VOID) +{ + UINT32 intSave; + + TRACE_LOCK(intSave); + if (g_traceState != TRACE_STARTED) { + goto STOP_END; + } + + g_enableTrace = FALSE; + g_traceState = TRACE_STOPED; + OsTraceNotifyStop(); +STOP_END: + TRACE_UNLOCK(intSave); +} + +VOID LOS_TraceEventMaskSet(UINT32 mask) +{ + g_traceMask = mask & EVENT_MASK; +} + +VOID LOS_TraceRecordDump(BOOL toClient) +{ + if (g_traceState != TRACE_STOPED) { + TRACE_ERROR("trace dump must after trace stopped , the current state is : %d\n", g_traceState); + return; + } + OsTraceRecordDump(toClient); +} + +OfflineHead *LOS_TraceRecordGet(VOID) +{ + return OsTraceRecordGet(); +} + +VOID LOS_TraceReset(VOID) +{ + if (g_traceState == TRACE_UNINIT) { + TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); + return; + } + + OsTraceReset(); +} + +VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook) +{ + UINT32 intSave; + + TRACE_LOCK(intSave); + g_traceHwiFliterHook = hook; + TRACE_UNLOCK(intSave); +} + #ifdef LOSCFG_SHELL -UINT32 OsShellCmdTraceNumSwitch(TraceType traceType, const CHAR *onOff) +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceSetMask(INT32 argc, const CHAR **argv) { - UINT32 ret = LOS_NOK; + size_t mask; + CHAR *endPtr = NULL; - if (strcmp("on", onOff) == 0) { - ret = LOS_TraceTypeSwitch(traceType, LOS_TRACE_ENABLE); - if (ret == LOS_OK) { - PRINTK("trace %s on\n", traceFunc[traceType].typeStr); - } else { - PRINTK("trace %d is unregistered\n", traceType); - } - } else if (strcmp("off", onOff) == 0) { - ret = LOS_TraceTypeSwitch(traceType, LOS_TRACE_DISABLE); - if (ret == LOS_OK) { - PRINTK("trace %s off\n", traceFunc[traceType].typeStr); - } else { - PRINTK("trace %d is unregistered\n", traceType); - } + if (argc >= 2) { /* 2:Just as number of parameters */ + PRINTK("\nUsage: trace_mask or trace_mask ID\n"); + return OS_ERROR; + } + + if (argc == 0) { + mask = TRACE_DEFAULT_MASK; } else { - PRINTK("Unknown option: %s\n", onOff); - } - - return ret; -} - -UINT32 OsShellCmdTraceStrSwitch(const CHAR *typeStr, const CHAR *onOff) -{ - UINT32 ret = LOS_NOK; - UINT32 i; - for (i = 0; i <= LOS_TRACE_TYPE_MAX; i++) { - if (traceFunc[i].typeStr != NULL && !strcmp(typeStr, traceFunc[i].typeStr)) { - ret = OsShellCmdTraceNumSwitch(i, onOff); - if (ret != LOS_OK) { - PRINTK("Unknown option: %s\n", onOff); - } - return ret; - } - } - PRINTK("Unknown option: %s\n", typeStr); - return ret; -} - -UINT32 OsShellCmdTraceSwitch(INT32 argc, const CHAR **argv) -{ - UINT32 ret; - if (argc == 1) { - if (strcmp("on", argv[0]) == 0) { - LOS_TraceSwitch(LOS_TRACE_ENABLE); - PRINTK("trace on\n"); - } else if (strcmp("off", argv[0]) == 0) { - LOS_TraceSwitch(LOS_TRACE_DISABLE); - PRINTK("trace off\n"); - } else { - PRINTK("Unknown option: %s\n", argv[0]); - goto TRACE_HELP; - } - } else if (argc == 2) { /* 2:argc number limited */ - if (isdigit(argv[0][0]) != 0) { - CHAR *endPtr = NULL; - UINT32 traceType = strtoul(argv[0], &endPtr, 0); - if ((endPtr == NULL) || (*endPtr != 0)) { - PRINTK("Unknown option: %s\n", argv[0]); - goto TRACE_HELP; - } - ret = OsShellCmdTraceNumSwitch(traceType, argv[1]); - if (ret != LOS_OK) { - goto TRACE_HELP; - } - } else { - ret = OsShellCmdTraceStrSwitch(argv[0], argv[1]); - if (ret != LOS_OK) { - goto TRACE_HELP; - } - } - } else { - PRINTK("Argc is Incorrect!\n"); - goto TRACE_HELP; + mask = strtoul(argv[0], &endPtr, 0); } + LOS_TraceEventMaskSet((UINT32)mask); return LOS_OK; -TRACE_HELP: - PRINTK("Usage:trace [typeNum/typeName] on/off\n"); - PRINTK(" typeNum range: [%d,%d]\n", LOS_TRACE_TYPE_MIN, LOS_TRACE_TYPE_MAX); - return LOS_NOK; } -#ifdef LOSCFG_FS_VFS -UINT32 OsShellCmdTrace2File(INT32 argc, const CHAR **argv) +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceDump(INT32 argc, const CHAR **argv) { - INT32 ret; - if (argc == 1) { - ret = LOS_Trace2File(argv[0]); - if (ret == -1) { - PRINTK("Trace to file failed: %s\n", argv[0]); - } else { - PRINTK("Trace to file successed: %s\n", argv[0]); - } - } else { - PRINTK("Trace to file:wrong argc\n"); - goto TRACE_HELP; - } - return LOS_OK; + BOOL toClient; + CHAR *endPtr = NULL; -TRACE_HELP: - PRINTK("usage:trace2file filename\n"); - return LOS_NOK; + if (argc >= 2) { /* 2:Just as number of parameters */ + PRINTK("\nUsage: trace_dump or trace_dump [1/0]\n"); + return OS_ERROR; + } + + if (argc == 0) { + toClient = FALSE; + } else { + toClient = strtoul(argv[0], &endPtr, 0) != 0 ? TRUE : FALSE; + } + LOS_TraceRecordDump(toClient); + return LOS_OK; } -SHELLCMD_ENTRY(trace2file_shellcmd, CMD_TYPE_EX, "trace2file", 1, (CmdCallBackFunc)OsShellCmdTrace2File); +SHELLCMD_ENTRY(tracestart_shellcmd, CMD_TYPE_EX, "trace_start", 0, (CmdCallBackFunc)LOS_TraceStart); +SHELLCMD_ENTRY(tracestop_shellcmd, CMD_TYPE_EX, "trace_stop", 0, (CmdCallBackFunc)LOS_TraceStop); +SHELLCMD_ENTRY(tracesetmask_shellcmd, CMD_TYPE_EX, "trace_mask", 1, (CmdCallBackFunc)OsShellCmdTraceSetMask); +SHELLCMD_ENTRY(tracereset_shellcmd, CMD_TYPE_EX, "trace_reset", 0, (CmdCallBackFunc)LOS_TraceReset); +SHELLCMD_ENTRY(tracedump_shellcmd, CMD_TYPE_EX, "trace_dump", 1, (CmdCallBackFunc)OsShellCmdTraceDump); #endif -SHELLCMD_ENTRY(trace_shellcmd, CMD_TYPE_EX, "trace", 1, (CmdCallBackFunc)OsShellCmdTraceSwitch); -#endif - -#endif - -LOS_MODULE_INIT(OsTraceInit, LOS_INIT_LEVEL_EARLIEST); +LOS_MODULE_INIT(OsTraceInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/kernel/extended/trace/los_trace_frame.c b/kernel/extended/trace/los_trace_frame.c deleted file mode 100644 index 6fe2f772..00000000 --- a/kernel/extended/trace/los_trace_frame.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "los_trace_frame.h" - - -#ifdef LOSCFG_KERNEL_TRACE - -INT32 OsTaskTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap) -{ - va_list ap2; - va_copy(ap2, ap); - - TaskTraceFrame *x = (TaskTraceFrame *)inputBuffer; - if (sizeof(TaskTraceFrame) > bufLen) { - va_end(ap2); - return 0; - } - - SETPARAM(ap2, x, taskEntry, UINTPTR); - SETPARAM(ap2, x, status, UINT16); - SETPARAM(ap2, x, mask, UINT16); - SETPARAM(ap2, x, ipcId, UINTPTR); - - va_end(ap2); - return sizeof(TaskTraceFrame); -} - -INT32 OsIpcTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap) -{ - va_list ap2; - va_copy(ap2, ap); - - IpcTraceFrame *x = (IpcTraceFrame *)inputBuffer; - if (sizeof(IpcTraceFrame) > bufLen) { - va_end(ap2); - return 0; - } - - SETPARAM(ap2, x, srcTid, UINT32); - SETPARAM(ap2, x, srcPid, UINT32); - SETPARAM(ap2, x, dstTid, UINT32); - SETPARAM(ap2, x, dstPid, UINT32); - SETPARAM(ap2, x, msgType, UINT8); - SETPARAM(ap2, x, code, UINT8); - SETPARAM(ap2, x, operation, UINT8); - SETPARAM(ap2, x, ipcStatus, UINT8); - - va_end(ap2); - return sizeof(IpcTraceFrame); -} - -INT32 OsMemTimeTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap) -{ - va_list ap2; - va_copy(ap2, ap); - - MemTimeTraceFrame *x = (MemTimeTraceFrame *)inputBuffer; - if (sizeof(MemTimeTraceFrame) > bufLen) { - va_end(ap2); - return 0; - } - - SETPARAM(ap2, x, poolAddr, UINT16); - SETPARAM(ap2, x, type, UINT16); - SETPARAM(ap2, x, timeUsed, UINT32); - - va_end(ap2); - return sizeof(MemTimeTraceFrame); -} - -INT32 OsMemInfoTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap) -{ - va_list ap2; - va_copy(ap2, ap); - - MemInfoTraceFrame *x = (MemInfoTraceFrame *)inputBuffer; - if (sizeof(MemInfoTraceFrame) > bufLen) { - va_end(ap2); - return 0; - } - - SETPARAM(ap2, x, poolAddr, UINT16); - SETPARAM(ap2, x, fragment, UINT8); - SETPARAM(ap2, x, usage, UINT8); - SETPARAM(ap2, x, freeTotalSize, UINT32); - SETPARAM(ap2, x, maxFreeSize, UINT32); - SETPARAM(ap2, x, usedNodeNum, UINT16); - SETPARAM(ap2, x, freeNodeNum, UINT16); - - va_end(ap2); - return sizeof(MemInfoTraceFrame); -} -#endif - diff --git a/kernel/extended/trace/los_trace_frame.h b/kernel/extended/trace/los_trace_frame.h deleted file mode 100644 index 5c0d18e4..00000000 --- a/kernel/extended/trace/los_trace_frame.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. - */ -#ifndef _LOS_TRACE_FRAME_H -#define _LOS_TRACE_FRAME_H - -#include "los_typedef.h" -#include "stdarg.h" - -#define LOSCFG_TRACE_LR -#define LOSCFG_TRACE_LR_RECORD 5 -#define LOSCFG_TRACE_LR_IGNOR 0 - -#pragma pack (4) -typedef struct { - UINT16 frameSize; - UINT8 type; - UINT8 cpuID; - INT32 taskID; - UINT64 timestamp; -#ifdef LOSCFG_TRACE_LR - UINTPTR linkReg[LOSCFG_TRACE_LR_RECORD]; -#endif -}FrameHead; -#pragma pack () - -#define SETPARAM(ap, st, member, type) ((st)->member = (type)va_arg((ap), unsigned int)) -#define SETPARAM_LL(ap, st, member, type) ((st)->member = (type)va_arg((ap), unsigned long long)) - -#define LOS_TRACE_TASK 0 -#define LOS_TRACE_TASK_NAME "task" -#define LOS_TRACE_IPC 1 -#define LOS_TRACE_IPC_NAME "liteipc" -#define LOS_TRACE_MEM_TIME 2 -#define LOS_TRACE_MEM_TIME_NAME "mem_time" -#define LOS_TRACE_MEM_INFO 3 -#define LOS_TRACE_MEM_INFO_NAME "mem_info" - -/* task trace frame */ -typedef struct { - UINTPTR taskEntry; - UINT16 status; /**< Task status: - OS_TASK_STATUS_READY - OS_TASK_STATUS_RUNNING - OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME */ - UINT16 mask; /**< Task status Subdivision */ - UINTPTR ipcId; -} TaskTraceFrame; - -/* liteipc trace frame */ -typedef struct { - UINT32 srcTid; - UINT32 srcPid; - UINT32 dstTid; - UINT32 dstPid; - UINT8 msgType; - UINT8 code; - UINT8 operation; - UINT8 ipcStatus; -} IpcTraceFrame; - -#define MEM_POOL_ADDR_MASK 0xffff -#define MEM_TRACE_MALLOC 0 -#define MEM_TRACE_FREE 1 -#define MEM_TRACE_MEMALIGN 2 -#define MEM_TRACE_REALLOC 3 - -#define MEM_TRACE_CYCLE_TO_US(cycles) (UINT32)((UINT64)(cycles) * 1000000 / OS_SYS_CLOCK) /* 1000000: unit is us */ - -/* mem time use trace frame */ -typedef struct { - UINT32 poolAddr : 16; /* Record the low 16 bits of the memory pool address for distinction. */ - UINT32 type : 16; /* 0:malloc, 1: free, 2: memalign, 3: realloc. */ - UINT32 timeUsed; /* Time-consuming for each type of interface about type, uint: us. */ -} MemTimeTraceFrame; - -/* mem pool info trace frame */ -typedef struct { - UINT32 poolAddr : 16; /* Record the low 16 bits of the memory pool address for distinction. */ - UINT32 fragment : 8; /* 100: percent denominator. */ - UINT32 usage : 8; /* Memory pool usage. */ - UINT32 freeTotalSize; /* Total remaining memory. */ - UINT32 maxFreeSize; /* Maximum memory block size. */ - UINT32 usedNodeNum : 16; /* Number of used memory blocks. */ - UINT32 freeNodeNum : 16; /* Number of unused memory blocks. */ -} MemInfoTraceFrame; - -extern INT32 OsTaskTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap); -extern INT32 OsIpcTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap); -extern INT32 OsMemTimeTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap); -extern INT32 OsMemInfoTrace(UINT8 *inputBuffer, UINT32 bufLen, va_list ap); - -#endif diff --git a/kernel/extended/trace/los_trace_pri.h b/kernel/extended/trace/los_trace_pri.h index 585ab11a..95c2fddd 100644 --- a/kernel/extended/trace/los_trace_pri.h +++ b/kernel/extended/trace/los_trace_pri.h @@ -29,12 +29,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LOS_TRACE_PRI_H -#define LOS_TRACE_PRI_H +#ifndef _LOS_TRACE_PRI_H +#define _LOS_TRACE_PRI_H #include "los_trace.h" -#include "los_spinlock.h" -#include "los_seq_buf.h" +#include "los_task_pri.h" #ifdef __cplusplus #if __cplusplus @@ -42,25 +41,113 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -typedef struct { - TraceSwitch onOff; - WriteHook inputHook; - const CHAR *typeStr; -} TraceHook; +#ifdef LOSCFG_TRACE_CONTROL_AGENT +#define TRACE_CMD_END_CHAR 0xD +#endif -/* - * |1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0| - * | | - * readIndex writeIndex +#define TRACE_ERROR PRINT_ERR +#define TRACE_MODE_OFFLINE 0 +#define TRACE_MODE_ONLINE 1 + +/* just task and hwi were traced */ +#define TRACE_DEFAULT_MASK (TRACE_HWI_FLAG | TRACE_TASK_FLAG) +#define TRACE_CTL_MAGIC_NUM 0xDEADBEEF +#define TRACE_BIGLITTLE_WORD 0x12345678 +#define TRACE_VERSION(MODE) (0xFFFFFFFF & (MODE)) +#define TRACE_MASK_COMBINE(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) + +#define TRACE_GET_MODE_FLAG(type) ((type) & 0xFFFFFFF0) + +#ifdef LOSCFG_KERNEL_SMP +extern SPIN_LOCK_S g_traceSpin; +#define TRACE_LOCK(state) LOS_SpinLockSave(&g_traceSpin, &(state)) +#define TRACE_UNLOCK(state) LOS_SpinUnlockRestore(&g_traceSpin, (state)) +#else +#define TRACE_LOCK(state) (state) = LOS_IntLock() +#define TRACE_UNLOCK(state) LOS_IntRestore(state) +#endif + +typedef VOID (*TRACE_DUMP_HOOK)(BOOL toClient); +extern TRACE_DUMP_HOOK g_traceDumpHook; + +enum TraceCmd { + TRACE_CMD_START = 1, + TRACE_CMD_STOP, + TRACE_CMD_SET_EVENT_MASK, + TRACE_CMD_RECODE_DUMP, + TRACE_CMD_MAX_CODE, +}; + +/** + * @ingroup los_trace + * struct to store the trace cmd from traceClient. */ - typedef struct { - UINT8 *dataBuf; - UINT32 bufLen; - TraceSwitch onOff; - UINT32 writeIndex; - UINT32 readIndex; -} TraceBufferCtl; + UINT8 cmd; + UINT8 param1; + UINT8 param2; + UINT8 param3; + UINT8 param4; + UINT8 param5; + UINT8 end; +} TraceClientCmd; + +/** + * @ingroup los_trace + * struct to store the event infomation + */ +typedef struct { + UINT32 cmd; /* trace start or stop cmd */ + UINT32 param; /* magic numb stand for notify msg */ +} TraceNotifyFrame; + +/** + * @ingroup los_trace + * struct to store the trace config information. + */ +typedef struct { + struct WriteCtrl { + UINT16 curIndex; /* The current record index */ + UINT16 maxRecordCount; /* The max num of track items */ + UINT16 curObjIndex; /* The current obj index */ + UINT16 maxObjCount; /* The max num of obj index */ + ObjData *objBuf; /* Pointer to obj info data */ + TraceEventFrame *frameBuf; /* Pointer to the track items */ + } ctrl; + OfflineHead *head; +} TraceOfflineHeaderInfo; + +extern UINT32 OsTraceGetMaskTid(UINT32 taskId); +extern VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb); +extern VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame); +extern UINT32 OsTraceBufInit(UINT32 size); +extern VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId); +extern BOOL OsTraceIsEnable(VOID); +extern OfflineHead *OsTraceRecordGet(VOID); + +#ifdef LOSCFG_RECORDER_MODE_ONLINE +extern VOID OsTraceSendHead(VOID); +extern VOID OsTraceSendObjTable(VOID); +extern VOID OsTraceSendNotify(UINT32 type, UINT32 value); + +#define OsTraceNotifyStart() do { \ + OsTraceSendNotify(SYS_START, TRACE_CTL_MAGIC_NUM); \ + OsTraceSendHead(); \ + OsTraceSendObjTable(); \ + } while (0) + +#define OsTraceNotifyStop() do { \ + OsTraceSendNotify(SYS_STOP, TRACE_CTL_MAGIC_NUM); \ + } while (0) + +#define OsTraceReset() +#define OsTraceRecordDump(toClient) +#else +extern VOID OsTraceReset(VOID); +extern VOID OsTraceRecordDump(BOOL toClient); +#define OsTraceNotifyStart() +#define OsTraceNotifyStop() +#endif #ifdef __cplusplus #if __cplusplus @@ -68,4 +155,4 @@ typedef struct { #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* LOS_TRACE_PRI_H */ +#endif /* _LOS_TRACE_PRI_H */ diff --git a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c b/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c new file mode 100644 index 00000000..766d4127 --- /dev/null +++ b/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "trace_pipeline_serial.h" +#include "trace_pipeline.h" + +#ifdef LOSCFG_TRACE_CONTROL_AGENT +UINT32 SerialPipelineInit(VOID) +{ + return uart_hwiCreate(); +} + +UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + return uart_read(data, size, timeout); +} + +UINT32 SerialWait(VOID) +{ + return uart_wait_adapt(); +} + +#else + +UINT32 SerialPipelineInit(VOID) +{ + return LOS_OK; +} + +UINT32 SerialDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + return LOS_OK; +} + +UINT32 SerialWait(VOID) +{ + return LOS_OK; +} +#endif + +VOID SerialDataSend(UINT16 len, UINT8 *data) +{ + UartPuts((CHAR *)data, len, 1); +} + +STATIC const TracePipelineOps g_serialOps = { + .init = SerialPipelineInit, + .dataSend = SerialDataSend, + .dataRecv = SerialDataReceive, + .wait = SerialWait, +}; + +UINT32 OsTracePipelineInit(VOID) +{ + OsTracePipelineReg(&g_serialOps); + return g_serialOps.init(); +} + diff --git a/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h b/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h new file mode 100644 index 00000000..3f2da50d --- /dev/null +++ b/kernel/extended/trace/pipeline/serial/trace_pipeline_serial.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _TRACE_PIPELINE_SERIAL_H +#define _TRACE_PIPELINE_SERIAL_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_PIPELINE_SERIAL_H */ diff --git a/kernel/extended/trace/pipeline/trace_pipeline.c b/kernel/extended/trace/pipeline/trace_pipeline.c new file mode 100644 index 00000000..b28d97f9 --- /dev/null +++ b/kernel/extended/trace/pipeline/trace_pipeline.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "trace_pipeline.h" +#include "trace_tlv.h" +#include "los_trace_pri.h" + +#ifdef LOSCFG_KERNEL_SMP +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_pipeSpin); +#define PIPE_LOCK(state) LOS_SpinLockSave(&g_pipeSpin, &(state)) +#define PIPE_UNLOCK(state) LOS_SpinUnlockRestore(&g_pipeSpin, (state)) +#else +#define PIPE_LOCK(state) (state) = LOS_IntLock() +#define PIPE_UNLOCK(state) LOS_IntRestore(state) +#endif + +STATIC TlvTable g_traceTlvTblNotify[] = { + { CMD, LOS_OFF_SET_OF(TraceNotifyFrame, cmd), sizeof(UINT32) }, + { PARAMS, LOS_OFF_SET_OF(TraceNotifyFrame, param), sizeof(UINT32) }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblHead[] = { + { ENDIAN, LOS_OFF_SET_OF(TraceBaseHeaderInfo, bigLittleEndian), sizeof(UINT32) }, + { VERSION, LOS_OFF_SET_OF(TraceBaseHeaderInfo, version), sizeof(UINT32) }, + { CLOCK_FREQ, LOS_OFF_SET_OF(TraceBaseHeaderInfo, clockFreq), sizeof(UINT32) }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblObj[] = { + { ADDR, LOS_OFF_SET_OF(ObjData, id), sizeof(UINT32) }, + { PRIO, LOS_OFF_SET_OF(ObjData, prio), sizeof(UINT32) }, + { NAME, LOS_OFF_SET_OF(ObjData, name), sizeof(CHAR) * LOSCFG_TRACE_OBJ_MAX_NAME_SIZE }, + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable g_traceTlvTblEvent[] = { +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + { CORE, LOS_OFF_SET_OF(TraceEventFrame, core), sizeof(UINT32) }, +#endif + { EVENT_CODE, LOS_OFF_SET_OF(TraceEventFrame, eventType), sizeof(UINT32) }, + { CUR_TIME, LOS_OFF_SET_OF(TraceEventFrame, curTime), sizeof(UINT64) }, + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + { EVENT_COUNT, LOS_OFF_SET_OF(TraceEventFrame, eventCount), sizeof(UINT32) }, +#endif + { CUR_TASK, LOS_OFF_SET_OF(TraceEventFrame, curTask), sizeof(UINT32) }, + { IDENTITY, LOS_OFF_SET_OF(TraceEventFrame, identity), sizeof(UINTPTR) }, + { EVENT_PARAMS, LOS_OFF_SET_OF(TraceEventFrame, params), sizeof(UINTPTR) * LOSCFG_TRACE_FRAME_MAX_PARAMS }, + { CUR_PID, LOS_OFF_SET_OF(TraceEventFrame, curPid), sizeof(UINT32) }, +#ifdef LOS_TRACE_FRAME_LR + { EVENT_LR, LOS_OFF_SET_OF(TraceEventFrame, linkReg), sizeof(UINTPTR) * LOS_TRACE_LR_RECORD }, +#endif + { TRACE_TLV_TYPE_NULL, 0, 0 }, +}; + +STATIC TlvTable *g_traceTlvTbl[] = { + g_traceTlvTblNotify, + g_traceTlvTblHead, + g_traceTlvTblObj, + g_traceTlvTblEvent +}; + +STATIC UINT32 DefaultPipelineInit(VOID) +{ + return LOS_OK; +} + +STATIC VOID DefaultDataSend(UINT16 len, UINT8 *data) +{ + (VOID)len; + (VOID)data; +} + +STATIC UINT32 DefaultDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) +{ + (VOID)data; + (VOID)size; + (VOID)timeout; + return LOS_OK; +} + +STATIC UINT32 DefaultWait(VOID) +{ + return LOS_OK; +} + +STATIC TracePipelineOps g_defaultOps = { + .init = DefaultPipelineInit, + .dataSend = DefaultDataSend, + .dataRecv = DefaultDataReceive, + .wait = DefaultWait, +}; + +STATIC const TracePipelineOps *g_tracePipelineOps = &g_defaultOps; + +VOID OsTracePipelineReg(const TracePipelineOps *ops) +{ + g_tracePipelineOps = ops; +} + +VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data) +{ + UINT32 intSave; + UINT8 outBuf[LOSCFG_TRACE_TLV_BUF_SIZE] = {0}; + + if ((type > TRACE_MSG_MAX) || (len > LOSCFG_TRACE_TLV_BUF_SIZE)) { + return; + } + + len = OsTraceDataEncode(type, g_traceTlvTbl[type], data, &outBuf[0], sizeof(outBuf)); + + PIPE_LOCK(intSave); + g_tracePipelineOps->dataSend(len, &outBuf[0]); + PIPE_UNLOCK(intSave); +} + +UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout) +{ + return g_tracePipelineOps->dataRecv(data, size, timeout); +} + +UINT32 OsTraceDataWait(VOID) +{ + return g_tracePipelineOps->wait(); +} diff --git a/kernel/extended/trace/pipeline/trace_pipeline.h b/kernel/extended/trace/pipeline/trace_pipeline.h new file mode 100644 index 00000000..10c02967 --- /dev/null +++ b/kernel/extended/trace/pipeline/trace_pipeline.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _TRACE_PIPELINE_H +#define _TRACE_PIPELINE_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT32 (*init)(VOID); + VOID (*dataSend)(UINT16 len, UINT8 *data); + UINT32 (*dataRecv)(UINT8 *data, UINT32 size, UINT32 timeout); + UINT32 (*wait)(VOID); +} TracePipelineOps; + +/* used as tlv's tag */ +enum TraceMsgType { + NOTIFY, + HEAD, + OBJ, + EVENT, + TRACE_MSG_MAX, +}; + +enum TraceNotifySubType { + CMD = 0x1, + PARAMS, +}; + +enum TraceHeadSubType { + ENDIAN = 0x1, + VERSION, + OBJ_SIZE, + OBJ_COUNT, + CUR_INDEX, + MAX_RECODE, + CUR_OBJ_INDEX, + CLOCK_FREQ, +}; + +enum TraceObjSubType { + ADDR = 0x1, + PRIO, + NAME, +}; + +enum TraceEvtSubType { + CORE = 0x1, + EVENT_CODE, + CUR_TIME, + EVENT_COUNT, + CUR_TASK, + IDENTITY, + EVENT_PARAMS, + CUR_PID, + EVENT_LR, +}; + +extern VOID OsTracePipelineReg(const TracePipelineOps *ops); +extern UINT32 OsTracePipelineInit(VOID); + +extern VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data); +extern UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout); +extern UINT32 OsTraceDataWait(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_PIPELINE_H */ diff --git a/kernel/extended/trace/pipeline/trace_tlv.c b/kernel/extended/trace/pipeline/trace_tlv.c new file mode 100644 index 00000000..3fbc409c --- /dev/null +++ b/kernel/extended/trace/pipeline/trace_tlv.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "trace_tlv.h" +#include "securec.h" + +#define CRC_WIDTH 8 +#define CRC_POLY 0x1021 +#define CRC_TOPBIT 0x8000 + +STATIC UINT16 CalcCrc16(const UINT8 *buf, UINT32 len) +{ + UINT32 i; + UINT16 crc = 0; + + for (; len > 0; len--) { + crc = crc ^ (*buf++ << CRC_WIDTH); + for (i = 0; i < CRC_WIDTH; i++) { + if (crc & CRC_TOPBIT) { + crc = (crc << 1) ^ CRC_POLY; + } else { + crc <<= 1; + } + } + } + return crc; +} + +STATIC UINT32 OsWriteTlv(UINT8 *tlvBuf, UINT8 type, UINT8 len, UINT8 *value) +{ + TraceMsgTlvBody *body = (TraceMsgTlvBody *)tlvBuf; + + if (len == 0) { + return 0; + } + + body->type = type; + body->len = len; + /* Do not check return value for performance, if copy failed, only this package will be discarded */ + (VOID)memcpy_s(body->value, len, value, len); + return len + sizeof(body->type) + sizeof(body->len); +} + +STATIC UINT32 OsTlvEncode(const TlvTable *table, UINT8 *srcBuf, UINT8 *tlvBuf, INT32 tlvBufLen) +{ + UINT32 len = 0; + const TlvTable *tlvTableItem = table; + + while (tlvTableItem->tag != TRACE_TLV_TYPE_NULL) { + if ((len + tlvTableItem->elemSize + sizeof(UINT8) + sizeof(UINT8)) > tlvBufLen) { + break; + } + len += OsWriteTlv(tlvBuf + len, tlvTableItem->tag, tlvTableItem->elemSize, srcBuf + tlvTableItem->elemOffset); + tlvTableItem++; + } + return len; +} + +UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen) +{ + UINT16 crc; + INT32 len; + INT32 tlvBufLen; + UINT8 *tlvBuf = NULL; + + TraceMsgTlvHead *head = (TraceMsgTlvHead *)dest; + tlvBufLen = destLen - sizeof(TraceMsgTlvHead); + + if ((tlvBufLen <= 0) || (table == NULL)) { + return 0; + } + + tlvBuf = dest + sizeof(TraceMsgTlvHead); + len = OsTlvEncode(table, src, tlvBuf, tlvBufLen); + crc = CalcCrc16(tlvBuf, len); + + head->magicNum = TRACE_TLV_MSG_HEAD; + head->msgType = type; + head->len = len; + head->crc = crc; + return len + sizeof(TraceMsgTlvHead); +} diff --git a/kernel/extended/trace/pipeline/trace_tlv.h b/kernel/extended/trace/pipeline/trace_tlv.h new file mode 100644 index 00000000..45d16f93 --- /dev/null +++ b/kernel/extended/trace/pipeline/trace_tlv.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _TRACE_TLV_H +#define _TRACE_TLV_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define TRACE_TLV_MSG_HEAD 0xFF +#define TRACE_TLV_TYPE_NULL 0xFF + +typedef struct { + UINT8 magicNum; + UINT8 msgType; + UINT16 len; + UINT16 crc; +} TraceMsgTlvHead; + +typedef struct { + UINT8 type; + UINT8 len; + UINT8 value[]; +} TraceMsgTlvBody; + +typedef struct { + UINT8 tag; + UINT8 elemOffset; + UINT8 elemSize; +} TlvTable; + +/** + * @ingroup los_trace + * @brief Encode trace raw data. + * + * @par Description: + * This API is used to encode trace raw data to tlv data. + * @attention + *
    + *
  • Encade trace data
  • + *
+ * + * @param type [IN] Type #UINT8. The type stands for different struct of src data. + * @param src [IN] Type #UINT8 *. The raw trace data. + * @param table [IN] Type #const TlvTable *. The tlv table descript elemOffset and elemSize. + * @param dest [OUT] Type #UINT8 *. The tlv data. + * @param destLen [IN] Type #UINT8 *. The tlv buf max len. + + * @retval #0 convert failed. + * @retval #UINT32 convert success bytes. + * + * @par Dependency: + *
  • trace_tlv.h: the header file that contains the API declaration.
+ * @see OsTraceDataEncode + */ +extern UINT32 OsTraceDataEncode(UINT8 type, const TlvTable *table, UINT8 *src, UINT8 *dest, INT32 destLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _TRACE_TLV_H */ diff --git a/kernel/extended/trace/trace_offline.c b/kernel/extended/trace/trace_offline.c new file mode 100644 index 00000000..fe33c032 --- /dev/null +++ b/kernel/extended/trace/trace_offline.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "los_trace_pri.h" +#include "trace_pipeline.h" + +#define BITS_NUM_FOR_TASK_ID 16 + +LITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder; +LITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; + +UINT32 OsTraceGetMaskTid(UINT32 tid) +{ + return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */ +} + +UINT32 OsTraceBufInit(UINT32 size) +{ + UINT32 headSize; + VOID *buf = NULL; + headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM; + if (size <= headSize) { + TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize); + return LOS_ERRNO_TRACE_BUF_TOO_SMALL; + } + + + buf = LOS_MemAlloc(m_aucSysMem0, size); + if (buf == NULL) { + return LOS_ERRNO_TRACE_NO_MEMORY; + } + + (VOID)memset_s(buf, size, 0, size); + g_traceRecoder.head = (OfflineHead *)buf; + g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD; + g_traceRecoder.head->baseInfo.version = TRACE_VERSION(TRACE_MODE_OFFLINE); + g_traceRecoder.head->baseInfo.clockFreq = OS_SYS_CLOCK; + g_traceRecoder.head->objSize = sizeof(ObjData); + g_traceRecoder.head->frameSize = sizeof(TraceEventFrame); + g_traceRecoder.head->objOffset = sizeof(OfflineHead); + g_traceRecoder.head->frameOffset = headSize; + g_traceRecoder.head->totalLen = size; + + g_traceRecoder.ctrl.curIndex = 0; + g_traceRecoder.ctrl.curObjIndex = 0; + g_traceRecoder.ctrl.maxObjCount = LOSCFG_TRACE_OBJ_MAX_NUM; + g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame); + g_traceRecoder.ctrl.objBuf = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset); + g_traceRecoder.ctrl.frameBuf = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset); + + return LOS_OK; +} + +VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) +{ + UINT32 intSave; + UINT32 index; + ObjData *obj = NULL; + + TRACE_LOCK(intSave); + /* add obj begin */ + index = g_traceRecoder.ctrl.curObjIndex; + if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */ + TRACE_UNLOCK(intSave); + return; + } + obj = &g_traceRecoder.ctrl.objBuf[index]; + + if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) { + g_tidMask[taskId]++; + } + + OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId)); + + g_traceRecoder.ctrl.curObjIndex++; + if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) { + g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */ + } + /* add obj end */ + TRACE_UNLOCK(intSave); +} + +VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) +{ + UINT16 index; + UINT32 intSave; + + TRACE_LOCK(intSave); + index = g_traceRecoder.ctrl.curIndex; + (VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame)); + + g_traceRecoder.ctrl.curIndex++; + if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) { + g_traceRecoder.ctrl.curIndex = 0; + } + TRACE_UNLOCK(intSave); +} + +VOID OsTraceReset(VOID) +{ + UINT32 intSave; + UINT32 bufLen; + + TRACE_LOCK(intSave); + bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount; + (VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen); + g_traceRecoder.ctrl.curIndex = 0; + TRACE_UNLOCK(intSave); +} + +STATIC VOID OsTraceInfoObj(VOID) +{ + UINT32 i; + ObjData *obj = &g_traceRecoder.ctrl.objBuf[0]; + + if (g_traceRecoder.ctrl.maxObjCount > 0) { + PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex); + PRINTK("Index TaskID TaskPrio TaskName \n"); + for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) { + PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name); + } + PRINTK("\n"); + } +} + +STATIC VOID OsTraceInfoEventTitle(VOID) +{ + PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex); + + PRINTK("Index Time(cycles) EventType CurPid CurTask Identity "); +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + PRINTK("cpuId hwiActive taskLockCnt "); +#endif +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + PRINTK("eventCount "); +#endif +#ifdef LOS_TRACE_FRAME_LR + UINT32 i; + PRINTK("backtrace "); + for (i = 0; i < LOS_TRACE_LR_RECORD; i++) { + PRINTK(" "); + } +#endif + if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) { + PRINTK("params "); + } + PRINTK("\n"); +} + +STATIC VOID OsTraceInfoEventData(VOID) +{ + UINT32 i, j; + TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0]; + + for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) { + PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-7x 0x%-11x ", i, frame->curTime, frame->eventType, + frame->curPid, frame->curTask, frame->identity); +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + UINT32 taskLockCnt = frame->core.taskLockCnt; +#ifdef LOSCFG_KERNEL_SMP + /* + * For smp systems, TRACE_LOCK will requst taskLock, and this counter + * will increase by 1 in that case. + */ + taskLockCnt -= 1; +#endif + PRINTK("%-11u %-11u %-11u", frame->core.cpuId, frame->core.hwiActive, taskLockCnt); +#endif +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + PRINTK("%-11u", frame->eventCount); +#endif +#ifdef LOS_TRACE_FRAME_LR + for (j = 0; j < LOS_TRACE_LR_RECORD; j++) { + PRINTK("0x%-11x", frame->linkReg[j]); + } +#endif + for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) { + PRINTK("0x%-11x", frame->params[j]); + } + PRINTK("\n"); + } +} + +STATIC VOID OsTraceInfoDisplay(VOID) +{ + OfflineHead *head = g_traceRecoder.head; + + PRINTK("*******TraceInfo begin*******\n"); + PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq); + + OsTraceInfoObj(); + + OsTraceInfoEventTitle(); + OsTraceInfoEventData(); + + PRINTK("*******TraceInfo end*******\n"); +} + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT +STATIC VOID OsTraceSendInfo(VOID) +{ + UINT32 i; + ObjData *obj = NULL; + TraceEventFrame *frame = NULL; + + OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head); + + obj = &g_traceRecoder.ctrl.objBuf[0]; + for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) { + OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i)); + } + + frame = &g_traceRecoder.ctrl.frameBuf[0]; + for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) { + OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i)); + } +} +#endif + +VOID OsTraceRecordDump(BOOL toClient) +{ + if (!toClient) { + OsTraceInfoDisplay(); + return; + } + +#ifdef LOSCFG_TRACE_CLIENT_INTERACT + OsTraceSendInfo(); +#endif +} + +OfflineHead *OsTraceRecordGet(VOID) +{ + return g_traceRecoder.head; +} diff --git a/kernel/extended/trace/trace_online.c b/kernel/extended/trace/trace_online.c new file mode 100644 index 00000000..2e674ef6 --- /dev/null +++ b/kernel/extended/trace/trace_online.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "los_trace_pri.h" +#include "trace_pipeline.h" + +UINT32 OsTraceGetMaskTid(UINT32 taskId) +{ + return taskId; +} + +UINT32 OsTraceBufInit(UINT32 size) +{ + (VOID)size; + return LOS_OK; +} + +VOID OsTraceSendHead(VOID) +{ + TraceBaseHeaderInfo head = { + .bigLittleEndian = TRACE_BIGLITTLE_WORD, + .version = TRACE_VERSION(TRACE_MODE_ONLINE), + .clockFreq = OS_SYS_CLOCK, + }; + + OsTraceDataSend(HEAD, sizeof(TraceBaseHeaderInfo), (UINT8 *)&head); +} + +VOID OsTraceSendNotify(UINT32 type, UINT32 value) +{ + TraceNotifyFrame frame = { + .cmd = type, + .param = value, + }; + + OsTraceDataSend(NOTIFY, sizeof(TraceNotifyFrame), (UINT8 *)&frame); +} + +STATIC VOID OsTraceSendObj(const LosTaskCB *tcb) +{ + ObjData obj; + + OsTraceSetObj(&obj, tcb); + OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)&obj); +} + +VOID OsTraceSendObjTable(VOID) +{ + UINT32 loop; + LosTaskCB *tcb = NULL; + + for (loop = 0; loop < g_taskMaxNum; ++loop) { + tcb = g_taskCBArray + loop; + if (tcb->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + OsTraceSendObj(tcb); + } +} + +VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) +{ + if (OsTraceIsEnable()) { + OsTraceSendObj(OS_TCB_FROM_TID(taskId)); + } +} + +VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame) +{ + OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)frame); +} + +OfflineHead *OsTraceRecordGet(VOID) +{ + return NULL; +} diff --git a/kernel/include/los_err.h b/kernel/include/los_err.h index 612134b9..9d5bf4b7 100644 --- a/kernel/include/los_err.h +++ b/kernel/include/los_err.h @@ -142,6 +142,7 @@ enum LOS_MOUDLE_ID { LOS_MOD_EVENT = 0x1c, LOS_MOD_MUX = 0X1d, LOS_MOD_CPUP = 0x1e, + LOS_MOD_HOOK = 0x1f, LOS_MOD_SHELL = 0x31, LOS_MOD_DRIVER = 0x41, LOS_MOD_BUTT diff --git a/kernel/include/los_hook.h b/kernel/include/los_hook.h new file mode 100644 index 00000000..7df33ca8 --- /dev/null +++ b/kernel/include/los_hook.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ + +#ifndef _LOS_HOOK_H +#define _LOS_HOOK_H + +#include "los_config.h" +#include "los_err.h" +#include "los_errno.h" + +#ifdef LOSCFG_KERNEL_HOOK +#include "los_hook_types.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_HOOK +/** + * @ingroup los_hook + * Hook error code: The hook pool is insufficient. + * + * Value: 0x02001f00 + * + * Solution: Deregister the registered hook. + */ +#define LOS_ERRNO_HOOK_POOL_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x00) + +/** + * @ingroup los_hook + * Hook error code: Invalid parameter. + * + * Value: 0x02001f01 + * + * Solution: Check the input parameters of LOS_HookReg. + */ +#define LOS_ERRNO_HOOK_REG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x01) + +/** + * @ingroup los_hook + * Hook error code: Invalid parameter. + * + * Value: 0x02001f02 + * + * Solution: Check the input parameters of LOS_HookUnReg. + */ +#define LOS_ERRNO_HOOK_UNREG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HOOK, 0x02) + +/** + * @ingroup los_hook + * @brief Registration of hook function. + * + * @par Description: + * This API is used to register hook function. + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param hookType [IN] Register the type of the hook. + * @param hookFn [IN] The function to be registered. + * + * @retval None. + * @par Dependency: + *
  • los_hook.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_HookReg(hookType, hookFn) hookType##_RegHook(hookFn) + +/** + * @ingroup los_hook + * @brief Deregistration of hook function. + * + * @par Description: + * This API is used to deregister hook function. + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param hookType [IN] Deregister the type of the hook. + * @param hookFn [IN] The function to be deregistered. + * + * @retval None. + * @par Dependency: + *
  • los_hook.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_HookUnReg(hookType, hookFn) hookType##_UnRegHook(hookFn) + +/** + * Call hook functions. + */ +#define OsHookCall(hookType, ...) hookType##_CallHook(__VA_ARGS__) + +#else +#define LOS_HookReg(hookType, hookFn) +#define LOS_HookUnReg(hookType, hookFn) +#define OsHookCall(hookType, ...) +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HOOK_H */ diff --git a/kernel/include/los_trace.h b/kernel/include/los_trace.h index b68f627b..f5376c75 100644 --- a/kernel/include/los_trace.h +++ b/kernel/include/los_trace.h @@ -29,10 +29,15 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * @defgroup los_trace Trace + * @ingroup kernel + */ + #ifndef _LOS_TRACE_H #define _LOS_TRACE_H -#include "los_trace_frame.h" +#include "los_task.h" #include "los_base.h" #ifdef __cplusplus @@ -41,171 +46,584 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/* Provide a mechanism for kernel tracking. Record the data to global buffer, - * and you can get the data from /proc/ktrace. - */ +#ifdef LOSCFG_TRACE_CONTROL_AGENT /** * @ingroup los_trace - * Task error code: User type is invalid when register new trace. + * Trace Control agent task's priority. + */ +#define LOSCFG_TRACE_TASK_PRIORITY 2 +#endif + +#define LOSCFG_TRACE_OBJ_MAX_NAME_SIZE LOS_TASK_NAMELEN + +#define LOS_TRACE_LR_RECORD 5 +#define LOS_TRACE_LR_IGNOR 0 +/** + * @ingroup los_trace + * Trace records the max number of objects(kernel object, like tasks), range is [0, LOSCFG_BASE_CORE_TSK_LIMIT]. + * if set to 0, trace will not record any object. + */ +#define LOSCFG_TRACE_OBJ_MAX_NUM 0 + +/** + * @ingroup los_trace + * Trace tlv encode buffer size, the buffer is used to encode one piece raw frame to tlv message in online mode. + */ +#define LOSCFG_TRACE_TLV_BUF_SIZE 100 + +/** + * @ingroup los_trace + * Trace error code: init trace failed. * * Value: 0x02001400 * - * Solution: Use valid type to regeister the new trace. + * Solution: Follow the trace State Machine. */ -#define LOS_ERRNO_TRACE_TYPE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x00) +#define LOS_ERRNO_TRACE_ERROR_STATUS LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x00) /** * @ingroup los_trace - * Task error code: The callback function is null when register new trace. + * Trace error code: Insufficient memory for trace buf init. * * Value: 0x02001401 * - * Solution: Use valid callback function to regeister the new trace. + * Solution: Expand the configured system memory or decrease the value defined by LOS_TRACE_BUFFER_SIZE. */ -#define LOS_ERRNO_TRACE_FUNCTION_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x01) +#define LOS_ERRNO_TRACE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x01) /** * @ingroup los_trace - * Task error code: The type is already registered. + * Trace error code: Insufficient memory for trace struct. * * Value: 0x02001402 * - * Solution: Use valid type to regeister the new trace. + * Solution: Increase trace buffer's size. */ -#define LOS_ERRNO_TRACE_TYPE_EXISTED LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x02) +#define LOS_ERRNO_TRACE_BUF_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x02) /** * @ingroup los_trace - * Task error code: The type is not registered. - * - * Value: 0x02001403 - * - * Solution: Use valid type to regeister the new trace. + * Trace state. */ -#define LOS_ERRNO_TRACE_TYPE_NOT_EXISTED LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x03) - -/** -* @ingroup los_trace -* @brief Define the type of a function used to record trace. -* -* @par Description: -* This API is used to define the type of a recording trace function and call it after task or interrupt switch. -* @attention None. -* -* @param inBuf [IN] Type #UINT8 * The buffer saved trace information. -* @param bufLen [IN] Type #UINT32 The buffer len. -* @param ap [IN] Type #va_list The trace data list. -* -* @retval trace frame length. -* @par Dependency: -*
  • los_trace.h: the header file that contains the API declaration.
-* @see -*/ -typedef INT32 (*WriteHook)(UINT8 *inBuf, UINT32 bufLen, va_list ap); +enum TraceState { + TRACE_UNINIT = 0, /**< trace isn't inited */ + TRACE_INITED, /**< trace is inited but not started yet */ + TRACE_STARTED, /**< trace is started and system is tracing */ + TRACE_STOPED, /**< trace is stopped */ +}; /** * @ingroup los_trace - * Stands for the trace type can be registered. + * Trace mask is used to filter events in runtime. Each mask keep only one unique bit to 1, and user can define own + * module's trace mask. */ typedef enum { - LOS_TRACE_TYPE_MIN = 0, - LOS_TRACE_TYPE_MAX = 15, -} TraceType; + TRACE_SYS_FLAG = 0x10, + TRACE_HWI_FLAG = 0x20, + TRACE_TASK_FLAG = 0x40, + TRACE_SWTMR_FLAG = 0x80, + TRACE_MEM_FLAG = 0x100, + TRACE_QUE_FLAG = 0x200, + TRACE_EVENT_FLAG = 0x400, + TRACE_SEM_FLAG = 0x800, + TRACE_MUX_FLAG = 0x1000, + TRACE_IPC_FLAG = 0x2000, -typedef enum { - LOS_TRACE_DISABLE = 0, - LOS_TRACE_ENABLE = 1, -} TraceSwitch; + TRACE_MAX_FLAG = 0x80000000, + TRACE_USER_DEFAULT_FLAG = 0xFFFFFFF0, +} LOS_TRACE_MASK; /** * @ingroup los_trace - * @brief main trace function is called by user to logger the information. + * Trace event type which indicate the exactly happend events, user can define own module's event type like + * TRACE_#MODULE#_FLAG | NUMBER. + * 28 4 + * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0 + * | | | + * trace_module_flag number + * + */ +typedef enum { + /* 0x10~0x1F */ + SYS_ERROR = TRACE_SYS_FLAG | 0, + SYS_START = TRACE_SYS_FLAG | 1, + SYS_STOP = TRACE_SYS_FLAG | 2, + + /* 0x20~0x2F */ + HWI_CREATE = TRACE_HWI_FLAG | 0, + HWI_CREATE_SHARE = TRACE_HWI_FLAG | 1, + HWI_DELETE = TRACE_HWI_FLAG | 2, + HWI_DELETE_SHARE = TRACE_HWI_FLAG | 3, + HWI_RESPONSE_IN = TRACE_HWI_FLAG | 4, + HWI_RESPONSE_OUT = TRACE_HWI_FLAG | 5, + HWI_ENABLE = TRACE_HWI_FLAG | 6, + HWI_DISABLE = TRACE_HWI_FLAG | 7, + HWI_TRIGGER = TRACE_HWI_FLAG | 8, + HWI_SETPRI = TRACE_HWI_FLAG | 9, + HWI_CLEAR = TRACE_HWI_FLAG | 10, + HWI_SETAFFINITY = TRACE_HWI_FLAG | 11, + HWI_SENDIPI = TRACE_HWI_FLAG | 12, + + /* 0x40~0x4F */ + TASK_CREATE = TRACE_TASK_FLAG | 0, + TASK_PRIOSET = TRACE_TASK_FLAG | 1, + TASK_DELETE = TRACE_TASK_FLAG | 2, + TASK_SUSPEND = TRACE_TASK_FLAG | 3, + TASK_RESUME = TRACE_TASK_FLAG | 4, + TASK_SWITCH = TRACE_TASK_FLAG | 5, + TASK_SIGNAL = TRACE_TASK_FLAG | 6, + + /* 0x80~0x8F */ + SWTMR_CREATE = TRACE_SWTMR_FLAG | 0, + SWTMR_DELETE = TRACE_SWTMR_FLAG | 1, + SWTMR_START = TRACE_SWTMR_FLAG | 2, + SWTMR_STOP = TRACE_SWTMR_FLAG | 3, + SWTMR_EXPIRED = TRACE_SWTMR_FLAG | 4, + + /* 0x100~0x10F */ + MEM_ALLOC = TRACE_MEM_FLAG | 0, + MEM_ALLOC_ALIGN = TRACE_MEM_FLAG | 1, + MEM_REALLOC = TRACE_MEM_FLAG | 2, + MEM_FREE = TRACE_MEM_FLAG | 3, + MEM_INFO_REQ = TRACE_MEM_FLAG | 4, + MEM_INFO = TRACE_MEM_FLAG | 5, + + /* 0x200~0x20F */ + QUEUE_CREATE = TRACE_QUE_FLAG | 0, + QUEUE_DELETE = TRACE_QUE_FLAG | 1, + QUEUE_RW = TRACE_QUE_FLAG | 2, + + /* 0x400~0x40F */ + EVENT_CREATE = TRACE_EVENT_FLAG | 0, + EVENT_DELETE = TRACE_EVENT_FLAG | 1, + EVENT_READ = TRACE_EVENT_FLAG | 2, + EVENT_WRITE = TRACE_EVENT_FLAG | 3, + EVENT_CLEAR = TRACE_EVENT_FLAG | 4, + + /* 0x800~0x80F */ + SEM_CREATE = TRACE_SEM_FLAG | 0, + SEM_DELETE = TRACE_SEM_FLAG | 1, + SEM_PEND = TRACE_SEM_FLAG | 2, + SEM_POST = TRACE_SEM_FLAG | 3, + + /* 0x1000~0x100F */ + MUX_CREATE = TRACE_MUX_FLAG | 0, + MUX_DELETE = TRACE_MUX_FLAG | 1, + MUX_PEND = TRACE_MUX_FLAG | 2, + MUX_POST = TRACE_MUX_FLAG | 3, + + /* 0x2000~0x200F */ + IPC_WRITE_DROP = TRACE_IPC_FLAG | 0, + IPC_WRITE = TRACE_IPC_FLAG | 1, + IPC_READ_DROP = TRACE_IPC_FLAG | 2, + IPC_READ = TRACE_IPC_FLAG | 3, + IPC_TRY_READ = TRACE_IPC_FLAG | 4, + IPC_READ_TIMEOUT = TRACE_IPC_FLAG | 5, + IPC_KILL = TRACE_IPC_FLAG | 6, +} LOS_TRACE_TYPE; + +/** + * @ingroup los_trace + * struct to store the trace config information. + */ +typedef struct { + UINT32 bigLittleEndian; /**< big little endian flag */ + UINT32 clockFreq; /**< system clock frequency */ + UINT32 version; /**< trace version */ +} TraceBaseHeaderInfo; + +/** + * @ingroup los_trace + * struct to store the event infomation + */ +typedef struct { + UINT32 eventType; /**< event type */ + UINT32 curTask; /**< current running task */ + UINT32 curPid; /**< current running processID */ + UINT64 curTime; /**< current timestamp */ + UINTPTR identity; /**< subject of the event description */ +#ifdef LOSCFG_TRACE_FRAME_CORE_MSG + struct CoreStatus { + UINT32 cpuId : 8, /**< cpuid */ + hwiActive : 4, /**< whether is in hwi response */ + taskLockCnt : 4, /**< task lock count */ + paramCount : 4, /**< event frame params' number */ + reserves : 12; /**< reserves */ + } core; +#endif + +#ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT + UINT32 eventCount; /**< the sequence of happend events */ +#endif + +#ifdef LOS_TRACE_FRAME_LR + UINTPTR linkReg[LOS_TRACE_LR_RECORD]; +#endif + +#ifdef LOSCFG_TRACE_FRAME_MAX_PARAMS + UINTPTR params[LOSCFG_TRACE_FRAME_MAX_PARAMS]; /**< event frame's params */ +#endif +} TraceEventFrame; + +#ifdef LOSCFG_DRIVERS_TRACE +typedef struct { + UINT32 eventType; + UINTPTR identity; + UINTPTR params[3]; +} UsrEventInfo; +#endif + +/** + * @ingroup los_trace + * struct to store the kernel obj information, we defined task as kernel obj in this system. + */ +typedef struct { + UINT32 id; /**< kernel obj's id */ + UINT32 prio; /**< kernel obj's priority */ + CHAR name[LOSCFG_TRACE_OBJ_MAX_NAME_SIZE]; /**< kernel obj's name */ +} ObjData; + +/** + * @ingroup los_trace + * struct to store the trace data. + */ +typedef struct { + TraceBaseHeaderInfo baseInfo; /**< basic info, include bigLittleEndian flag, system clock freq */ + UINT16 totalLen; /**< trace data's total length */ + UINT16 objSize; /**< sizeof #ObjData */ + UINT16 frameSize; /**< sizeof #TraceEventFrame */ + UINT16 objOffset; /**< the offset of the first obj data to record beginning */ + UINT16 frameOffset; /**< the offset of the first event frame data to record beginning */ +} OfflineHead; + +/** + * @ingroup los_trace + * @brief Define the type of trace hardware interrupt filter hook function. * * @par Description: - * This API is used to trace the infomation. + * User can register fliter function by LOS_TraceHwiFilterHookReg to filter hardware interrupt events. Return true if + * user don't need trace the certain number. + * + * @attention + * None. + * + * @param hwiNum [IN] Type #UINT32. The hardware interrupt number. + * @retval #TRUE 0x00000001: Not record the certain number. + * @retval #FALSE 0x00000000: Need record the certain number. + * + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ */ +typedef BOOL (*TRACE_HWI_FILTER_HOOK)(UINT32 hwiNum); + +typedef VOID (*TRACE_EVENT_HOOK)(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount); +extern TRACE_EVENT_HOOK g_traceEventHook; + +/** + * @ingroup los_trace + * Trace event params: + 1. Configure the macro without parameters so as not to record events of this type; + 2. Configure the macro at least with one parameter to record this type of event; + 3. User can delete unnecessary parameters which defined in corresponding marco; * @attention *
    - *
  • This API can be called only after trace type is intialized. Otherwise, the trace will be failed.
  • + *
  • The first param is treat as key, keep at least this param if you want trace this event.
  • + *
  • All parameters were treated as UINTPTR.
  • *
+ * eg. Trace a event as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio + * eg. Not Trace a event as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) + * eg. Trace only you need parmas as: + * #define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId + */ +#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ + taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus +#define TASK_PRIOSET_PARAMS(taskId, taskStatus, oldPrio, newPrio) taskId, taskStatus, oldPrio, newPrio +#define TASK_CREATE_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio +#define TASK_DELETE_PARAMS(taskId, taskStatus, usrStack) taskId, taskStatus, usrStack +#define TASK_SUSPEND_PARAMS(taskId, taskStatus, runTaskId) taskId, taskStatus, runTaskId +#define TASK_RESUME_PARAMS(taskId, taskStatus, prio) taskId, taskStatus, prio +#define TASK_SIGNAL_PARAMS(taskId, signal, schedFlag) // taskId, signal, schedFlag + +#define SWTMR_START_PARAMS(swtmrId, mode, overrun, interval, expiry) swtmrId, mode, overrun, interval, expiry +#define SWTMR_DELETE_PARAMS(swtmrId) swtmrId +#define SWTMR_EXPIRED_PARAMS(swtmrId) swtmrId +#define SWTMR_STOP_PARAMS(swtmrId) swtmrId +#define SWTMR_CREATE_PARAMS(swtmrId) swtmrId + +#define HWI_CREATE_PARAMS(hwiNum, hwiPrio, hwiMode, hwiHandler) hwiNum, hwiPrio, hwiMode, hwiHandler +#define HWI_CREATE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret +#define HWI_DELETE_PARAMS(hwiNum) hwiNum +#define HWI_DELETE_SHARE_PARAMS(hwiNum, pDevId, ret) hwiNum, pDevId, ret +#define HWI_RESPONSE_IN_PARAMS(hwiNum) hwiNum +#define HWI_RESPONSE_OUT_PARAMS(hwiNum) hwiNum +#define HWI_ENABLE_PARAMS(hwiNum) hwiNum +#define HWI_DISABLE_PARAMS(hwiNum) hwiNum +#define HWI_TRIGGER_PARAMS(hwiNum) hwiNum +#define HWI_SETPRI_PARAMS(hwiNum, priority) hwiNum, priority +#define HWI_CLEAR_PARAMS(hwiNum) hwiNum +#define HWI_SETAFFINITY_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask +#define HWI_SENDIPI_PARAMS(hwiNum, cpuMask) hwiNum, cpuMask + +#define EVENT_CREATE_PARAMS(eventCB) eventCB +#define EVENT_DELETE_PARAMS(eventCB, delRetCode) eventCB, delRetCode +#define EVENT_READ_PARAMS(eventCB, eventId, mask, mode, timeout) \ + eventCB, eventId, mask, mode, timeout +#define EVENT_WRITE_PARAMS(eventCB, eventId, events) eventCB, eventId, events +#define EVENT_CLEAR_PARAMS(eventCB, eventId, events) eventCB, eventId, events + +#define QUEUE_CREATE_PARAMS(queueId, queueSz, itemSz, queueAddr, memType) \ + queueId, queueSz, itemSz, queueAddr, memType +#define QUEUE_DELETE_PARAMS(queueId, state, readable) queueId, state, readable +#define QUEUE_RW_PARAMS(queueId, queueSize, bufSize, operateType, readable, writeable, timeout) \ + queueId, queueSize, bufSize, operateType, readable, writeable, timeout + +#define SEM_CREATE_PARAMS(semId, type, count) semId, type, count +#define SEM_DELETE_PARAMS(semId, delRetCode) semId, delRetCode +#define SEM_PEND_PARAMS(semId, count, timeout) semId, count, timeout +#define SEM_POST_PARAMS(semId, type, count) semId, type, count + +#define MUX_CREATE_PARAMS(muxId) muxId +#define MUX_DELETE_PARAMS(muxId, state, count, owner) muxId, state, count, owner +#define MUX_PEND_PARAMS(muxId, count, owner, timeout) muxId, count, owner, timeout +#define MUX_POST_PARAMS(muxId, count, owner) muxId, count, owner + +#define MEM_ALLOC_PARAMS(pool, ptr, size) pool, ptr, size +#define MEM_ALLOC_ALIGN_PARAMS(pool, ptr, size, boundary) pool, ptr, size, boundary +#define MEM_REALLOC_PARAMS(pool, ptr, size) pool, ptr, size +#define MEM_FREE_PARAMS(pool, ptr) pool, ptr +#define MEM_INFO_REQ_PARAMS(pool) pool +#define MEM_INFO_PARAMS(pool, usedSize, freeSize) pool, usedSize, freeSize + +#define IPC_WRITE_DROP_PARAMS(dstTid, dstPid, msgType, code, ipcStatus) \ + dstTid, dstPid, msgType, code, ipcStatus +#define IPC_WRITE_PARAMS(dstTid, dstPid, msgType, code, ipcStatus) \ + dstTid, dstPid, msgType, code, ipcStatus +#define IPC_READ_DROP_PARAMS(srcTid, srcPid, msgType, code, ipcStatus) \ + srcTid, srcPid, msgType, code, ipcStatus +#define IPC_READ_PARAMS(srcTid, srcPid, msgType, code, ipcStatus) \ + srcTid, srcPid, msgType, code, ipcStatus +#define IPC_TRY_READ_PARAMS(msgType, ipcStatus) msgType, ipcStatus +#define IPC_READ_TIMEOUT_PARAMS(msgType, ipcStatus) msgType, ipcStatus +#define IPC_KILL_PARAMS(msgType, ipcStatus) msgType, ipcStatus + +#define SYS_ERROR_PARAMS(errno) errno + +#ifdef LOSCFG_KERNEL_TRACE + +/** + * @ingroup los_trace + * @brief Trace static code stub. * - * @param traceType [IN] TraceType Type of trace information. - * @param ... [IN] The trace data. + * @par Description: + * This API is used to instrument trace code stub in source code, to track events. + * @attention + * None. * + * @param TYPE [IN] Type #LOS_TRACE_TYPE. The event type. + * @param IDENTITY [IN] Type #UINTPTR. The subject of this event description. + * @param ... [IN] Type #UINTPTR. This piece of event's params. * @retval None. * * @par Dependency: *
  • los_trace.h: the header file that contains the API declaration.
- * @see LOS_Trace */ -VOID LOS_Trace(TraceType traceType, ...); +#define LOS_TRACE(TYPE, IDENTITY, ...) \ + do { \ + UINTPTR _inner[] = {0, TYPE##_PARAMS((UINTPTR)IDENTITY, ##__VA_ARGS__)}; \ + UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \ + if ((_n > 1) && (g_traceEventHook != NULL)) { \ + g_traceEventHook(TYPE, _inner[1], _n > 2 ? &_inner[2] : NULL, _n - 2); \ + } \ + } while (0) +#else +#define LOS_TRACE(TYPE, ...) +#endif + +#ifdef LOSCFG_KERNEL_TRACE /** * @ingroup los_trace - * @brief intialize the trace when the system startup. + * @brief Trace static easier user-defined code stub. * * @par Description: - * This API is used to intilize the trace for system level. + * This API is used to instrument user-defined trace code stub in source code, to track events simply. * @attention - *
    - *
  • This API can be called only after the memory is initialized. Otherwise, the CPU usage fails to be obtained.
  • - *
+ * None. * - * @param None. + * @param TYPE [IN] Type #UINT32. The event type, only low 4 bits take effect. + * @param IDENTITY [IN] Type #UINTPTR. The subject of this event description. + * @param ... [IN] Type #UINTPTR. This piece of event's params. + * @retval None. * - * @retval #LOS_OK : The trace function is initialized successfully. * @par Dependency: *
  • los_trace.h: the header file that contains the API declaration.
- * @see OsTraceInit */ -UINT32 OsTraceInit(VOID); +#define LOS_TRACE_EASY(TYPE, IDENTITY, ...) \ + do { \ + UINTPTR _inner[] = {0, ##__VA_ARGS__}; \ + UINTPTR _n = sizeof(_inner) / sizeof(UINTPTR); \ + if (g_traceEventHook != NULL) { \ + g_traceEventHook(TRACE_USER_DEFAULT_FLAG | TYPE, (UINTPTR)IDENTITY, _n > 1 ? &_inner[1] : NULL, _n - 1); \ + } \ + } while (0) +#else +#define LOS_TRACE_EASY(...) +#endif /** * @ingroup los_trace - * @brief register the hook for specific trace type. + * @brief Start trace. * * @par Description: - * This API is used to register the hook for specific trace type. + * This API is used to start trace. * @attention *
    - *
  • This API can be called only after that trace type, input hookfnc and trace's data struct are established.
  • + *
  • Start trace
  • + *
+ * + * @param None. + * @retval #LOS_ERRNO_TRACE_ERROR_STATUS 0x02001400: Trace start failed. + * @retval #LOS_OK 0x00000000: Trace start success. + * + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceStart + */ +extern UINT32 LOS_TraceStart(VOID); + +/** + * @ingroup los_trace + * @brief Stop trace sample. + * + * @par Description: + * This API is used to start trace sample. + * @attention + *
    + *
  • Stop trace sample
  • + *
+ * + * @param None. + * @retval #None. + * + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceStop + */ +extern VOID LOS_TraceStop(VOID); + +/** + * @ingroup los_trace + * @brief Clear the trace buf. + * + * @par Description: + * Clear the event frames in trace buf only at offline mode. + * @attention + *
    + *
  • This API can be called only after that trace buffer has been established.
  • * Otherwise, the trace will be failed. *
* - * @param traceType [IN] TraceType. Type of trace information. - * @param inhook [IN] WriteHook. It's a callback function to store the useful trace information. - * @param typeStr [IN] const CHAR *. The trace name of trace type. - * @param onOff [IN] TraceSwitch. It only can be LOS_TRACE_DISABLE or LOS_TRACE_ENABLE. + * @param None. + * @retval #NA + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceReset + */ +extern VOID LOS_TraceReset(VOID); + +/** + * @ingroup los_trace + * @brief Set trace event mask. * - * @retval #LOS_ERRNO_TRACE_NO_MEMORY 0x02001400: The memory is not enough for initilize. - * @retval #LOS_ERRNO_TRACE_TYPE_INVALID 0x02001401: The trace type is invalid. Valid type is from - * LOS_TRACE_TYPE_MAX - * @retval #LOS_ERRNO_TRACE_FUNCTION_NULL 0x02001402: The input callback function is NULL - * @retval #LOS_ERRNO_TRACE_MAX_SIZE_INVALID 0x02001403: The information maxmum size is 0 to store. - * @retval #LOS_OK 0x00000000: The registeration is successful. + * @par Description: + * Set trace event mask. + * @attention + *
    + *
  • Set trace event filter mask.
  • + *
  • The Default mask is (TRACE_HWI_FLAG | TRACE_TASK_FLAG), stands for switch on task and hwi events.
  • + *
  • Customize mask according to the type defined in enum LOS_TRACE_MASK to switch on corresponding module's + * trace.
  • + *
  • The system's trace mask will be overrode by the input parameter.
  • + *
+ * + * @param mask [IN] Type #UINT32. The mask used to filter events of LOS_TRACE_MASK. + * @retval #NA. + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceEventMaskSet + */ +extern VOID LOS_TraceEventMaskSet(UINT32 mask); + +/** + * @ingroup los_trace + * @brief Offline trace buffer display. + * + * @par Description: + * Display trace buf data only at offline mode. + * @attention + *
    + *
  • This API can be called only after that trace stopped. Otherwise the trace dump will be failed.
  • + *
  • Trace data will be send to pipeline when user set toClient = TRUE. Otherwise it will be formatted and printed + * out.
  • + *
+ * + * @param toClient [IN] Type #BOOL. Whether send trace data to Client through pipeline. + * @retval #NA * * @par Dependency: *
  • los_trace.h: the header file that contains the API declaration.
- * @see LOS_TraceUserReg + * @see LOS_TraceRecordDump */ -UINT32 LOS_TraceReg(TraceType traceType, WriteHook inHook, const CHAR *typeStr, TraceSwitch onOff); +extern VOID LOS_TraceRecordDump(BOOL toClient); -UINT32 LOS_TraceUnreg(TraceType traceType); - -UINT8 *LOS_TraceBufDataGet(UINT32 *desLen, UINT32 *relLen); - -VOID LOS_TraceSwitch(TraceSwitch onOff); - -UINT32 LOS_TraceTypeSwitch(TraceType traceType, TraceSwitch onOff); - -#ifdef LOSCFG_FS_VFS -INT32 LOS_Trace2File(const CHAR *filename); -#endif +/** + * @ingroup los_trace + * @brief Offline trace buffer export. + * + * @par Description: + * Return the trace buf only at offline mode. + * @attention + *
    + *
  • This API can be called only after that trace buffer has been established.
  • + *
  • The return buffer's address is a critical resource, user can only ready.
  • + *
+ * + * @param NA + * @retval #OfflineHead* The trace buffer's address, analyze this buffer according to the structure of + * OfflineHead. + * + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceRecordGet + */ +extern OfflineHead *LOS_TraceRecordGet(VOID); +/** + * @ingroup los_trace + * @brief Hwi num fliter hook. + * + * @par Description: + * Hwi fliter function. + * @attention + *
    + *
  • Filter the hwi events by hwi num
  • + *
+ * + * @param hook [IN] Type #TRACE_HWI_FILTER_HOOK. The user defined hook for hwi num filter, + * the hook should return true if you don't want trace this hwi num. + * @retval #None + * @par Dependency: + *
  • los_trace.h: the header file that contains the API declaration.
+ * @see LOS_TraceHwiFilterHookReg + */ +extern VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook); #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif +#endif /* _LOS_TRACE_H */ diff --git a/platform/los_config.h b/platform/los_config.h index b3c89951..e1ecf20d 100644 --- a/platform/los_config.h +++ b/platform/los_config.h @@ -359,14 +359,6 @@ extern UINT32 __heap_end; #define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) -/** - * @ingroup los_trace - * It's the total size of trace buffer. It's in the unit of char - */ -#ifdef LOSCFG_KERNEL_TRACE -#define LOS_TRACE_BUFFER_SIZE (1024 * 512) -#endif - /** * @ingroup los_config * Version number diff --git a/testsuites/unittest/BUILD.gn b/testsuites/unittest/BUILD.gn index f287a343..f2b0d7ed 100644 --- a/testsuites/unittest/BUILD.gn +++ b/testsuites/unittest/BUILD.gn @@ -330,5 +330,13 @@ group("unittest") { deps += [ "signal:liteos_a_signal_unittest" ] } } + if (LOSCFG_USER_TEST_TRACE == true) { + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + deps += [ "trace:liteos_a_trace_unittest_door" ] + } + if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + deps += [ "trace:liteos_a_trace_unittest" ] + } + } } } diff --git a/testsuites/unittest/config.gni b/testsuites/unittest/config.gni index 0520a702..f2a2257f 100644 --- a/testsuites/unittest/config.gni +++ b/testsuites/unittest/config.gni @@ -74,3 +74,4 @@ LOSCFG_USER_TEST_SYS = true LOSCFG_USER_TEST_TIME_CLOCK = true LOSCFG_USER_TEST_TIME_TIMER = true LOSCFG_USER_TEST_UTIL = true +LOSCFG_USER_TEST_TRACE = false diff --git a/testsuites/unittest/trace/BUILD.gn b/testsuites/unittest/trace/BUILD.gn new file mode 100644 index 00000000..a9c6eebb --- /dev/null +++ b/testsuites/unittest/trace/BUILD.gn @@ -0,0 +1,79 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + +import("//build/lite/config/test.gni") +import("../config.gni") + +common_include_dirs = [ + "//third_party/googletest/googletest/include", + "../common/include", + "./", +] + +sources_entry = [ + "../common/osTest.cpp", + "trace_unit_test.cpp", +] + +sources_smoke = [ + "smoke/trace_test_001.cpp", + "smoke/trace_test_002.cpp", + "smoke/trace_test_003.cpp", + "smoke/trace_test_004.cpp", +] + +sources_full = [ +] + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { + unittest("liteos_a_trace_unittest_door") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources_full = [] + sources += sources_full + configs = [ "..:public_config_for_door" ] + deps = [ "//third_party/bounds_checking_function:libsec_shared" ] + } +} + +if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_MIDDLE) { + unittest("liteos_a_trace_unittest") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + include_dirs = common_include_dirs + sources = sources_entry + sources += sources_smoke + sources += sources_full + configs = [ "..:public_config_for_all" ] + deps = [ "//third_party/bounds_checking_function:libsec_shared" ] + } +} diff --git a/testsuites/unittest/trace/It_test_trace.h b/testsuites/unittest/trace/It_test_trace.h new file mode 100644 index 00000000..aa183311 --- /dev/null +++ b/testsuites/unittest/trace/It_test_trace.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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. + */ +#ifndef _IT_TEST_SYS_H +#define _IT_TEST_SYS_H + +#include "osTest.h" +#include +#include +#include +#include +#include + +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) +#define TRACE_USR_MAX_PARAMS 3 + +typedef struct { + unsigned int eventType; + uintptr_t identity; + uintptr_t params[TRACE_USR_MAX_PARAMS]; +} UsrEventInfo; + +VOID ItTestTrace001(VOID); +VOID ItTestTrace002(VOID); +VOID ItTestTrace003(VOID); +VOID ItTestTrace004(VOID); +#endif diff --git a/testsuites/unittest/trace/smoke/trace_test_001.cpp b/testsuites/unittest/trace/smoke/trace_test_001.cpp new file mode 100644 index 00000000..65694ec2 --- /dev/null +++ b/testsuites/unittest/trace/smoke/trace_test_001.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_START, NULL); + sleep(1); + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace001(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_001", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/unittest/trace/smoke/trace_test_002.cpp b/testsuites/unittest/trace/smoke/trace_test_002.cpp new file mode 100644 index 00000000..71ec72cf --- /dev/null +++ b/testsuites/unittest/trace/smoke/trace_test_002.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + size_t mask; + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_RESET, NULL); /* clear all events */ + + mask = 0x10000; /* filter kernel events */ + ioctl(fd, TRACE_SET_MASK, mask); + + ioctl(fd, TRACE_START, NULL); /* start trace */ + sleep(1); + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace002(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_002", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/unittest/trace/smoke/trace_test_003.cpp b/testsuites/unittest/trace/smoke/trace_test_003.cpp new file mode 100644 index 00000000..3feeb3b9 --- /dev/null +++ b/testsuites/unittest/trace/smoke/trace_test_003.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + UsrEventInfo info = { + .eventType = 0x1, + .identity = 0x0001, + .params = {1, 2, 3}, + }; + + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_START, NULL); /* start trace */ + (void)write(fd, &info, sizeof(UsrEventInfo)); + info.eventType = 0x2; + info.identity = 0x0002; + (void)write(fd, &info, sizeof(UsrEventInfo)); + + ioctl(fd, TRACE_STOP, NULL); + ioctl(fd, TRACE_DUMP, false); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace003(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_003", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/unittest/trace/smoke/trace_test_004.cpp b/testsuites/unittest/trace/smoke/trace_test_004.cpp new file mode 100644 index 00000000..2ec18090 --- /dev/null +++ b/testsuites/unittest/trace/smoke/trace_test_004.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "It_test_trace.h" + +static UINT32 TestCase(VOID) +{ + int i; + int size = 0x100; + int len; + char *buffer = NULL; + + int fd = open("/dev/trace", O_RDWR); + ICUNIT_GOTO_NOT_EQUAL(fd, -1, errno, EXIT); + + ioctl(fd, TRACE_STOP, NULL); + + buffer= (char *)malloc(size); + if (buffer == NULL) { + printf("Read buffer malloc failed!\n"); + goto EXIT; + } + + len = read(fd, buffer, size); + for (i = 0; i < len; i++) { + printf("%02x ", buffer[i] & 0xFF); + } + printf("\n"); + free(buffer); +EXIT: + close(fd); + return 0; +} + +VOID ItTestTrace004(VOID) +{ + TEST_ADD_CASE("IT_TEST_TRACE_004", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/unittest/trace/trace_unit_test.cpp b/testsuites/unittest/trace/trace_unit_test.cpp new file mode 100644 index 00000000..78f3702e --- /dev/null +++ b/testsuites/unittest/trace/trace_unit_test.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 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 "stdio.h" +#include +#include + +#include "It_test_trace.h" + +using namespace testing::ext; +namespace OHOS { +class TraceTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +#if defined(LOSCFG_USER_TEST_SMOKE) +/* * + * @tc.name: IT_TEST_TRACE_001 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TraceTest, ItTestTrace001, TestSize.Level0) +{ + ItTestTrace001(); +} + +/* * + * @tc.name: IT_TEST_TRACE_002 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TraceTest, ItTestTrace002, TestSize.Level0) +{ + ItTestTrace002(); +} + +/* * + * @tc.name: IT_TEST_TRACE_003 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TraceTest, ItTestTrace003, TestSize.Level0) +{ + ItTestTrace003(); +} + +/* * + * @tc.name: IT_TEST_TRACE_004 + * @tc.desc: function for TraceTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TraceTest, ItTestTrace004, TestSize.Level0) +{ + ItTestTrace004(); +} +#endif +} // namespace OHOS diff --git a/tools/build/mk/los_config.mk b/tools/build/mk/los_config.mk index dbb529cf..7a79b378 100644 --- a/tools/build/mk/los_config.mk +++ b/tools/build/mk/los_config.mk @@ -156,9 +156,14 @@ ifeq ($(LOSCFG_KERNEL_VDSO), y) endif ifeq ($(LOSCFG_KERNEL_TRACE), y) - LITEOS_BASELIB += -ltrace + LITEOS_BASELIB += -ltrace LIB_SUBDIRS += kernel/extended/trace - LITEOS_TRACE_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/trace +endif + +ifeq ($(LOSCFG_KERNEL_HOOK), y) + LITEOS_BASELIB += -lhook + LIB_SUBDIRS += kernel/extended/hook + LITEOS_HOOK_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/hook/include endif ifeq ($(LOSCFG_KERNEL_LITEIPC), y) @@ -357,6 +362,11 @@ ifeq ($(LOSCFG_DRIVERS_MEM), y) LITEOS_DEV_MEM_INCLUDE = -I $(LITEOSTOPDIR)/drivers/char/mem/include endif +ifeq ($(LOSCFG_DRIVERS_TRACE), y) + LITEOS_BASELIB += -ltrace_dev + LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/trace +endif + ifeq ($(LOSCFG_DRIVERS_QUICKSTART), y) LITEOS_BASELIB += -lquickstart LIB_SUBDIRS += $(LITEOSTOPDIR)/drivers/char/quickstart @@ -515,7 +525,7 @@ STRIP = $(LITEOS_COMPILER_PATH)$(CROSS_COMPILE)strip endif LITEOS_EXTKERNEL_INCLUDE := $(LITEOS_CPPSUPPORT_INCLUDE) $(LITEOS_DYNLOAD_INCLUDE) \ - $(LITEOS_TICKLESS_INCLUDE) $(LITEOS_TRACE_INCLUDE) \ + $(LITEOS_TICKLESS_INCLUDE) $(LITEOS_HOOK_INCLUDE)\ $(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \ $(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \