From 2067ca185220348b70b35c96e175dfb87cc05592 Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Sun, 6 Feb 2022 16:31:19 +0000 Subject: we have kprintf() --- kc/core/Makefile | 2 +- kc/core/kprint.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- kc/core/kprint.h | 4 ++ 3 files changed, 135 insertions(+), 2 deletions(-) (limited to 'kc') diff --git a/kc/core/Makefile b/kc/core/Makefile index b0f4035..6874179 100644 --- a/kc/core/Makefile +++ b/kc/core/Makefile @@ -13,7 +13,7 @@ SOBJS := GOBJS := entry_x86_64.o reloc_x86_64.o kprint.o serial.o port.o \ kc_main.o main.o memory.o memset.o memcpy.o memmove.o memcmp.o cpu.o \ vm_tree.o exceptions.o panic.o msr.o task.o cpu_task.o \ - kcc_memory.o + kcc_memory.o string.o IOBJS := # __attribute__((interrupt)) requires -mgeneral-regs-only diff --git a/kc/core/kprint.c b/kc/core/kprint.c index 2f4da01..596d110 100644 --- a/kc/core/kprint.c +++ b/kc/core/kprint.c @@ -1,7 +1,9 @@ #include "kprint.h" #include "serial.h" -#include +#include + +#include __attribute__((optimize("O3"))) int kputchar(int c) @@ -20,3 +22,130 @@ int kputs(const char *s) return 0; } +static char *convert_scalar( + uint64_t value, + unsigned base, + char *buffer, + size_t bufsz) +{ + static const char *stringdigits = "0123456789abcdef"; + + // the string will be built from the lower-to-higher value, and the + // result pointer will point to the first character of the string in + // the supplied buffer + + // gotta zero the buffer + memset(buffer, 0, bufsz); + + // the string is being built backwards, so the pointer needs to be + // at the last byte of the string + char *result = buffer + bufsz - 1; + + // result >= buffer condition ensures we don't overflow + + while (value > 0 && result >= buffer) + { + *--result = stringdigits[value % base]; + value /= base; + } + + return result; +} + +int kvprintf(const char *restrict format, va_list arguments) +{ + int count = 0; + + while (*format) + { + if (*format != '%') + { + kputchar(*format++); + count++; + continue; + } + + switch (*++format) + { + case 0: + return count; + case '%': + count++; + kputchar('%'); + break; + case 's': + { + const char *s = va_arg(arguments, const char *); + count += strlen(s); + kputs(s); + break; + } + + case 'x': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 16, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'd': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 10, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'o': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 8, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'b': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 2, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + + default: + break; + } + + format++; + } + + va_end(arguments); + return count; +} + +int kprintf(const char *restrict format, ...) +{ + va_list arguments; + va_start (arguments, format); + + return kvprintf(format, arguments); +} + diff --git a/kc/core/kprint.h b/kc/core/kprint.h index 5b307a2..0c547ea 100644 --- a/kc/core/kprint.h +++ b/kc/core/kprint.h @@ -1,5 +1,9 @@ #pragma once +#include + int kputchar(int c); int kputs(const char *s); +int kprintf(const char *restrict format, ...); +int kvprintf(const char *restrict format, va_list arguments); -- cgit v1.3.1-1-g115d