feat: device subsystem rework
[lunaix-os.git] / lunaix-os / kernel / kprintf.c
1 #include <klibc/stdio.h>
2 #include <lunaix/lxconsole.h>
3 #include <lunaix/spike.h>
4 #include <lunaix/syscall.h>
5 #include <lunaix/syslog.h>
6 #include <lunaix/tty/tty.h>
7
8 #define MAX_KPRINTF_BUF_SIZE 512
9 #define MAX_XFMT_SIZE 512
10
11 static char* log_prefix[] = { "- ", "W ", "E ", "D " };
12 static char* color_code[] = { "", "\033[6;0m", "\033[12;0m", "\033[9;0m" };
13
14 void
15 __kprintf_internal(const char* component,
16                    int log_level,
17                    const char* prefix,
18                    const char* fmt,
19                    va_list args)
20 {
21     char buf[MAX_KPRINTF_BUF_SIZE];
22     char expanded_fmt[MAX_XFMT_SIZE];
23     char* color = color_code[log_level];
24
25     if (component) {
26         ksnprintf(expanded_fmt,
27                   MAX_XFMT_SIZE,
28                   "%s%s%s: %s\033[39;49m",
29                   color,
30                   prefix,
31                   component,
32                   fmt);
33     } else {
34         ksnprintf(
35           expanded_fmt, MAX_XFMT_SIZE, "%s%s%s\033[39;49m", color, prefix, fmt);
36     }
37
38     __ksprintf_internal(buf, expanded_fmt, MAX_KPRINTF_BUF_SIZE, args);
39     console_write_str(buf);
40 }
41
42 char*
43 __get_loglevel(char* fmt, int* log_level_out)
44 {
45     char l = '0';
46     if (*fmt == '\x1b') {
47         l = *(++fmt);
48         fmt++;
49     }
50     l -= '0';
51
52     if (l > 3) {
53         l = 0;
54     }
55
56     *log_level_out = (int)l;
57     return fmt;
58 }
59
60 void
61 kappendf(const char* fmt, ...)
62 {
63     char buf[MAX_KPRINTF_BUF_SIZE];
64
65     va_list args;
66     va_start(args, fmt);
67
68     int log_level;
69     fmt = __get_loglevel(fmt, &log_level);
70
71     __kprintf_internal(NULL, log_level, "", fmt, args);
72
73     va_end(args);
74 }
75
76 void
77 __kprintf(const char* component, const char* fmt, va_list args)
78 {
79     if (!fmt)
80         return;
81
82     int log_level;
83     fmt = __get_loglevel(fmt, &log_level);
84     __kprintf_internal(component, log_level, log_prefix[log_level], fmt, args);
85 }
86
87 void
88 kprint_panic(const char* fmt, ...)
89 {
90     char buf[MAX_KPRINTF_BUF_SIZE];
91     va_list args;
92     va_start(args, fmt);
93
94     tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_RED);
95     tty_clear_line(24);
96
97     __ksprintf_internal(buf, fmt, MAX_KPRINTF_BUF_SIZE, args);
98     tty_put_str_at(buf, 0, 24);
99
100     va_end(args);
101
102     spin();
103 }
104
105 void
106 kprint_dbg(const char* fmt, ...)
107 {
108     char buf[MAX_KPRINTF_BUF_SIZE];
109     va_list args;
110     va_start(args, fmt);
111
112     tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_MAGENTA);
113     tty_clear_line(24);
114
115     __ksprintf_internal(buf, fmt, MAX_KPRINTF_BUF_SIZE, args);
116     tty_put_str_at(buf, 0, 24);
117
118     va_end(args);
119
120     tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
121 }
122
123 void
124 kprint_hex(const void* buffer, unsigned int size)
125 {
126     unsigned char* data = (unsigned char*)buffer;
127     char buf[16];
128     char ch_cache[16];
129     unsigned int ptr = 0;
130     int i;
131
132     ch_cache[0] = '|';
133     ch_cache[1] = ' ';
134     while (size) {
135         ksnprintf(buf, 64, " %.4p: ", ptr);
136         console_write_str(buf);
137         for (i = 0; i < 8 && size; i++, size--, ptr++) {
138             unsigned char c = *(data + ptr) & 0xff;
139             ch_cache[2 + i] = (32 <= c && c < 127) ? c : '.';
140             ksnprintf(buf, 64, "%.2x  ", c);
141             console_write_str(buf);
142         }
143         ch_cache[2 + i] = '\0';
144         console_write_str(ch_cache);
145         console_write_char('\n');
146     }
147 }
148
149 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
150 {
151     __kprintf_internal("syslog", level, "", fmt, args);
152 }