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