1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include <zephyr/kernel_structs.h>
8 #include <zephyr/init.h>
9 #include <zephyr/debug/cpu_load.h>
10 #include <ksched.h>
11
12 #include <SEGGER_SYSVIEW.h>
13
14 #define NAMED_EVENT_MAXSTR 20 /* Maximum string length supported by named event */
15
16 static uint32_t interrupt;
17
sysview_get_timestamp(void)18 uint32_t sysview_get_timestamp(void)
19 {
20 return k_cycle_get_32();
21 }
22
sysview_get_interrupt(void)23 uint32_t sysview_get_interrupt(void)
24 {
25 #ifdef CONFIG_CPU_CORTEX_M
26 interrupt = ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) >>
27 SCB_ICSR_VECTACTIVE_Pos);
28 #endif
29 return interrupt;
30 }
31
sys_trace_k_thread_switched_in(void)32 void sys_trace_k_thread_switched_in(void)
33 {
34 struct k_thread *thread;
35
36 thread = k_current_get();
37
38 if (z_is_idle_thread_object(thread)) {
39 SEGGER_SYSVIEW_OnIdle();
40 } else {
41 SEGGER_SYSVIEW_OnTaskStartExec((uint32_t)(uintptr_t)thread);
42 }
43 }
44
sys_trace_k_thread_switched_out(void)45 void sys_trace_k_thread_switched_out(void)
46 {
47 SEGGER_SYSVIEW_OnTaskStopExec();
48 }
49
sys_trace_isr_enter(void)50 void sys_trace_isr_enter(void)
51 {
52 SEGGER_SYSVIEW_RecordEnterISR();
53 }
54
sys_trace_isr_exit(void)55 void sys_trace_isr_exit(void)
56 {
57 SEGGER_SYSVIEW_RecordExitISR();
58 }
59
sys_trace_isr_exit_to_scheduler(void)60 void sys_trace_isr_exit_to_scheduler(void)
61 {
62 SEGGER_SYSVIEW_RecordExitISRToScheduler();
63 }
64
sys_trace_idle(void)65 void sys_trace_idle(void)
66 {
67 #ifdef CONFIG_TRACING_IDLE
68 SEGGER_SYSVIEW_OnIdle();
69 #endif
70
71 if (IS_ENABLED(CONFIG_CPU_LOAD)) {
72 cpu_load_on_enter_idle();
73 }
74 }
75
sys_trace_idle_exit(void)76 void sys_trace_idle_exit(void)
77 {
78 if (IS_ENABLED(CONFIG_CPU_LOAD)) {
79 cpu_load_on_exit_idle();
80 }
81 }
82
sys_trace_named_event(const char * name,uint32_t arg0,uint32_t arg1)83 void sys_trace_named_event(const char *name, uint32_t arg0, uint32_t arg1)
84 {
85 /* Based on SEGGER provided code for user defined packets */
86 uint8_t a_packet[SEGGER_SYSVIEW_INFO_SIZE + 2 *
87 SEGGER_SYSVIEW_QUANTA_U32 + NAMED_EVENT_MAXSTR + 1];
88 uint8_t *payload;
89
90 payload = SEGGER_SYSVIEW_PREPARE_PACKET(a_packet);
91 payload = SEGGER_SYSVIEW_EncodeString(payload, name, NAMED_EVENT_MAXSTR);
92 payload = SEGGER_SYSVIEW_EncodeU32(payload, arg0);
93 payload = SEGGER_SYSVIEW_EncodeU32(payload, arg1);
94 SEGGER_SYSVIEW_SendPacket(a_packet, payload, TID_NAMED_EVENT);
95 }
96
sysview_init(void)97 static int sysview_init(void)
98 {
99
100 SEGGER_SYSVIEW_Conf();
101 if (IS_ENABLED(CONFIG_SEGGER_SYSTEMVIEW_BOOT_ENABLE)) {
102 SEGGER_SYSVIEW_Start();
103 }
104 return 0;
105 }
106
107
108 SYS_INIT(sysview_init, POST_KERNEL, 0);
109