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