diff --git a/include/tracing/tracing_syscall.h b/include/tracing/tracing_syscall.h new file mode 100644 index 00000000000..96eb23f23b3 --- /dev/null +++ b/include/tracing/tracing_syscall.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TRACING_SYSCALL_H_ +#define ZEPHYR_INCLUDE_TRACING_SYSCALL_H_ + +#if defined CONFIG_SEGGER_SYSTEMVIEW + +#include "tracing_sysview_syscall.h" + +#elif defined CONFIG_TRACING_TEST + +#include "tracing_test_syscall.h" + +#else + +/** + * @brief Syscall Tracing APIs + * @defgroup syscall_tracing_apis Syscall Tracing APIs + * @ingroup tracing_apis + * @{ + */ + +/** + * @brief Trace syscall entry + * @param id Syscall ID (as defined in the generated syscall_list.h) + * @param name Syscall name as a token (ex: k_thread_create) + * @param ... Other parameters passed to the syscall + */ +#define sys_port_trace_syscall_enter(id, name, ...) + +/** + * @brief Trace syscall exit + * @param id Syscall ID (as defined in the generated syscall_list.h) + * @param name Syscall name as a token (ex: k_thread_create) + * @param ... Other parameters passed to the syscall, if the syscall has a return, the return value + * is the last parameter in the list + */ +#define sys_port_trace_syscall_exit(id, name, ...) + +/** + * @} + */ /* end of syscall_tracing_apis */ + +#endif + +#endif /* ZEPHYR_INCLUDE_TRACING_SYSCALL_H_ */ diff --git a/scripts/gen_syscalls.py b/scripts/gen_syscalls.py index f060034952f..fada726a7a3 100755 --- a/scripts/gen_syscalls.py +++ b/scripts/gen_syscalls.py @@ -29,6 +29,12 @@ import argparse import os import json +# Some kernel headers cannot include automated tracing without causing unintended recursion or +# other serious issues. +# These headers typically already have very specific tracing hooks for all relevant things +# written by hand so are excluded. +notracing = ["kernel.h", "errno_private.h"] + types64 = ["int64_t", "uint64_t"] # The kernel linkage is complicated. These functions from @@ -73,7 +79,9 @@ list_template = """ syscall_template = """ /* auto-generated by gen_syscalls.py, don't edit */ -%s +{include_guard} + +{tracing_include} #ifndef _ASMLANGUAGE @@ -82,6 +90,7 @@ syscall_template = """ #include + #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #endif @@ -94,13 +103,13 @@ syscall_template = """ #endif #ifdef __cplusplus -extern "C" { +extern "C" {{ #endif -%s +{invocations} #ifdef __cplusplus -} +}} #endif #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) @@ -122,6 +131,36 @@ uintptr_t %s(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, void *ssf); """ +# defines a macro wrapper which supercedes the syscall when used +# and provides tracing enter/exit hooks while allowing per compilation unit +# enable/disable of syscall tracing. Used for returning functions +# Note that the last argument to the exit macro is the return value. +syscall_tracer_with_return_template = """ +#ifndef DISABLE_SYSCALL_TRACING +{trace_diagnostic} +#define {func_name}({argnames}) ({{ \ + {func_type} retval; \ + sys_port_trace_syscall_enter({syscall_id}, {func_name}{trace_argnames}); \ + retval = {func_name}({argnames}); \ + sys_port_trace_syscall_exit({syscall_id}, {func_name}{trace_argnames}, retval); \ + retval; \ +}}) +#endif +""" + +# defines a macro wrapper which supercedes the syscall when used +# and provides tracing enter/exit hooks while allowing per compilation unit +# enable/disable of syscall tracing. Used for non-returning (void) functions +syscall_tracer_void_template = """ +#ifndef DISABLE_SYSCALL_TRACING +{trace_diagnostic} +#define {func_name}({argnames}) do {{ \ + sys_port_trace_syscall_enter({syscall_id}, {func_name}{trace_argnames}); \ + {func_name}({argnames}); \ + sys_port_trace_syscall_exit({syscall_id}, {func_name}{trace_argnames}); \ +}} while(false) +#endif +""" typename_regex = re.compile(r'(.*?)([A-Za-z0-9_]+)$') @@ -156,7 +195,7 @@ def need_split(argtype): def union_decl(type): return "union { struct { uintptr_t lo, hi; } split; %s val; }" % type -def wrapper_defs(func_name, func_type, args): +def wrapper_defs(func_name, func_type, args, fn): ret64 = need_split(func_type) mrsh_args = [] # List of rvalue expressions for the marshalled invocation split_args = [] @@ -174,6 +213,7 @@ def wrapper_defs(func_name, func_type, args): mrsh_args.append("(uintptr_t)&ret64") decl_arglist = ", ".join([" ".join(argrec) for argrec in args]) or "void" + syscall_id = "K_SYSCALL_" + func_name.upper() wrap = "extern %s z_impl_%s(%s);\n" % (func_type, func_name, decl_arglist) wrap += "\n" @@ -195,7 +235,6 @@ def wrapper_defs(func_name, func_type, args): wrap += "\t\t" + "};\n" mrsh_args[5:] = ["(uintptr_t) &more"] - syscall_id = "K_SYSCALL_" + func_name.upper() invoke = ("arch_syscall_invoke%d(%s)" % (len(mrsh_args), ", ".join(mrsh_args + [syscall_id]))) @@ -230,6 +269,23 @@ def wrapper_defs(func_name, func_type, args): wrap += "}\n" + if fn not in notracing: + argnames = ", ".join([f"{argname}" for _, argname in args]) + trace_argnames = "" + if len(args) > 0: + trace_argnames = ", " + argnames + trace_diagnostic = "" + if os.getenv('TRACE_DIAGNOSTICS'): + trace_diagnostic = f"#warning Tracing {func_name}" + if func_type != "void": + wrap += syscall_tracer_with_return_template.format(func_type=func_type, func_name=func_name, + argnames=argnames, trace_argnames=trace_argnames, + syscall_id=syscall_id, trace_diagnostic=trace_diagnostic) + else: + wrap += syscall_tracer_void_template.format(func_type=func_type, func_name=func_name, + argnames=argnames, trace_argnames=trace_argnames, + syscall_id=syscall_id, trace_diagnostic=trace_diagnostic) + return wrap # Returns an expression for the specified (zero-indexed!) marshalled @@ -316,7 +372,7 @@ def marshall_defs(func_name, func_type, args): return mrsh, mrsh_name -def analyze_fn(match_group): +def analyze_fn(match_group, fn): func, args = match_group try: @@ -334,7 +390,7 @@ def analyze_fn(match_group): marshaller = None marshaller, handler = marshall_defs(func_name, func_type, args) - invocation = wrapper_defs(func_name, func_type, args) + invocation = wrapper_defs(func_name, func_type, args, fn) # Entry in _k_syscall_table table_entry = "[%s] = %s" % (sys_id, handler) @@ -380,7 +436,7 @@ def main(): handlers = [] for match_group, fn in syscalls: - handler, inv, mrsh, sys_id, entry = analyze_fn(match_group) + handler, inv, mrsh, sys_id, entry = analyze_fn(match_group, fn) if fn not in invocations: invocations[fn] = [] @@ -426,7 +482,10 @@ def main(): ig = re.sub("[^a-zA-Z0-9]", "_", "Z_INCLUDE_SYSCALLS_" + fn).upper() include_guard = "#ifndef %s\n#define %s\n" % (ig, ig) - header = syscall_template % (include_guard, "\n\n".join(invo_list)) + tracing_include = "" + if fn not in notracing: + tracing_include = "#include " + header = syscall_template.format(include_guard=include_guard, tracing_include=tracing_include, invocations="\n\n".join(invo_list)) with open(out_fn, "w") as fp: fp.write(header) diff --git a/subsys/tracing/Kconfig b/subsys/tracing/Kconfig index b4a784b3a92..9785acafafd 100644 --- a/subsys/tracing/Kconfig +++ b/subsys/tracing/Kconfig @@ -204,7 +204,7 @@ config TRACING_CMD_BUFFER_SIZE menu "Tracing Configuration" -config SYSCALL_TRACING +config TRACING_SYSCALL bool "Enable tracing Syscalls" default y help diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index 55c0256fbdf..d6ccd625cb7 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -321,9 +321,6 @@ extern "C" { #define sys_port_trace_k_thread_resume_exit(thread) -#define sys_port_trace_syscall_enter() sys_trace_syscall_enter() -#define sys_port_trace_syscall_exit() sys_trace_syscall_exit() - #define sys_port_trace_pm_system_suspend_enter(ticks) #define sys_port_trace_pm_system_suspend_exit(ticks, ret) #define sys_port_trace_pm_device_request_enter(dev, target_state) @@ -334,8 +331,6 @@ extern "C" { #define sys_port_trace_pm_device_disable_enter(dev) #define sys_port_trace_pm_device_disable_exit(dev) -void sys_trace_syscall_enter(void); -void sys_trace_syscall_exit(void); void sys_trace_idle(void); void sys_trace_isr_enter(void); void sys_trace_isr_exit(void); diff --git a/subsys/tracing/sysview/tracing_sysview.h b/subsys/tracing/sysview/tracing_sysview.h index b2c6377ec35..99f674cec63 100644 --- a/subsys/tracing/sysview/tracing_sysview.h +++ b/subsys/tracing/sysview/tracing_sysview.h @@ -8,155 +8,14 @@ #include #include #include +#include #include - #ifdef __cplusplus extern "C" { #endif -#define TID_OFFSET (32u) - -#define TID_SCHED_LOCK (0u + TID_OFFSET) -#define TID_SCHED_UNLOCK (1u + TID_OFFSET) -#define TID_BUSYWAIT (2u + TID_OFFSET) - -#define TID_IRQ_ENABLE (3u + TID_OFFSET) -#define TID_IRQ_DISABLE (4u + TID_OFFSET) - -#define TID_MUTEX_INIT (5u + TID_OFFSET) -#define TID_MUTEX_UNLOCK (6u + TID_OFFSET) -#define TID_MUTEX_LOCK (7u + TID_OFFSET) - -#define TID_SEMA_INIT (8u + TID_OFFSET) -#define TID_SEMA_GIVE (9u + TID_OFFSET) -#define TID_SEMA_TAKE (10u + TID_OFFSET) -#define TID_SEMA_RESET (59u + TID_OFFSET) - -#define TID_QUEUE_INIT (11u + TID_OFFSET) -#define TID_QUEUE_APPEND (12u + TID_OFFSET) -#define TID_QUEUE_ALLOC_APPEND (13u + TID_OFFSET) -#define TID_QUEUE_PREPEND (14u + TID_OFFSET) -#define TID_QUEUE_ALLOC_PREPEND (15u + TID_OFFSET) -#define TID_QUEUE_INSERT (16u + TID_OFFSET) -#define TID_QUEUE_APPEND_LIST (17u + TID_OFFSET) -#define TID_QUEUE_GET (18u + TID_OFFSET) -#define TID_QUEUE_REMOVE (19u + TID_OFFSET) -#define TID_QUEUE_CANCEL_WAIT (20u + TID_OFFSET) -#define TID_QUEUE_PEAK_HEAD (21u + TID_OFFSET) -#define TID_QUEUE_PEAK_TAIL (22u + TID_OFFSET) - -#define TID_STACK_INIT (23u + TID_OFFSET) -#define TID_STACK_PUSH (24u + TID_OFFSET) -#define TID_STACK_POP (25u + TID_OFFSET) -#define TID_QUEUE_STACK_CLEANUP (26u + TID_OFFSET) - -#define TID_MSGQ_INIT (27u + TID_OFFSET) -#define TID_MSGQ_PUT (28u + TID_OFFSET) -#define TID_MSGQ_GET (29u + TID_OFFSET) -#define TID_MSGQ_CLEANUP (30u + TID_OFFSET) -#define TID_MSQG_PEEK (31u + TID_OFFSET) -#define TID_MSGQ_PURGE (32u + TID_OFFSET) - -#define TID_MBOX_INIT (33u + TID_OFFSET) -#define TID_MBOX_PUT (34u + TID_OFFSET) -#define TID_MBOX_ASYNC_PUT (35u + TID_OFFSET) -#define TID_MBOX_GET (36u + TID_OFFSET) -#define TID_MBOX_DATA_GET (37u + TID_OFFSET) -#define TID_MBOX_DATA_BLOCK_GET (38u + TID_OFFSET) - -#define TID_PIPE_INIT (39u + TID_OFFSET) -#define TID_PIPE_CLEANUP (40u + TID_OFFSET) -#define TID_PIPE_PUT (41u + TID_OFFSET) -#define TID_PIPE_GET (42u + TID_OFFSET) -#define TID_PIPE_BLOCK_GET (43u + TID_OFFSET) - -#define TID_HEAP_INIT (44u + TID_OFFSET) -#define TID_HEAP_ALLOC (45u + TID_OFFSET) -#define TID_HEAP_FREE (46u + TID_OFFSET) -#define TID_HEAP_ALIGNED_ALLOC (47u + TID_OFFSET) - -#define TID_MSLAB_INIT (52u + TID_OFFSET) -#define TID_MSLAB_ALLOC (53u + TID_OFFSET) -#define TID_MSLAB_FREE (54u + TID_OFFSET) - -#define TID_TIMER_INIT (55u + TID_OFFSET) -#define TID_TIMER_START (56u + TID_OFFSET) -#define TID_TIMER_STOP (57u + TID_OFFSET) -#define TID_TIMER_STATUS_SYNC (58u + TID_OFFSET) -#define TID_TIMER_USER_DATA_SET (59u + TID_OFFSET) -#define TID_TIMER_USER_DATA_GET (60u + TID_OFFSET) -#define TID_TIMER_EXPIRY_FN (61u + TID_OFFSET) -#define TID_TIMER_STOP_FN (62u + TID_OFFSET) - -#define TID_SLEEP (63u + TID_OFFSET) -#define TID_MSLEEP (64u + TID_OFFSET) -#define TID_USLEEP (65u + TID_OFFSET) - -#define TID_THREAD_PRIORITY_SET (66u + TID_OFFSET) -#define TID_THREAD_WAKEUP (67u + TID_OFFSET) -#define TID_THREAD_ABORT (68u + TID_OFFSET) -#define TID_THREAD_START (69u + TID_OFFSET) -#define TID_THREAD_SUSPEND (70u + TID_OFFSET) -#define TID_THREAD_RESUME (71u + TID_OFFSET) -#define TID_THREAD_JOIN (72u + TID_OFFSET) -#define TID_THREAD_YIELD (73u + TID_OFFSET) -#define TID_THREAD_USERMODE_ENTER (74u + TID_OFFSET) -#define TID_THREAD_FOREACH (75u + TID_OFFSET) -#define TID_THREAD_FOREACH_UNLOCKED (76u + TID_OFFSET) -#define TID_THREAD_NAME_SET (123u + TID_OFFSET) - -#define TID_CONDVAR_INIT (77u + TID_OFFSET) -#define TID_CONDVAR_SIGNAL (78u + TID_OFFSET) -#define TID_CONDVAR_BROADCAST (79u + TID_OFFSET) -#define TID_CONDVAR_WAIT (80u + TID_OFFSET) - -#define TID_WORK_CANCEL (81u + TID_OFFSET) -#define TID_WORK_CANCEL_DELAYABLE (82u + TID_OFFSET) -#define TID_WORK_CANCEL_DELAYABLE_SYNC (83u + TID_OFFSET) -#define TID_WORK_CANCEL_SYNC (84u + TID_OFFSET) -#define TID_WORK_DELAYABLE_INIT (85u + TID_OFFSET) -#define TID_WORK_QUEUE_DRAIN (86u + TID_OFFSET) -#define TID_WORK_FLUSH (87u + TID_OFFSET) -#define TID_WORK_FLUSH_DELAYABLE (88u + TID_OFFSET) -#define TID_WORK_INIT (89u + TID_OFFSET) -#define TID_WORK_POLL_CANCEL (90u + TID_OFFSET) -#define TID_WORK_POLL_INIT (91u + TID_OFFSET) -#define TID_WORK_POLL_SUBMIT (92u + TID_OFFSET) -#define TID_WORK_POLL_SUBMIT_TO_QUEUE (93u + TID_OFFSET) -#define TID_WORK_QUEUE_START (94u + TID_OFFSET) -#define TID_WORK_RESCHEDULE (95u + TID_OFFSET) -#define TID_WORK_RESCHEDULE_FOR_QUEUE (96u + TID_OFFSET) -#define TID_WORK_SCHEDULE (97u + TID_OFFSET) -#define TID_WORK_SCHEDULE_FOR_QUEUE (98u + TID_OFFSET) -#define TID_WORK_SUBMIT (99u + TID_OFFSET) -#define TID_WORK_SUBMIT_TO_QUEUE (100u + TID_OFFSET) -#define TID_WORK_QUEUE_UNPLUG (101u + TID_OFFSET) -#define TID_WORK_QUEUE_INIT (102u + TID_OFFSET) - -#define TID_FIFO_INIT (110u + TID_OFFSET) -#define TID_FIFO_CANCEL_WAIT (111u + TID_OFFSET) -#define TID_FIFO_ALLOC_PUT (112u + TID_OFFSET) -#define TID_FIFO_PUT_LIST (113u + TID_OFFSET) -#define TID_FIFO_PUT_SLIST (114u + TID_OFFSET) -#define TID_FIFO_PEAK_HEAD (115u + TID_OFFSET) -#define TID_FIFO_PEAK_TAIL (116u + TID_OFFSET) -#define TID_FIFO_PUT (117u + TID_OFFSET) -#define TID_FIFO_GET (118u + TID_OFFSET) - -#define TID_LIFO_INIT (119u + TID_OFFSET) -#define TID_LIFO_PUT (120u + TID_OFFSET) -#define TID_LIFO_GET (121u + TID_OFFSET) -#define TID_LIFO_ALLOC_PUT (122u + TID_OFFSET) - - -#define TID_PM_SUSPEND (124u + TID_OFFSET) -#define TID_PM_DEVICE_REQUEST (125u + TID_OFFSET) -#define TID_PM_DEVICE_ENABLE (126u + TID_OFFSET) -#define TID_PM_DEVICE_DISABLE (127u + TID_OFFSET) -/* latest ID is 127 */ - void sys_trace_thread_info(struct k_thread *thread); #define sys_port_trace_k_thread_foreach_enter() SEGGER_SYSVIEW_RecordVoid(TID_THREAD_FOREACH) @@ -734,8 +593,11 @@ void sys_trace_thread_info(struct k_thread *thread); #define sys_port_trace_k_timer_status_sync_exit(timer, result) \ SEGGER_SYSVIEW_RecordEndCallU32(TID_TIMER_STATUS_SYNC, (uint32_t)result) -#define sys_port_trace_syscall_enter() -#define sys_port_trace_syscall_exit() +#define sys_port_trace_syscall_enter(id, name, ...) \ + SEGGER_SYSVIEW_RecordU32(TID_SYSCALL, (uint32_t)id) + +#define sys_port_trace_syscall_exit(id, name, ...) \ + SEGGER_SYSVIEW_RecordEndCallU32(TID_SYSCALL, (uint32_t)id) void sys_trace_idle(void); diff --git a/subsys/tracing/sysview/tracing_sysview_ids.h b/subsys/tracing/sysview/tracing_sysview_ids.h new file mode 100644 index 00000000000..abbe5e28c89 --- /dev/null +++ b/subsys/tracing/sysview/tracing_sysview_ids.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TRACING_SYSVIEW_IDS_H_ +#define ZEPHYR_TRACING_SYSVIEW_IDS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define TID_OFFSET (32u) + +#define TID_SCHED_LOCK (0u + TID_OFFSET) +#define TID_SCHED_UNLOCK (1u + TID_OFFSET) +#define TID_BUSYWAIT (2u + TID_OFFSET) + +#define TID_IRQ_ENABLE (3u + TID_OFFSET) +#define TID_IRQ_DISABLE (4u + TID_OFFSET) + +#define TID_MUTEX_INIT (5u + TID_OFFSET) +#define TID_MUTEX_UNLOCK (6u + TID_OFFSET) +#define TID_MUTEX_LOCK (7u + TID_OFFSET) + +#define TID_SEMA_INIT (8u + TID_OFFSET) +#define TID_SEMA_GIVE (9u + TID_OFFSET) +#define TID_SEMA_TAKE (10u + TID_OFFSET) +#define TID_SEMA_RESET (59u + TID_OFFSET) + +#define TID_QUEUE_INIT (11u + TID_OFFSET) +#define TID_QUEUE_APPEND (12u + TID_OFFSET) +#define TID_QUEUE_ALLOC_APPEND (13u + TID_OFFSET) +#define TID_QUEUE_PREPEND (14u + TID_OFFSET) +#define TID_QUEUE_ALLOC_PREPEND (15u + TID_OFFSET) +#define TID_QUEUE_INSERT (16u + TID_OFFSET) +#define TID_QUEUE_APPEND_LIST (17u + TID_OFFSET) +#define TID_QUEUE_GET (18u + TID_OFFSET) +#define TID_QUEUE_REMOVE (19u + TID_OFFSET) +#define TID_QUEUE_CANCEL_WAIT (20u + TID_OFFSET) +#define TID_QUEUE_PEAK_HEAD (21u + TID_OFFSET) +#define TID_QUEUE_PEAK_TAIL (22u + TID_OFFSET) + +#define TID_STACK_INIT (23u + TID_OFFSET) +#define TID_STACK_PUSH (24u + TID_OFFSET) +#define TID_STACK_POP (25u + TID_OFFSET) +#define TID_QUEUE_STACK_CLEANUP (26u + TID_OFFSET) + +#define TID_MSGQ_INIT (27u + TID_OFFSET) +#define TID_MSGQ_PUT (28u + TID_OFFSET) +#define TID_MSGQ_GET (29u + TID_OFFSET) +#define TID_MSGQ_CLEANUP (30u + TID_OFFSET) +#define TID_MSQG_PEEK (31u + TID_OFFSET) +#define TID_MSGQ_PURGE (32u + TID_OFFSET) + +#define TID_MBOX_INIT (33u + TID_OFFSET) +#define TID_MBOX_PUT (34u + TID_OFFSET) +#define TID_MBOX_ASYNC_PUT (35u + TID_OFFSET) +#define TID_MBOX_GET (36u + TID_OFFSET) +#define TID_MBOX_DATA_GET (37u + TID_OFFSET) +#define TID_MBOX_DATA_BLOCK_GET (38u + TID_OFFSET) + +#define TID_PIPE_INIT (39u + TID_OFFSET) +#define TID_PIPE_CLEANUP (40u + TID_OFFSET) +#define TID_PIPE_PUT (41u + TID_OFFSET) +#define TID_PIPE_GET (42u + TID_OFFSET) +#define TID_PIPE_BLOCK_GET (43u + TID_OFFSET) + +#define TID_HEAP_INIT (44u + TID_OFFSET) +#define TID_HEAP_ALLOC (45u + TID_OFFSET) +#define TID_HEAP_FREE (46u + TID_OFFSET) +#define TID_HEAP_ALIGNED_ALLOC (47u + TID_OFFSET) + +#define TID_MSLAB_INIT (52u + TID_OFFSET) +#define TID_MSLAB_ALLOC (53u + TID_OFFSET) +#define TID_MSLAB_FREE (54u + TID_OFFSET) + +#define TID_TIMER_INIT (55u + TID_OFFSET) +#define TID_TIMER_START (56u + TID_OFFSET) +#define TID_TIMER_STOP (57u + TID_OFFSET) +#define TID_TIMER_STATUS_SYNC (58u + TID_OFFSET) +#define TID_TIMER_USER_DATA_SET (59u + TID_OFFSET) +#define TID_TIMER_USER_DATA_GET (60u + TID_OFFSET) +#define TID_TIMER_EXPIRY_FN (61u + TID_OFFSET) +#define TID_TIMER_STOP_FN (62u + TID_OFFSET) + +#define TID_SLEEP (63u + TID_OFFSET) +#define TID_MSLEEP (64u + TID_OFFSET) +#define TID_USLEEP (65u + TID_OFFSET) + +#define TID_THREAD_PRIORITY_SET (66u + TID_OFFSET) +#define TID_THREAD_WAKEUP (67u + TID_OFFSET) +#define TID_THREAD_ABORT (68u + TID_OFFSET) +#define TID_THREAD_START (69u + TID_OFFSET) +#define TID_THREAD_SUSPEND (70u + TID_OFFSET) +#define TID_THREAD_RESUME (71u + TID_OFFSET) +#define TID_THREAD_JOIN (72u + TID_OFFSET) +#define TID_THREAD_YIELD (73u + TID_OFFSET) +#define TID_THREAD_USERMODE_ENTER (74u + TID_OFFSET) +#define TID_THREAD_FOREACH (75u + TID_OFFSET) +#define TID_THREAD_FOREACH_UNLOCKED (76u + TID_OFFSET) +#define TID_THREAD_NAME_SET (123u + TID_OFFSET) + +#define TID_CONDVAR_INIT (77u + TID_OFFSET) +#define TID_CONDVAR_SIGNAL (78u + TID_OFFSET) +#define TID_CONDVAR_BROADCAST (79u + TID_OFFSET) +#define TID_CONDVAR_WAIT (80u + TID_OFFSET) + +#define TID_WORK_CANCEL (81u + TID_OFFSET) +#define TID_WORK_CANCEL_DELAYABLE (82u + TID_OFFSET) +#define TID_WORK_CANCEL_DELAYABLE_SYNC (83u + TID_OFFSET) +#define TID_WORK_CANCEL_SYNC (84u + TID_OFFSET) +#define TID_WORK_DELAYABLE_INIT (85u + TID_OFFSET) +#define TID_WORK_QUEUE_DRAIN (86u + TID_OFFSET) +#define TID_WORK_FLUSH (87u + TID_OFFSET) +#define TID_WORK_FLUSH_DELAYABLE (88u + TID_OFFSET) +#define TID_WORK_INIT (89u + TID_OFFSET) +#define TID_WORK_POLL_CANCEL (90u + TID_OFFSET) +#define TID_WORK_POLL_INIT (91u + TID_OFFSET) +#define TID_WORK_POLL_SUBMIT (92u + TID_OFFSET) +#define TID_WORK_POLL_SUBMIT_TO_QUEUE (93u + TID_OFFSET) +#define TID_WORK_QUEUE_START (94u + TID_OFFSET) +#define TID_WORK_RESCHEDULE (95u + TID_OFFSET) +#define TID_WORK_RESCHEDULE_FOR_QUEUE (96u + TID_OFFSET) +#define TID_WORK_SCHEDULE (97u + TID_OFFSET) +#define TID_WORK_SCHEDULE_FOR_QUEUE (98u + TID_OFFSET) +#define TID_WORK_SUBMIT (99u + TID_OFFSET) +#define TID_WORK_SUBMIT_TO_QUEUE (100u + TID_OFFSET) +#define TID_WORK_QUEUE_UNPLUG (101u + TID_OFFSET) +#define TID_WORK_QUEUE_INIT (102u + TID_OFFSET) + +#define TID_FIFO_INIT (110u + TID_OFFSET) +#define TID_FIFO_CANCEL_WAIT (111u + TID_OFFSET) +#define TID_FIFO_ALLOC_PUT (112u + TID_OFFSET) +#define TID_FIFO_PUT_LIST (113u + TID_OFFSET) +#define TID_FIFO_PUT_SLIST (114u + TID_OFFSET) +#define TID_FIFO_PEAK_HEAD (115u + TID_OFFSET) +#define TID_FIFO_PEAK_TAIL (116u + TID_OFFSET) +#define TID_FIFO_PUT (117u + TID_OFFSET) +#define TID_FIFO_GET (118u + TID_OFFSET) + +#define TID_LIFO_INIT (119u + TID_OFFSET) +#define TID_LIFO_PUT (120u + TID_OFFSET) +#define TID_LIFO_GET (121u + TID_OFFSET) +#define TID_LIFO_ALLOC_PUT (122u + TID_OFFSET) + + +#define TID_PM_SUSPEND (124u + TID_OFFSET) +#define TID_PM_DEVICE_REQUEST (125u + TID_OFFSET) +#define TID_PM_DEVICE_ENABLE (126u + TID_OFFSET) +#define TID_PM_DEVICE_DISABLE (127u + TID_OFFSET) + +#define TID_SYSCALL (128u + TID_OFFSET) + +/* latest ID is 128 */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_TRACING_SYSVIEW_IDS_H_ */ diff --git a/subsys/tracing/sysview/tracing_sysview_syscall.h b/subsys/tracing/sysview/tracing_sysview_syscall.h new file mode 100644 index 00000000000..6cac431f419 --- /dev/null +++ b/subsys/tracing/sysview/tracing_sysview_syscall.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TRACING_SYSVIEW_SYSCALL_H_ +#define ZEPHYR_TRACING_SYSVIEW_SYSCALL_H_ + +#include +#include + +#define sys_port_trace_syscall_enter(id, name, ...) \ + SEGGER_SYSVIEW_RecordU32(TID_SYSCALL, (uint32_t)id) + +#define sys_port_trace_syscall_exit(id, name, ...) \ + SEGGER_SYSVIEW_RecordEndCallU32(TID_SYSCALL, (uint32_t)id) + +#endif /* ZEPHYR_TRACING_SYSVIEW_SYSCALL_H_ */ diff --git a/subsys/tracing/test/tracing_string_format_test.c b/subsys/tracing/test/tracing_string_format_test.c index 62eacb4fe54..6aeb31b2f61 100644 --- a/subsys/tracing/test/tracing_string_format_test.c +++ b/subsys/tracing/test/tracing_string_format_test.c @@ -4,8 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DISABLE_SYSCALL_TRACING + #include #include +#include #include void sys_trace_k_thread_switched_out(void) @@ -55,6 +58,11 @@ void sys_trace_k_thread_resume(struct k_thread *thread) TRACING_STRING("%s: %p\n", __func__, thread); } +void sys_trace_k_thread_resume_exit(struct k_thread *thread) +{ + TRACING_STRING("%s: %p\n", __func__, thread); +} + void sys_trace_k_thread_ready(struct k_thread *thread) { TRACING_STRING("%s: %p\n", __func__, thread); @@ -95,6 +103,16 @@ void sys_trace_k_thread_sleep_exit(k_timeout_t timeout, int ret) TRACING_STRING("%s\n", __func__); } +void sys_trace_k_thread_usleep_enter(int32_t us) +{ + TRACING_STRING("%s\n", __func__); +} + +void sys_trace_k_thread_usleep_exit(int32_t us, int ret) +{ + TRACING_STRING("%s\n", __func__); +} + void sys_trace_k_thread_busy_wait_enter(uint32_t usec_to_wait) { TRACING_STRING("%s\n", __func__); @@ -253,6 +271,11 @@ void sys_trace_k_sem_take_blocking(struct k_sem *sem, k_timeout_t timeout) TRACING_STRING("%s: %p, timeout: %u\n", __func__, sem, (uint32_t)timeout.ticks); } +void sys_trace_k_sem_reset(struct k_sem *sem) +{ + TRACING_STRING("%s: %p\n", __func__, sem); +} + void sys_trace_k_mutex_init(struct k_mutex *mutex, int ret) { TRACING_STRING("%s: %p, returns %d\n", __func__, mutex, ret); @@ -266,7 +289,7 @@ void sys_trace_k_mutex_lock_enter(struct k_mutex *mutex, k_timeout_t timeout) void sys_trace_k_mutex_lock_exit(struct k_mutex *mutex, k_timeout_t timeout, int ret) { TRACING_STRING("%s: %p, timeout: %u, returns: %d\n", __func__, mutex, - (uint32_t)timeout.ticks, ret); + (uint32_t)timeout.ticks, ret); } void sys_trace_k_mutex_lock_blocking(struct k_mutex *mutex, k_timeout_t timeout) @@ -302,6 +325,21 @@ void sys_trace_k_timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn, TRACING_STRING("%s: %p\n", __func__, timer); } +void sys_trace_k_timer_stop(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} +void sys_trace_k_timer_status_sync_blocking(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} + +void sys_trace_k_timer_status_sync_exit(struct k_timer *timer, uint32_t result) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} + + void sys_trace_k_heap_init(struct k_heap *h, void *mem, size_t bytes) { TRACING_STRING("%s: %p\n", __func__, h); @@ -333,7 +371,144 @@ void sys_trace_k_heap_alloc_exit(struct k_heap *h, size_t bytes, k_timeout_t tim } void sys_trace_k_heap_aligned_alloc_exit(struct k_heap *h, size_t bytes, - k_timeout_t timeout, void *ret) + k_timeout_t timeout, void *ret) { TRACING_STRING("%s: %p\n", __func__, h); } + +void sys_trace_k_heap_sys_k_free_enter(struct k_heap *h) +{ + TRACING_STRING("%s: %p\n", __func__, h); +} + +void sys_trace_k_heap_sys_k_free_exit(struct k_heap *h) +{ + TRACING_STRING("%s: %p\n", __func__, h); +} + +void sys_trace_k_queue_init(struct k_queue *queue) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_cancel_wait(struct k_queue *queue) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_append_enter(struct k_queue *queue, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_append_exit(struct k_queue *queue, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_queue_insert_enter(struct k_queue *queue, bool alloc, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_queue_insert_exit(struct k_queue *queue, bool alloc, void *data, int ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_get_blocking(struct k_queue *queue, k_timeout_t timeout) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_get_exit(struct k_queue *queue, k_timeout_t timeout, void *ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_peek_head(struct k_queue *queue, void *ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_peek_tail(struct k_queue *queue, void *ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_alloc_append_enter(struct k_queue *queue, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_alloc_append_exit(struct k_queue *queue, void *data, int ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_alloc_prepend_enter(struct k_queue *queue, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + +void sys_trace_k_queue_alloc_prepend_exit(struct k_queue *queue, void *data, int ret) +{ + TRACING_STRING("%s: %p\n", __func__, queue); +} + + +void sys_trace_k_mem_slab_alloc_enter(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) +{ + TRACING_STRING("%s: %p\n", __func__, slab); +} + +void sys_trace_k_mem_slab_alloc_blocking(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) +{ + TRACING_STRING("%s: %p\n", __func__, slab); +} + +void sys_trace_k_mem_slab_alloc_exit(struct k_mem_slab *slab, void **mem, k_timeout_t timeout, + int ret) +{ + TRACING_STRING("%s: %p\n", __func__, slab); +} + +void sys_trace_k_mem_slab_free_enter(struct k_mem_slab *slab, void **mem) +{ + TRACING_STRING("%s: %p\n", __func__, slab); +} + +void sys_trace_k_mem_slab_free_exit(struct k_mem_slab *slab, void **mem) +{ + TRACING_STRING("%s: %p\n", __func__, slab); +} + +void sys_trace_k_fifo_put_enter(struct k_fifo *fifo, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, fifo); +} + +void sys_trace_k_fifo_put_exit(struct k_fifo *fifo, void *data) +{ + TRACING_STRING("%s: %p\n", __func__, fifo); +} + +void sys_trace_k_fifo_get_enter(struct k_fifo *fifo, k_timeout_t timeout) +{ + TRACING_STRING("%s: %p\n", __func__, fifo); +} + +void sys_trace_k_fifo_get_exit(struct k_fifo *fifo, k_timeout_t timeout, void *ret) +{ + TRACING_STRING("%s: %p\n", __func__, fifo); +} + +void sys_trace_syscall_enter(uint32_t syscall_id, const char *syscall_name) +{ + TRACING_STRING("%s: %s (%u) enter\n", __func__, syscall_name, syscall_id); +} + +void sys_trace_syscall_exit(uint32_t syscall_id, const char *syscall_name) +{ + TRACING_STRING("%s: %s (%u) exit\n", __func__, syscall_name, syscall_id); +} diff --git a/subsys/tracing/test/tracing_test.h b/subsys/tracing/test/tracing_test.h index 2d9f08692a9..d8bb43e54bb 100644 --- a/subsys/tracing/test/tracing_test.h +++ b/subsys/tracing/test/tracing_test.h @@ -427,10 +427,6 @@ #define sys_port_trace_k_thread_resume_exit(thread) sys_trace_k_thread_resume_exit(thread) -#define sys_port_trace_syscall_enter() sys_trace_syscall_enter() -#define sys_port_trace_syscall_exit() sys_trace_syscall_exit() - - #define sys_port_trace_pm_system_suspend_enter(ticks) #define sys_port_trace_pm_system_suspend_exit(ticks, ret) #define sys_port_trace_pm_device_request_enter(dev, target_state) @@ -441,8 +437,6 @@ #define sys_port_trace_pm_device_disable_enter(dev) #define sys_port_trace_pm_device_disable_exit(dev) -void sys_trace_syscall_enter(void); -void sys_trace_syscall_exit(void); void sys_trace_idle(void); void sys_trace_isr_enter(void); void sys_trace_isr_exit(void); diff --git a/subsys/tracing/test/tracing_test_syscall.h b/subsys/tracing/test/tracing_test_syscall.h new file mode 100644 index 00000000000..8750f788539 --- /dev/null +++ b/subsys/tracing/test/tracing_test_syscall.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TRACING_TEST_SYSCALL_H_ +#define ZEPHYR_TRACING_TEST_SYSCALL_H_ + +#include + +void sys_trace_syscall_enter(uint32_t syscall_id, const char *syscall_name); +void sys_trace_syscall_exit(uint32_t syscall_id, const char *sycall_name); + +#define sys_port_trace_syscall_enter(id, name, ...) \ + sys_trace_syscall_enter(id, #name) + +#define sys_port_trace_syscall_exit(id, name, ...) \ + sys_trace_syscall_exit(id, #name) + +#endif /* ZEPHYR_TRACING_TEST_SYSCALL_H_ */ diff --git a/subsys/tracing/tracing_backend_uart.c b/subsys/tracing/tracing_backend_uart.c index 014a50e51e1..725204cc980 100644 --- a/subsys/tracing/tracing_backend_uart.c +++ b/subsys/tracing/tracing_backend_uart.c @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* Disable syscall tracing for all calls from this compilation unit to avoid + * undefined symbols as the macros are not expanded recursively + */ +#define DISABLE_SYSCALL_TRACING + #include #include #include @@ -14,6 +19,7 @@ #include #include + static const struct device *tracing_uart_dev; #ifdef CONFIG_TRACING_HANDLE_HOST_CMD @@ -60,8 +66,8 @@ static void uart_isr(const struct device *dev, void *user_data) #endif static void tracing_backend_uart_output( - const struct tracing_backend *backend, - uint8_t *data, uint32_t length) + const struct tracing_backend *backend, + uint8_t *data, uint32_t length) { for (uint32_t i = 0; i < length; i++) { uart_poll_out(tracing_uart_dev, data[i]); @@ -92,7 +98,7 @@ static void tracing_backend_uart_init(void) const struct tracing_backend_api tracing_backend_uart_api = { .init = tracing_backend_uart_init, - .output = tracing_backend_uart_output + .output = tracing_backend_uart_output }; TRACING_BACKEND_DEFINE(tracing_backend_uart, tracing_backend_uart_api); diff --git a/subsys/tracing/tracing_backend_usb.c b/subsys/tracing/tracing_backend_usb.c index 113ef6d8771..57be8e09755 100644 --- a/subsys/tracing/tracing_backend_usb.c +++ b/subsys/tracing/tracing_backend_usb.c @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* Disable syscall tracing for all calls from this compilation unit to avoid + * undefined symbols as the macros are not expanded recursively + */ +#define DISABLE_SYSCALL_TRACING + #include #include #include @@ -123,7 +128,7 @@ static struct usb_ep_cfg_data ep_cfg[] = { }; USBD_CFG_DATA_DEFINE(primary, tracing_backend_usb) - struct usb_cfg_data tracing_backend_usb_config = { +struct usb_cfg_data tracing_backend_usb_config = { .usb_device_description = NULL, .interface_descriptor = &dev_desc.if0, .cb_usb_status = dev_status_cb, diff --git a/subsys/tracing/tracing_core.c b/subsys/tracing/tracing_core.c index 5ac2a9cd30a..d7c88668134 100644 --- a/subsys/tracing/tracing_core.c +++ b/subsys/tracing/tracing_core.c @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* Disable syscall tracing for all calls from this compilation unit to avoid + * undefined symbols as the macros are not expanded recursively + */ +#define DISABLE_SYSCALL_TRACING + #include #include #include diff --git a/subsys/tracing/tracing_format_async.c b/subsys/tracing/tracing_format_async.c index ac2604b7a7f..1b130268787 100644 --- a/subsys/tracing/tracing_format_async.c +++ b/subsys/tracing/tracing_format_async.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DISABLE_SYSCALL_TRACING + #include #include #include diff --git a/tests/subsys/openthread/radio_stub.c b/tests/subsys/openthread/radio_stub.c index 9a4978864f1..b66116ce1b8 100644 --- a/tests/subsys/openthread/radio_stub.c +++ b/tests/subsys/openthread/radio_stub.c @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ + +/* Disable syscall tracing to avoid a conflict with the device_get_binding + * macro defined below + */ +#define DISABLE_SYSCALL_TRACING + /* needed here so the static device_get_binding does not get renamed */ #include