feat: kprintf now goes into dedicated pseudo-dev rather than flooding the framebuffer
[lunaix-os.git] / lunaix-os / kernel / kprint / kprintf.c
1 #include <lunaix/fs/twifs.h>
2 #include <lunaix/fs/twimap.h>
3 #include <lunaix/syscall.h>
4 #include <lunaix/syslog.h>
5
6 #include <klibc/strfmt.h>
7
8 #include "kp_records.h"
9
10 #define MAX_BUFSZ 512
11 #define MAX_BUFSZ_HLF 256
12 #define MAX_KPENT_NUM 1024
13
14 static char tmp_buf[MAX_BUFSZ];
15
16 static struct kp_records kprecs = {
17     .kp_ents = { .ents = { .next = &kprecs.kp_ents.ents,
18                            .prev = &kprecs.kp_ents.ents } },
19     .max_recs = MAX_KPENT_NUM,
20     .kp_ent_wp = &kprecs.kp_ents.ents
21 };
22
23 static char*
24 shift_level(const char* str, int* level)
25 {
26     if (str[0] == KMSG_LVLSTART) {
27         *level = KMSG_LOGLEVEL(str[1]);
28
29         return str += 2;
30     }
31
32     *level = KLOG_INFO;
33     return str;
34 }
35
36 static void
37 __kprintf_level(const char* component, int level, const char* fmt, va_list args)
38 {
39     char* buf = &tmp_buf[MAX_BUFSZ_HLF];
40     ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s", component, fmt);
41
42     size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args);
43     kp_rec_put(&kprecs, level, tmp_buf, sz);
44 }
45
46 void
47 __kprintf(const char* component, const char* fmt, va_list args)
48 {
49     int level;
50     fmt = shift_level(fmt, &level);
51
52     __kprintf_level(component, level, fmt, args);
53 }
54
55 static void
56 __twimap_kprintf_read(struct twimap* map)
57 {
58     struct kp_records* kprecs = twimap_data(map, struct kp_records*);
59
60     /*
61         XXX we can foreach all records in a single twimap read call,
62             as records is monotonic increasing by design.
63     */
64     struct kp_entry *pos, *n;
65     llist_for_each(pos, n, kprecs->kp_ent_wp, ents)
66     {
67         twimap_printf(map, "[%05d] %s\n", pos->time, pos->content);
68     }
69 }
70
71 static void
72 kprintf_mapping_init()
73 {
74     twimap_entry_simple(NULL, "kmsg", &kprecs, __twimap_kprintf_read);
75 }
76 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
77
78 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
79 {
80     __kprintf_level("syslog", level, fmt, args);
81 }