1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 #include <zephyr/logging/log_backend.h>
9 #include <zephyr/logging/log_backend_std.h>
10 
11 LOG_MODULE_REGISTER(log_efi);
12 
13 static volatile bool in_panic;
14 static uint32_t log_format_current = CONFIG_LOG_BACKEND_EFI_CON_OUTPUT_DEFAULT;
15 
16 static struct k_spinlock lock;
17 
18 #define LOG_BUF_SIZE 128
19 static uint8_t efi_output_buf[LOG_BUF_SIZE + 1];
20 
21 extern int efi_console_putchar(int c);
22 
char_out(uint8_t * data,size_t length,void * ctx)23 static int char_out(uint8_t *data, size_t length, void *ctx)
24 {
25 	ARG_UNUSED(ctx);
26 
27 	size_t cnt = 0;
28 	uint8_t *ptr = data;
29 
30 	while (cnt < length) {
31 		efi_console_putchar(*ptr);
32 		cnt++;
33 		ptr++;
34 	}
35 
36 	return length;
37 }
38 
39 LOG_OUTPUT_DEFINE(log_output_efi, char_out, efi_output_buf, sizeof(efi_output_buf));
40 
process(const struct log_backend * const backend,union log_msg_generic * msg)41 static void process(const struct log_backend *const backend,
42 		union log_msg_generic *msg)
43 {
44 	uint32_t flags = log_backend_std_get_flags();
45 
46 	log_format_func_t log_output_func = log_format_func_t_get(log_format_current);
47 
48 	k_spinlock_key_t key = k_spin_lock(&lock);
49 
50 	log_output_func(&log_output_efi, &msg->log, flags);
51 
52 	k_spin_unlock(&lock, key);
53 }
54 
format_set(const struct log_backend * const backend,uint32_t log_type)55 static int format_set(const struct log_backend *const backend, uint32_t log_type)
56 {
57 	log_format_current = log_type;
58 	return 0;
59 }
60 
log_backend_efi_init(struct log_backend const * const backend)61 static void log_backend_efi_init(struct log_backend const *const backend)
62 {
63 	ARG_UNUSED(backend);
64 
65 }
66 
panic(struct log_backend const * const backend)67 static void panic(struct log_backend const *const backend)
68 {
69 	in_panic = true;
70 	log_backend_std_panic(&log_output_efi);
71 }
72 
dropped(const struct log_backend * const backend,uint32_t cnt)73 static void dropped(const struct log_backend *const backend, uint32_t cnt)
74 {
75 	ARG_UNUSED(backend);
76 
77 	log_backend_std_dropped(&log_output_efi, cnt);
78 }
79 
80 const struct log_backend_api log_backend_efi_api = {
81 	.process = process,
82 	.panic = panic,
83 	.init = log_backend_efi_init,
84 	.dropped = IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ? NULL : dropped,
85 	.format_set = format_set,
86 };
87 
88 LOG_BACKEND_DEFINE(log_backend_efi, log_backend_efi_api, true);
89