12c421fd6d252ff48eda3c1345adb96d64e5cab0
[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 <lunaix/lxconsole.h>
7
8 #include <klibc/strfmt.h>
9
10 #include "kp_records.h"
11
12 #define MAX_BUFSZ 512
13 #define MAX_BUFSZ_HLF 256
14 #define MAX_KPENT_NUM 1024
15
16 static char tmp_buf[MAX_BUFSZ];
17
18 static struct kp_records kprecs = {
19     .kp_ents = { .ents = { .next = &kprecs.kp_ents.ents,
20                            .prev = &kprecs.kp_ents.ents } },
21     .max_recs = MAX_KPENT_NUM,
22     .kp_ent_wp = &kprecs.kp_ents.ents
23 };
24
25 static char*
26 shift_level(const char* str, int* level)
27 {
28     if (str[0] == KMSG_LVLSTART) {
29         *level = KMSG_LOGLEVEL(str[1]);
30
31         return str += 2;
32     }
33
34     *level = KLOG_INFO;
35     return str;
36 }
37
38 static inline void
39 kprintf_ml(const char* component, int level, const char* fmt, va_list args)
40 {
41     char* buf = &tmp_buf[MAX_BUFSZ_HLF];
42     ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s", component, fmt);
43
44     size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args);
45     kprec_put(&kprecs, level, tmp_buf, sz);
46
47     // FIXME temp measure, get some output
48     console_write_str(tmp_buf);
49     console_write_char('\n');
50 }
51
52 void
53 kprintf_m(const char* component, const char* fmt, va_list args)
54 {
55     int level;
56     fmt = shift_level(fmt, &level);
57
58     kprintf_ml(component, level, fmt, args);
59 }
60
61 static void
62 __twimap_kprintf_read(struct twimap* map)
63 {
64     struct kp_records* kprecs = twimap_data(map, struct kp_records*);
65
66     /*
67         XXX we can foreach all records in a single twimap read call,
68             as records is monotonic increasing by design.
69     */
70     struct kp_entry *pos, *n;
71     llist_for_each(pos, n, kprecs->kp_ent_wp, ents)
72     {
73         time_t s = pos->time / 1000;
74         time_t ms = pos->time % 1000;
75         twimap_printf(map, "[%05d.%03d] %s\n", s, ms, pos->content);
76     }
77 }
78
79 static void
80 kprintf_mapping_init()
81 {
82     twimap_entry_simple(NULL, "kmsg", &kprecs, __twimap_kprintf_read);
83 }
84 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
85
86 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
87 {
88     kprintf_ml("syslog", level, fmt, args);
89 }