#include #include #include "stdio.h" #include "debug.h" #include "video/render.h" #include "arch/x86_64/e9.h" #include "mp/spinlock.h" static const uint32_t g_LogSeverityColors[] = { [LVL_DEBUG] = 0xAAAAAA, // light gray [LVL_INFO] = 0xFFFFFF, // white [LVL_WARN] = 0xFFFF00, // yellow [LVL_ERROR] = 0xFF0000, // red [LVL_CRITICAL] = 0xFFFFFF, // white (can do red background separately if you want) }; static spinlock_t s_printf_lock = SPINLOCK_INIT; void fputc(char c) { putchar(c); e9_putc(c); } void fputs(const char* str) { const char* s = str; while (*s) fputc(*s++); } void fputs_colored(const char* str, uint32_t color) { while (*str) putchar_colored(*str++, color); while (*str) fputc(*str++); } const char g_HexChars[] = "0123456789abcdef"; void fprintf_unsigned(uint64_t number, int radix) { char buffer[32]; int pos = 0; do { buffer[pos++] = g_HexChars[number % radix]; number /= radix; } while (number > 0); while (--pos >= 0) fputc(buffer[pos]); } void fprintf_signed(int64_t number, int radix) { if (number < 0) { fputc('-'); fprintf_unsigned(-number, radix); } else { fprintf_unsigned(number, radix); } } void vfprintf(const char* fmt, va_list args) { int state = 0; // normal int length = 0; // default int radix = 10; bool sign = false; bool number = false; while (*fmt) { switch (state) { case 0: // normal if (*fmt == '%') state = 1; else fputc(*fmt); break; case 1: // length if (*fmt == 'l') { length = 3; state = 4; } else if (*fmt == 'h') { length = 2; state = 4; } else goto spec; break; case 4: // spec spec: switch (*fmt) { case 'c': fputc((char)va_arg(args,int)); break; case 's': fputs(va_arg(args,const char*)); break; case 'd': case 'i': sign = true; number = true; radix = 10; break; case 'u': sign = false; number = true; radix = 10; break; case 'x': case 'X': sign = false; number = true; radix = 16; break; case 'p': number = true; sign = false; radix = 16; break; case 'o': sign = false; number = true; radix = 8; break; case '%': fputc('%'); break; } if (number) { if (sign) fprintf_signed(va_arg(args,long), radix); else fprintf_unsigned(va_arg(args,unsigned long), radix); } state = 0; length = 0; number = false; sign = false; break; } fmt++; } } void printf(const char* fmt, ...) { uint64_t flags; spinlock_acquire_irqsave(&s_printf_lock, &flags); va_list args; va_start(args, fmt); vfprintf(fmt, args); va_end(args); spinlock_release_irqrestore(&s_printf_lock, flags); } void fprintf(const char* fmt, ...) { va_list args; va_start(args, fmt); vfprintf(fmt, args); va_end(args); }