forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdebug_stream_text_msg.c
More file actions
139 lines (114 loc) · 3.41 KB
/
debug_stream_text_msg.c
File metadata and controls
139 lines (114 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2024 Intel Corporation.
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#include <soc.h>
#include <adsp_debug_window.h>
#include <sof/common.h>
#include <zephyr/logging/log.h>
#include <zephyr/arch/exception.h>
#include <user/debug_stream_text_msg.h>
LOG_MODULE_REGISTER(debug_stream_text_msg);
void ds_msg(const char *format, ...)
{
va_list args;
struct {
struct debug_stream_text_msg msg;
char text[128];
} __packed buf = { 0 };
ssize_t len;
va_start(args, format);
len = vsnprintf(buf.text, sizeof(buf.text), format, args);
va_end(args);
if (len < 0)
return;
len = MIN(len, sizeof(buf.text));
buf.msg.hdr.id = DEBUG_STREAM_RECORD_ID_TEXT_MSG;
buf.msg.hdr.size_words = SOF_DIV_ROUND_UP(sizeof(buf.msg) + len,
sizeof(buf.msg.hdr.data[0]));
debug_stream_slot_send_record(&buf.msg.hdr);
}
#if defined(CONFIG_EXCEPTION_DUMP_HOOK)
/* The debug stream debug window slot is 4k, and when it is split
* between the cores and the header/other overhead is removed, with 5
* cores the size is 768 bytes. The dump record must be smaller than
* that to get through to the host side.
*
* Also, because of the limited circular buffer size, we should only
* send one exception record. On some situations the exceptions happen
* in bursts, and sending more than one record in short time makes the
* host-side decoder lose track of things.
*/
static struct {
struct debug_stream_text_msg msg;
char text[640];
} __packed ds_buf[CONFIG_MP_MAX_NUM_CPUS];
static int reports_sent_cpu[CONFIG_MP_MAX_NUM_CPUS];
static size_t ds_pos[CONFIG_MP_MAX_NUM_CPUS];
static void ds_exception_drain(bool flush)
{
unsigned int cpu = arch_proc_id();
if (flush) {
ds_pos[cpu] = 0;
reports_sent_cpu[cpu] = 0;
return;
}
if (ds_pos[cpu] == 0)
return;
if (reports_sent_cpu[cpu] > 0)
return;
ds_buf[cpu].msg.hdr.id = DEBUG_STREAM_RECORD_ID_TEXT_MSG;
ds_buf[cpu].msg.hdr.size_words =
SOF_DIV_ROUND_UP(sizeof(ds_buf[cpu].msg) + ds_pos[cpu],
sizeof(ds_buf[cpu].msg.hdr.data[0]));
/* Make sure the possible up to 3 extra bytes at end of msg are '\0' */
memset(ds_buf[cpu].text + ds_pos[cpu], 0,
ds_buf[cpu].msg.hdr.size_words * sizeof(ds_buf[cpu].msg.hdr.data[0]) - ds_pos[cpu]);
debug_stream_slot_send_record(&ds_buf[cpu].msg.hdr);
reports_sent_cpu[cpu] = 1;
ds_pos[cpu] = 0;
}
static void ds_exception_dump(const char *format, va_list args)
{
ssize_t len;
size_t avail;
size_t written;
unsigned int cpu = arch_proc_id();
if (reports_sent_cpu[cpu] > 0)
return;
avail = sizeof(ds_buf[cpu].text) - ds_pos[cpu];
if (avail == 0) {
ds_exception_drain(false);
return;
}
if (format[0] == '\0')
return;
/* Skip useless " ** " prefix to save bytes */
if (strlen(format) >= 4 &&
format[0] == ' ' && format[1] == '*' && format[2] == '*' && format[3] == ' ')
format += 4;
len = vsnprintf(ds_buf[cpu].text + ds_pos[cpu], avail, format, args);
if (len < 0) {
ds_pos[cpu] = 0;
return;
}
if (len == 0)
return;
if ((size_t)len >= avail)
written = avail - 1;
else
written = (size_t)len;
ds_pos[cpu] += written;
if (ds_pos[cpu] >= sizeof(ds_buf[cpu].text))
ds_exception_drain(false);
}
static int init_exception_dump_hook(void)
{
set_exception_dump_hook(ds_exception_dump, ds_exception_drain);
LOG_INF("exception_dump_hook set");
return 0;
}
SYS_INIT(init_exception_dump_hook, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif