diff --git a/src/drivers/uart.c b/src/drivers/uart.c index 4706db0..c15ee60 100644 --- a/src/drivers/uart.c +++ b/src/drivers/uart.c @@ -1,5 +1,6 @@ #include #include +#include #include void uart_put(size_t base_addr, uint8_t data) { @@ -17,6 +18,40 @@ void kprint(const char *str) { } } +void kprint_int(int num) { + char buffer[21]; + int i = 0; + if (num == 0) { + kputchar('0'); + return; + } + if (num < 0) { + kputchar('-'); + num = -num; + } + while (num > 0) { + buffer[i++] = '0' + (num % 10); + num /= 10; + } + while (i > 0) { + kputchar(buffer[--i]); + } +} + +void kprint_hex(uint64_t val) { + char *digits = "0123456789ABCDEF"; + char buffer[16]; // 64-bit hex is 16 chars + + // We process from right to left + for (int i = 15; i >= 0; i--) { + buffer[i] = digits[val & 0xF]; + val >>= 4; + } + + kprint(buffer); + +} + void knewline(void) { kputchar('\n'); } @@ -24,4 +59,43 @@ void knewline(void) { void kputs(const char *str) { kprint(str); knewline(); +} + +void kprintf(const char *format, ...) { + va_list args; + va_start(args, format); + + for(char *p = format; *p != '\0'; p++) { + if (*p == '%') { + p++; + switch (*p) { + case 's': { + char *s = va_arg(args, char *); + kprint(s); + break; + } + case 'd': { + int d = va_arg(args, int); + kprint_int(d); + break; + } + case 'x': // Hex + case 'p': { // Pointer + uint64_t x = va_arg(args, uint64_t); + kputchar('0'); kputchar('x'); + kprint_hex(x); + break; + } + case '%': + kputchar('%'); + break; + default: + kputchar('%'); + kputchar(*p); + } + } else { + kputchar(*p); + } + } + } \ No newline at end of file diff --git a/src/drivers/uart.h b/src/drivers/uart.h index 19e527c..e500918 100644 --- a/src/drivers/uart.h +++ b/src/drivers/uart.h @@ -4,6 +4,9 @@ #define UART_ADDRESS 0x10000000 void uart_put(size_t base_addr, uint8_t data); int kputchar(int ch); +void kprint_hex(uint64_t val); +void kprint_int(int num); +void kprintf(const char *format, ...); void knewline(); void kputs(const char *str); void kprint(const char *str);