1 /*
2  * Copyright (c) 2019 Intel corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <init.h>
8 #include <stdio.h>
9 #include <ctype.h>
10 #include <kernel.h>
11 #include <mipi_syst.h>
12 #include <sys/__assert.h>
13 #include <logging/log.h>
14 #include <logging/log_ctrl.h>
15 #include <logging/log_output.h>
16 
17 static struct mipi_syst_header log_syst_header;
18 static struct mipi_syst_handle log_syst_handle;
19 
20 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA)
21 #if defined(CONFIG_MIPI_SYST_STP)
22 static mipi_syst_u16 master = 128;
23 static mipi_syst_u16 channel = 1;
24 
25 static struct stp_writer_data writer_state;
26 #elif !defined(CONFIG_MIPI_SYST_RAW_DATA)
27 static const char pattern[] = "SYS-T RAW DATA: ";
28 static const char valToHex[] = "0123456789ABCDEF";
29 #endif
30 
out_func(int c,void * ctx)31 static int out_func(int c, void *ctx)
32 {
33 	const struct log_output *out_ctx = (const struct log_output *)ctx;
34 
35 	out_ctx->buf[out_ctx->control_block->offset] = (uint8_t)c;
36 	out_ctx->control_block->offset++;
37 
38 	__ASSERT_NO_MSG(out_ctx->control_block->offset <= out_ctx->size);
39 
40 	if (out_ctx->control_block->offset == out_ctx->size) {
41 		log_output_flush(out_ctx);
42 	}
43 
44 	return 0;
45 }
46 
47 #if defined(CONFIG_MIPI_SYST_STP)
stp_write_putNibble(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u8 n)48 static void stp_write_putNibble(struct mipi_syst_handle *systh,
49 				struct stp_writer_data *p, mipi_syst_u8 n)
50 {
51 	p->current |= (n << 4);
52 	p->byteDone = !p->byteDone;
53 
54 	if (p->byteDone) {
55 		out_func(p->current, systh->systh_platform.log_output);
56 		p->current = 0;
57 	} else {
58 		p->current >>= 4;
59 	}
60 }
61 
stp_write_flush(struct mipi_syst_handle * systh,struct stp_writer_data * p)62 static void stp_write_flush(struct mipi_syst_handle *systh,
63 			    struct stp_writer_data *p)
64 {
65 	if (!p->byteDone) {
66 		stp_write_putNibble(systh, p, 0);
67 	}
68 }
69 
stp_write_d4(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u8 v)70 static void stp_write_d4(struct mipi_syst_handle *systh,
71 			 struct stp_writer_data *p, mipi_syst_u8 v)
72 {
73 	stp_write_putNibble(systh, p, v);
74 }
75 
stp_write_payload8(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u8 v)76 static void stp_write_payload8(struct mipi_syst_handle *systh,
77 			       struct stp_writer_data *p, mipi_syst_u8 v)
78 {
79 	stp_write_d4(systh, p, v);
80 	stp_write_d4(systh, p, v>>4);
81 }
82 
stp_write_payload16(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u16 v)83 static void stp_write_payload16(struct mipi_syst_handle *systh,
84 				struct stp_writer_data *p, mipi_syst_u16 v)
85 {
86 	stp_write_payload8(systh, p, (mipi_syst_u8)v);
87 	stp_write_payload8(systh, p, (mipi_syst_u8)(v>>8));
88 }
89 
stp_write_payload32(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u32 v)90 static void stp_write_payload32(struct mipi_syst_handle *systh,
91 				struct stp_writer_data *p, mipi_syst_u32 v)
92 {
93 	stp_write_payload16(systh, p, (mipi_syst_u16)v);
94 	stp_write_payload16(systh, p, (mipi_syst_u16)(v>>16));
95 }
96 
stp_write_payload64(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u64 v)97 static void stp_write_payload64(struct mipi_syst_handle *systh,
98 				struct stp_writer_data *p, mipi_syst_u64 v)
99 {
100 	stp_write_payload32(systh, p, (mipi_syst_u32)v);
101 	stp_write_payload32(systh, p, (mipi_syst_u32)(v>>32));
102 }
103 
deltaTime(struct stp_writer_data * p)104 static mipi_syst_u64 deltaTime(struct stp_writer_data *p)
105 {
106 	mipi_syst_u64 delta;
107 
108 	delta = mipi_syst_get_epoch() - p->timestamp;
109 	return delta * 60;
110 }
111 
stp_write_d32mts(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u32 v)112 static void stp_write_d32mts(struct mipi_syst_handle *systh,
113 			     struct stp_writer_data *p, mipi_syst_u32 v)
114 {
115 	stp_write_d4(systh, p, 0xA);
116 	stp_write_payload32(systh, p, v);
117 
118 	stp_write_d4(systh, p, 0xE);
119 	stp_write_payload64(systh, p, deltaTime(p));
120 }
121 
stp_write_d64mts(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u64 v)122 static void stp_write_d64mts(struct mipi_syst_handle *systh,
123 			     struct stp_writer_data *p, mipi_syst_u64 v)
124 {
125 	stp_write_d4(systh, p, 0xB);
126 	stp_write_payload64(systh, p, v);
127 
128 	stp_write_d4(systh, p, 0xE);
129 	stp_write_payload64(systh, p, deltaTime(p));
130 }
131 
stp_write_d32ts(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u32 v)132 static void stp_write_d32ts(struct mipi_syst_handle *systh,
133 			    struct stp_writer_data *p, mipi_syst_u32 v)
134 {
135 	stp_write_d4(systh, p, 0xF);
136 	stp_write_d4(systh, p, 0x6);
137 
138 	stp_write_payload32(systh, p, v);
139 
140 	stp_write_d4(systh, p, 0xE);
141 	stp_write_payload64(systh, p, deltaTime(p));
142 }
143 
stp_write_d8(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u8 v)144 static void stp_write_d8(struct mipi_syst_handle *systh,
145 			 struct stp_writer_data *p, mipi_syst_u8 v)
146 {
147 	stp_write_d4(systh, p, 0x4);
148 	stp_write_payload8(systh, p, v);
149 }
150 
stp_write_d16(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u16 v)151 static void stp_write_d16(struct mipi_syst_handle *systh,
152 			  struct stp_writer_data *p, mipi_syst_u16 v)
153 {
154 	stp_write_d4(systh, p, 0x5);
155 	stp_write_payload16(systh, p, v);
156 }
157 
stp_write_d32(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u32 v)158 static void stp_write_d32(struct mipi_syst_handle *systh,
159 			  struct stp_writer_data *p, mipi_syst_u32 v)
160 {
161 	stp_write_d4(systh, p, 0x6);
162 	stp_write_payload32(systh, p, v);
163 }
164 
165 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
stp_write_d64(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u64 v)166 static void stp_write_d64(struct mipi_syst_handle *systh,
167 			  struct stp_writer_data *p, mipi_syst_u64 v)
168 {
169 	stp_write_d4(systh, p, 0x7);
170 	stp_write_payload64(systh, p, v);
171 }
172 #endif
173 
stp_write_flag(struct mipi_syst_handle * systh,struct stp_writer_data * p)174 static void stp_write_flag(struct mipi_syst_handle *systh,
175 			   struct stp_writer_data *p)
176 {
177 	stp_write_d4(systh, p, 0xF);
178 	stp_write_d4(systh, p, 0xE);
179 }
180 
stp_write_async(struct mipi_syst_handle * systh,struct stp_writer_data * p)181 static void stp_write_async(struct mipi_syst_handle *systh,
182 			    struct stp_writer_data *p)
183 {
184 	for (int i = 0; i < 21; ++i) {
185 		stp_write_d4(systh, p, 0xF);
186 	}
187 
188 	stp_write_d4(systh, p, 0x0);
189 }
190 
stp_write_version(struct mipi_syst_handle * systh,struct stp_writer_data * p)191 static void stp_write_version(struct mipi_syst_handle *systh,
192 			      struct stp_writer_data *p)
193 {
194 	stp_write_d4(systh, p, 0xF);
195 	stp_write_d4(systh, p, 0x0);
196 	stp_write_d4(systh, p, 0x0);
197 
198 	stp_write_d4(systh, p, 0x3);
199 
200 	p->master = 0;
201 	p->channel = 0;
202 }
203 
stp_write_freq(struct mipi_syst_handle * systh,struct stp_writer_data * p)204 static void stp_write_freq(struct mipi_syst_handle *systh,
205 			   struct stp_writer_data *p)
206 {
207 	stp_write_d4(systh, p, 0xF);
208 	stp_write_d4(systh, p, 0x0);
209 	stp_write_d4(systh, p, 0x8);
210 	stp_write_payload32(systh, p,  60 * 1000 * 1000);
211 }
212 
stp_write_setMC(struct mipi_syst_handle * systh,struct stp_writer_data * p,mipi_syst_u16 master,mipi_syst_u16 channel)213 static void stp_write_setMC(struct mipi_syst_handle *systh,
214 			    struct stp_writer_data *p,
215 			    mipi_syst_u16 master,
216 			    mipi_syst_u16 channel)
217 {
218 	if (!(p->recordCount++ % 20)) {
219 		stp_write_async(systh, p);
220 		stp_write_version(systh, p);
221 		stp_write_freq(systh, p);
222 	}
223 
224 	if (p->master != master) {
225 		stp_write_d4(systh, p, 0xF);
226 		stp_write_d4(systh, p, 0x1);
227 		stp_write_payload16(systh, p, master);
228 
229 		p->master = master;
230 		p->channel = 0;
231 	}
232 
233 	if (p->channel != channel) {
234 		stp_write_d4(systh, p, 0xF);
235 		stp_write_d4(systh, p, 0x3);
236 		stp_write_payload16(systh, p, channel);
237 
238 		p->channel = channel;
239 	}
240 }
241 #else
write_raw(struct mipi_syst_handle * systh,const void * p,int n)242 static void write_raw(struct mipi_syst_handle *systh, const void *p, int n)
243 {
244 	int i;
245 	uint8_t c;
246 
247 #if defined(MIPI_SYST_BIG_ENDIAN)
248 	for (i = n - 1; i >= 0; --i) {
249 #else
250 	for (i = 0; i < n; ++i) {
251 #endif
252 		c = ((const uint8_t *)p)[i];
253 #if defined(CONFIG_MIPI_SYST_RAW_DATA)
254 		out_func(c, systh->systh_platform.log_output);
255 #else
256 		out_func(valToHex[c >> 0x4], systh->systh_platform.log_output);
257 		out_func(valToHex[c & 0xF], systh->systh_platform.log_output);
258 #endif
259 	}
260 }
261 #endif
262 
263 static void write_d8(struct mipi_syst_handle *systh, uint8_t v)
264 {
265 #if defined(CONFIG_MIPI_SYST_STP)
266 	struct stp_writer_data *writer =
267 		systh->systh_header->systh_platform.stpWriter;
268 
269 	stp_write_d8(systh, writer, v);
270 #else
271 	write_raw(systh, &v, sizeof(v));
272 #endif
273 }
274 
275 static void write_d16(struct mipi_syst_handle *systh, uint16_t v)
276 {
277 #if defined(CONFIG_MIPI_SYST_STP)
278 	struct stp_writer_data *writer =
279 		systh->systh_header->systh_platform.stpWriter;
280 
281 	stp_write_d16(systh, writer, v);
282 #else
283 	write_raw(systh, &v, sizeof(v));
284 #endif
285 }
286 
287 static void write_d32(struct mipi_syst_handle *systh, uint32_t v)
288 {
289 #if defined(CONFIG_MIPI_SYST_STP)
290 	struct stp_writer_data *writer =
291 		systh->systh_header->systh_platform.stpWriter;
292 
293 	stp_write_d32(systh, writer, v);
294 #else
295 	write_raw(systh, &v, sizeof(v));
296 #endif
297 }
298 
299 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
300 static void write_d64(struct mipi_syst_handle *systh, uint64_t v)
301 {
302 #if defined(CONFIG_MIPI_SYST_STP)
303 	struct stp_writer_data *writer =
304 		systh->systh_header->systh_platform.stpWriter;
305 
306 	stp_write_d64(systh, writer, v);
307 #else
308 	write_raw(systh, &v, sizeof(v));
309 #endif
310 }
311 #endif
312 
313 static void write_d32ts(struct mipi_syst_handle *systh, uint32_t v)
314 {
315 #if defined(CONFIG_MIPI_SYST_STP)
316 	struct stp_writer_data *writer =
317 		systh->systh_header->systh_platform.stpWriter;
318 
319 	stp_write_setMC(systh, writer,
320 			systh->systh_platform.master,
321 			systh->systh_platform.channel);
322 	stp_write_d32ts(systh, writer, v);
323 #elif defined(CONFIG_MIPI_SYST_RAW_DATA)
324 	ARG_UNUSED(systh);
325 
326 	write_raw(systh, &v, sizeof(v));
327 #else
328 	for (int i = 0; i < strlen(pattern); i++) {
329 		out_func(pattern[i], systh->systh_platform.log_output);
330 	}
331 
332 	write_raw(systh, &v, sizeof(v));
333 #endif
334 }
335 
336 static void write_d32mts(struct mipi_syst_handle *systh, mipi_syst_u32 v)
337 {
338 #if defined(CONFIG_MIPI_SYST_STP)
339 	struct stp_writer_data *writer =
340 		systh->systh_header->systh_platform.stpWriter;
341 
342 	stp_write_setMC(systh, writer,
343 			systh->systh_platform.master,
344 			systh->systh_platform.channel);
345 	stp_write_d32mts(systh, writer, v);
346 #else
347 	ARG_UNUSED(systh);
348 	ARG_UNUSED(v);
349 #endif
350 }
351 
352 static void write_d64mts(struct mipi_syst_handle *systh, mipi_syst_u64 v)
353 {
354 #if defined(CONFIG_MIPI_SYST_STP)
355 	struct stp_writer_data *writer =
356 		systh->systh_header->systh_platform.stpWriter;
357 
358 	stp_write_setMC(systh, writer,
359 			systh->systh_platform.master,
360 			systh->systh_platform.channel);
361 	stp_write_d64mts(systh, writer, v);
362 #else
363 	ARG_UNUSED(systh);
364 	ARG_UNUSED(v);
365 #endif
366 }
367 
368 static void write_flag(struct mipi_syst_handle *systh)
369 {
370 #if defined(CONFIG_MIPI_SYST_STP)
371 	struct stp_writer_data *writer =
372 		systh->systh_header->systh_platform.stpWriter;
373 
374 	stp_write_flag(systh, writer);
375 	stp_write_flush(systh, writer);
376 #elif defined(CONFIG_MIPI_SYST_RAW_DATA)
377 	ARG_UNUSED(systh);
378 #else
379 	uint32_t flag = systh->systh_platform.flag;
380 
381 	if ((flag & LOG_OUTPUT_FLAG_CRLF_NONE) != 0U) {
382 		return;
383 	}
384 
385 	if ((flag & LOG_OUTPUT_FLAG_CRLF_LFONLY) != 0U) {
386 		out_func('\n', systh->systh_platform.log_output);
387 	} else {
388 		out_func('\r', systh->systh_platform.log_output);
389 		out_func('\n', systh->systh_platform.log_output);
390 	}
391 #endif
392 }
393 #endif
394 
395 #if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP)
396 mipi_syst_u64 mipi_syst_get_epoch(void)
397 {
398 	return k_uptime_ticks();
399 }
400 #endif
401 
402 static void update_systh_platform_data(struct mipi_syst_handle *handle,
403 				       const struct log_output *log_output,
404 				       uint32_t flag)
405 {
406 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA)
407 	handle->systh_platform.flag = (mipi_syst_u32)flag;
408 	handle->systh_platform.log_output = (struct log_output *)log_output;
409 #endif
410 }
411 
412 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_HANDLE_DATA)
413 /*
414  * Platform specific SyS-T handle initialization hook function
415  *
416  * @param systh pointer to the SyS-T handle structure
417  */
418 static void platform_handle_init(struct mipi_syst_handle *systh)
419 {
420 #if defined(CONFIG_MIPI_SYST_STP)
421 	if (channel > 127) {
422 		++master;
423 		channel = 1;
424 	}
425 
426 	systh->systh_platform.channel = channel++;
427 	systh->systh_platform.master  = master;
428 #endif
429 
430 #if defined(MIPI_SYST_PCFG_LENGTH_FIELD)
431 	MIPI_SYST_ENABLE_HANDLE_LENGTH(systh, 1);
432 #endif
433 
434 #if defined(MIPI_SYST_PCFG_ENABLE_TIMESTAMP)
435 	MIPI_SYST_ENABLE_HANDLE_TIMESTAMP(systh, 1);
436 #endif
437 }
438 
439 static void platform_handle_release(struct mipi_syst_handle *systh)
440 {
441 	ARG_UNUSED(systh);
442 }
443 #endif
444 
445 /*
446  * Platform specific global state initialization hook function
447  *
448  * @param systh pointer to the new SyS-T handle structure
449  * @param platform_data user defined data for the init function.
450  *
451  */
452 static void mipi_syst_platform_init(struct mipi_syst_header *systh,
453 				    const void *platform_data)
454 {
455 #if defined(CONFIG_MIPI_SYST_STP)
456 	writer_state.byteDone = 0;
457 	writer_state.current = 0;
458 	writer_state.master = 0;
459 	writer_state.channel = 0;
460 	writer_state.recordCount = 0;
461 	writer_state.timestamp = mipi_syst_get_epoch();
462 
463 	systh->systh_platform.stpWriter = &writer_state;
464 #endif
465 
466 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_HANDLE_DATA)
467 	systh->systh_inith = platform_handle_init;
468 	systh->systh_releaseh = platform_handle_release;
469 #endif
470 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA)
471 	systh->systh_platform.write_d8 = write_d8;
472 	systh->systh_platform.write_d16 = write_d16;
473 	systh->systh_platform.write_d32 = write_d32;
474 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
475 	systh->systh_platform.write_d64 = write_d64;
476 #endif
477 	systh->systh_platform.write_d32ts = write_d32ts;
478 	systh->systh_platform.write_d32mts = write_d32mts;
479 	systh->systh_platform.write_d64mts = write_d64mts;
480 	systh->systh_platform.write_flag = write_flag;
481 #endif
482 }
483 
484 /*
485  *    0   MIPI_SYST_SEVERITY_MAX      no assigned severity
486  *    1   MIPI_SYST_SEVERITY_FATAL    critical error level
487  *    2   MIPI_SYST_SEVERITY_ERROR    error message level
488  *    3   MIPI_SYST_SEVERITY_WARNING  warning message level
489  *    4   MIPI_SYST_SEVERITY_INFO     information message level
490  *    5   MIPI_SYST_SEVERITY_USER1    user defined level 5
491  *    6   MIPI_SYST_SEVERITY_USER2    user defined level 6
492  *    7   MIPI_SYST_SEVERITY_DEBUG    debug information level
493  */
494 static uint32_t level_to_syst_severity(uint32_t level)
495 {
496 	uint32_t ret;
497 
498 	switch (level) {
499 	case LOG_LEVEL_NONE:
500 		ret = 0U;
501 		break;
502 	case LOG_LEVEL_ERR:
503 		ret = 2U;
504 		break;
505 	case LOG_LEVEL_WRN:
506 		ret = 3U;
507 		break;
508 	case LOG_LEVEL_INF:
509 		ret = 4U;
510 		break;
511 	case LOG_LEVEL_DBG:
512 		ret = 7U;
513 		break;
514 	default:
515 		ret = 7U;
516 		break;
517 	}
518 
519 	return ret;
520 }
521 
522 static void std_print(struct log_msg *msg,
523 		const struct log_output *log_output)
524 {
525 	const char *str = log_msg_str_get(msg);
526 	uint32_t nargs = log_msg_nargs_get(msg);
527 	uint32_t *args = alloca(sizeof(uint32_t)*nargs);
528 	uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
529 
530 	for (int i = 0; i < nargs; i++) {
531 		args[i] = log_msg_arg_get(msg, i);
532 	}
533 
534 	switch (log_msg_nargs_get(msg)) {
535 	case 0:
536 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str);
537 		break;
538 	case 1:
539 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0]);
540 		break;
541 	case 2:
542 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
543 				args[1]);
544 		break;
545 	case 3:
546 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
547 				args[1], args[2]);
548 		break;
549 	case 4:
550 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
551 				args[1], args[2], args[3]);
552 		break;
553 	case 5:
554 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
555 				args[1], args[2], args[3], args[4]);
556 		break;
557 	case 6:
558 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
559 				args[1], args[2], args[3], args[4], args[5]);
560 		break;
561 	case 7:
562 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
563 				args[1], args[2], args[3], args[4], args[5],
564 				args[6]);
565 		break;
566 	case 8:
567 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
568 				args[1], args[2], args[3], args[4], args[5],
569 				args[6], args[7]);
570 		break;
571 	case 9:
572 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
573 				args[1], args[2], args[3], args[4], args[5],
574 				args[6], args[7], args[8]);
575 		break;
576 	case 10:
577 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
578 				args[1], args[2], args[3], args[4], args[5],
579 				args[6], args[7], args[8], args[9]);
580 		break;
581 	case 11:
582 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
583 				args[1], args[2], args[3], args[4], args[5],
584 				args[6], args[7], args[8], args[9], args[10]);
585 		break;
586 	case 12:
587 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
588 				args[1], args[2], args[3], args[4], args[5],
589 				args[6], args[7], args[8], args[9], args[10],
590 				args[11]);
591 		break;
592 	case 13:
593 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
594 				args[1], args[2], args[3], args[4], args[5],
595 				args[6], args[7], args[8], args[9], args[10],
596 				args[11], args[12]);
597 		break;
598 	case 14:
599 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
600 				args[1], args[2], args[3], args[4], args[5],
601 				args[6], args[7], args[8], args[9], args[10],
602 				args[11], args[12], args[13]);
603 		break;
604 	case 15:
605 		MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
606 				args[1], args[2], args[3], args[4], args[5],
607 				args[6], args[7], args[8], args[9], args[10],
608 				args[11], args[12], args[13], args[14]);
609 		break;
610 	default:
611 		/* Unsupported number of arguments. */
612 		__ASSERT_NO_MSG(true);
613 		break;
614 	}
615 }
616 
617 static void raw_string_print(struct log_msg *msg,
618 			const struct log_output *log_output)
619 {
620 	char buf[CONFIG_LOG_STRDUP_MAX_STRING + 1];
621 	size_t length = CONFIG_LOG_STRDUP_MAX_STRING;
622 	uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
623 
624 	log_msg_hexdump_data_get(msg, buf, &length, 0);
625 
626 	buf[length] = '\0';
627 
628 	MIPI_SYST_PRINTF(&log_syst_handle, severity, buf);
629 }
630 
631 static void hexdump_print(struct log_msg *msg,
632 			  const struct log_output *log_output)
633 {
634 	char buf[CONFIG_LOG_STRDUP_MAX_STRING + 1];
635 	size_t length = CONFIG_LOG_STRDUP_MAX_STRING;
636 	uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
637 
638 	log_msg_hexdump_data_get(msg, buf, &length, 0);
639 
640 	MIPI_SYST_WRITE(&log_syst_handle, severity, 0x1A, buf, length);
641 }
642 
643 void log_output_msg_syst_process(const struct log_output *log_output,
644 				struct log_msg *msg, uint32_t flag)
645 {
646 	uint8_t level = (uint8_t)log_msg_level_get(msg);
647 	bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);
648 
649 	update_systh_platform_data(&log_syst_handle, log_output, flag);
650 
651 	if (log_msg_is_std(msg)) {
652 		std_print(msg, log_output);
653 	} else if (raw_string) {
654 		raw_string_print(msg, log_output);
655 	} else {
656 		hexdump_print(msg, log_output);
657 	}
658 }
659 
660 void log_output_string_syst_process(const struct log_output *log_output,
661 				struct log_msg_ids src_level,
662 				const char *fmt, va_list ap, uint32_t flag)
663 {
664 	uint8_t str[CONFIG_LOG_STRDUP_MAX_STRING];
665 	size_t length = CONFIG_LOG_STRDUP_MAX_STRING;
666 	uint32_t severity = level_to_syst_severity((uint32_t)src_level.level);
667 
668 	length = vsnprintk(str, length, fmt, ap);
669 	str[length] = '\0';
670 
671 	update_systh_platform_data(&log_syst_handle, log_output, flag);
672 
673 	MIPI_SYST_PRINTF(&log_syst_handle, severity, str);
674 }
675 
676 void log_output_hexdump_syst_process(const struct log_output *log_output,
677 				struct log_msg_ids src_level,
678 				const uint8_t *data, uint32_t length, uint32_t flag)
679 {
680 	uint32_t severity = level_to_syst_severity((uint32_t)src_level.level);
681 
682 	update_systh_platform_data(&log_syst_handle, log_output, flag);
683 
684 	MIPI_SYST_WRITE(&log_syst_handle, severity, 0x1A, data, length);
685 }
686 
687 static int syst_init(const struct device *arg)
688 {
689 	ARG_UNUSED(arg);
690 
691 	MIPI_SYST_INIT_STATE(&log_syst_header,
692 			     mipi_syst_platform_init, (void *)0);
693 
694 	MIPI_SYST_INIT_HANDLE_STATE(&log_syst_header,
695 				    &log_syst_handle, NULL);
696 
697 	return 0;
698 }
699 
700 SYS_INIT(syst_init, POST_KERNEL, 0);
701