summaryrefslogtreecommitdiff
path: root/kernel/common/log.c
diff options
context:
space:
mode:
authorNathan Lee <me@nwlee.tech>2026-08-12 17:44:17 -0500
committerNathan Lee <me@nwlee.tech>2026-08-12 17:44:17 -0500
commit2c0efd93530c472e96ff3529aee983b53f3b78d9 (patch)
treecc36e7334e162ba67df79333e267ac93b4d984b9 /kernel/common/log.c
parent640a81b3ee366c651286efd1b80b37992cd53282 (diff)
rework project structure
Diffstat (limited to 'kernel/common/log.c')
-rw-r--r--kernel/common/log.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/kernel/common/log.c b/kernel/common/log.c
new file mode 100644
index 0000000..88136f2
--- /dev/null
+++ b/kernel/common/log.c
@@ -0,0 +1,109 @@
+#include <sys/log.h>
+
+__attribute__((section(".ringbuf"), aligned(64)))
+volatile char log_ring[RINGBUF_SIZE];
+static int pos = 0;
+
+void stub(char c) {
+ (void)c;
+ return;
+}
+
+console_callback_t callback = stub;
+
+void put_char(char c) {
+ log_ring[pos++] = c;
+ if (pos >= RINGBUF_SIZE)
+ pos = 0;
+
+ callback(c);
+}
+
+void put_string(const char *s) {
+ while (*s)
+ put_char(*s++);
+}
+
+void put_uint(unsigned int value, unsigned int radix) {
+ char tmp[16];
+ const char digits[] = "0123456789abcdef";
+ int i = 0;
+
+ if (value == 0) {
+ put_char('0');
+ return;
+ }
+
+ while (value) {
+ tmp[i++] = digits[value % radix];
+ value /= radix;
+ }
+
+ while (i--)
+ put_char(tmp[i]);
+}
+
+void put_int(int value) {
+ if (value < 0) {
+ put_char('-');
+ put_uint((unsigned int)(-value), 10);
+ } else {
+ put_uint((unsigned int)value, 10);
+ }
+}
+
+void vprintk(const char *fmt, __builtin_va_list args) {
+ while (*fmt) {
+ if (*fmt != '%') {
+ put_char(*fmt++);
+ continue;
+ }
+
+ fmt++;
+
+ switch (*fmt) {
+ case '%':
+ put_char('%');
+ break;
+
+ case 'c':
+ put_char((char)__builtin_va_arg(args, int));
+ break;
+
+ case 's':
+ put_string(__builtin_va_arg(args, const char *));
+ break;
+
+ case 'd':
+ case 'i':
+ put_int(__builtin_va_arg(args, int));
+ break;
+
+ case 'u':
+ put_uint(__builtin_va_arg(args, unsigned int), 10);
+ break;
+
+ case 'x':
+ put_uint(__builtin_va_arg(args, unsigned int), 16);
+ break;
+
+ default:
+ put_char('%');
+ put_char(*fmt);
+ break;
+ }
+
+ fmt++;
+ }
+}
+
+void printk(const char *fmt, ...) {
+ __builtin_va_list args;
+ __builtin_va_start(args, fmt);
+ vprintk(fmt, args);
+ __builtin_va_end(args);
+}
+
+void register_console_callback(console_callback_t cb) {
+ callback = cb;
+}