diff options
author | Marvin Borner | 2021-07-04 21:31:28 +0200 |
---|---|---|
committer | Marvin Borner | 2021-07-04 21:34:15 +0200 |
commit | 9b8698769535846d029c44247956eed9a21f1185 (patch) | |
tree | 294a17af4102805ab9863274339e8e030897804e /src/loader/log.c |
Initial commit
Diffstat (limited to 'src/loader/log.c')
-rw-r--r-- | src/loader/log.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/loader/log.c b/src/loader/log.c new file mode 100644 index 0000000..a2c05f0 --- /dev/null +++ b/src/loader/log.c @@ -0,0 +1,108 @@ +#include <cpu.h> +#include <lib.h> +#include <log.h> + +/** + * Formatting + */ + +static u32 vsnprintf(char *str, u32 size, const char *format, va_list ap) +{ + u32 length = 0; + + int temp_int; + char temp_ch; + char *temp_str; + + char buffer[64] = { 0 }; + + // TODO: Fix potential memory overflows because of str[length++]=xxx + char ch; + while ((ch = *format++)) { + if (ch == '%') { + switch (*format++) { + case '%': + str[length++] = '%'; + break; + case 'c': + temp_ch = va_arg(ap, int); + str[length++] = temp_ch; + break; + case 's': + temp_str = va_arg(ap, char *); + length += strlcpy(&str[length], temp_str, size - length); + break; + case 'b': + temp_int = va_arg(ap, int); + itoa(temp_int, buffer, 2); + length += strlcpy(&str[length], buffer, size - length); + break; + case 'd': + temp_int = va_arg(ap, int); + itoa(temp_int, buffer, 10); + length += strlcpy(&str[length], buffer, size - length); + break; + case 'x': + temp_int = va_arg(ap, int); + itoa(temp_int, buffer, 16); + length += strlcpy(&str[length], buffer, size - length); + break; + default: + serial_print("Unknown printf format\n"); + } + } else { + str[length++] = ch; + } + } + + return length; +} + +/** + * Serial + */ + +void serial_install(void) +{ + outb(0x3f8 + 1, 0x00); + outb(0x3f8 + 3, 0x80); + outb(0x3f8 + 0, 0x03); + outb(0x3f8 + 1, 0x00); + outb(0x3f8 + 3, 0x03); + outb(0x3f8 + 2, 0xc7); + outb(0x3f8 + 4, 0x0B); +} + +static int is_transmit_empty(void) +{ + return inb(0x3f8 + 5) & 0x20; +} + +static void serial_put(char ch) +{ + while (is_transmit_empty() == 0) + ; + outb(0x3f8, (u8)ch); +} + +void serial_print(const char *data) +{ + for (const char *p = data; *p; p++) + serial_put(*p); +} + +/** + * Universal print function + */ + +void log(const char *format, ...) +{ + char buf[1024] = { 0 }; + + va_list ap; + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + serial_print(buf); +} |