Debug printing functions
This commit is contained in:
parent
a766726065
commit
d05ddfeab4
116
src/kernel/boot/debug.c
Normal file
116
src/kernel/boot/debug.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// TODO: Temporary declarations
|
||||||
|
void vga_write(char c);
|
||||||
|
void serial_write(int port, char c);
|
||||||
|
#define PORT_COM1 0
|
||||||
|
|
||||||
|
|
||||||
|
void num2str(char *buf, uint64_t num, uint64_t base)
|
||||||
|
{
|
||||||
|
if(num == 0)
|
||||||
|
{
|
||||||
|
buf[0] = '0';
|
||||||
|
buf[1] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64_t i=0, j=0;
|
||||||
|
char chars[] = "0123456789ABCDEF";
|
||||||
|
while(num > 0)
|
||||||
|
{
|
||||||
|
buf[i++] = chars[num%base];
|
||||||
|
num /= base;
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
while(j<i)
|
||||||
|
{
|
||||||
|
char t = buf[i];
|
||||||
|
buf[i--] = buf[j];
|
||||||
|
buf[j++] = t;
|
||||||
|
}
|
||||||
|
buf[i+j+1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void debug_putch(char c)
|
||||||
|
{
|
||||||
|
vga_write(c);
|
||||||
|
serial_write(PORT_COM1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_putsn(char *s, size_t n)
|
||||||
|
{
|
||||||
|
while(n--)
|
||||||
|
debug_putch(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_puts(char *s)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
while(s[len]) len++;
|
||||||
|
debug_putsn(s, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_vprintf(char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
if(!(*fmt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(*fmt != '%')
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
while(fmt[len] && fmt[len] != '%')
|
||||||
|
len++;
|
||||||
|
debug_putsn(fmt, len);
|
||||||
|
debug_vprintf(&fmt[len], args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
uint64_t base = 0;
|
||||||
|
switch(*fmt)
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
base = 2;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
base = 10;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
base = 16;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
debug_putch((char)va_arg(args, uint64_t));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
debug_puts(va_arg(args, char*));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug_putch('%');
|
||||||
|
fmt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(base)
|
||||||
|
{
|
||||||
|
uintmax_t number = va_arg(args, uintmax_t);
|
||||||
|
char buf[128];
|
||||||
|
num2str(buf, number, base);
|
||||||
|
debug_puts(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
debug_vprintf(fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_printf(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
debug_vprintf(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
117
src/kernel/boot/debug.tt
Normal file
117
src/kernel/boot/debug.tt
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// vim: ft=c
|
||||||
|
#include <ttest.h>
|
||||||
|
#include "debug.c"
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 16
|
||||||
|
char vga_recv[BUFFER_SIZE];
|
||||||
|
char serial_recv[BUFFER_SIZE];
|
||||||
|
|
||||||
|
BEFORE()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
vga_recv[i] = '\0';
|
||||||
|
serial_recv[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_write(char c)
|
||||||
|
{
|
||||||
|
static int i = 0;
|
||||||
|
vga_recv[i++] = c;
|
||||||
|
}
|
||||||
|
void serial_write(int port, char c)
|
||||||
|
{
|
||||||
|
(void)port;
|
||||||
|
static int i = 0;
|
||||||
|
serial_recv[i++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(putch_sends_character_to_vga)
|
||||||
|
{
|
||||||
|
char input = 'a';
|
||||||
|
debug_putch(input);
|
||||||
|
ASSERT_EQ_CHR(vga_recv[0], input);
|
||||||
|
}
|
||||||
|
TEST(putch_sends_character_to_serial)
|
||||||
|
{
|
||||||
|
char input = 'a';
|
||||||
|
debug_putch(input);
|
||||||
|
ASSERT_EQ_CHR(serial_recv[0], input);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(putsn_writes_string)
|
||||||
|
{
|
||||||
|
char *str = "hello";
|
||||||
|
debug_putsn(str, 5);
|
||||||
|
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(putsn_writes_correct_number_of_characters)
|
||||||
|
{
|
||||||
|
char *str = "1234567890";
|
||||||
|
debug_putsn(str, 5);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "12345", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(puts_writes_string)
|
||||||
|
{
|
||||||
|
char *str = "world";
|
||||||
|
debug_puts(str);
|
||||||
|
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(printf_prints_string)
|
||||||
|
{
|
||||||
|
char *str = "Hello, world!";
|
||||||
|
debug_printf(str);
|
||||||
|
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_does_not_print_percent)
|
||||||
|
{
|
||||||
|
debug_printf("123%d", 45);
|
||||||
|
ASSERT_NEQ_CHR(vga_recv[3], '%');
|
||||||
|
}
|
||||||
|
TEST(printf_prints_binary_number)
|
||||||
|
{
|
||||||
|
debug_printf("%b", 0x55aa);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "101010110101010", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_ocal_number)
|
||||||
|
{
|
||||||
|
debug_printf("%o", 8);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "10", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_decimal_number)
|
||||||
|
{
|
||||||
|
debug_printf("%d", 123);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "123", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_hexadecimal_number)
|
||||||
|
{
|
||||||
|
debug_printf("%x", 42);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "2A", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_char)
|
||||||
|
{
|
||||||
|
debug_printf("%c", 'X');
|
||||||
|
ASSERT_EQ_STR(vga_recv, "X", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_passed_string)
|
||||||
|
{
|
||||||
|
debug_printf("%s", "asdf");
|
||||||
|
ASSERT_EQ_STR(vga_recv, "asdf", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_keeps_printing_after_number)
|
||||||
|
{
|
||||||
|
debug_printf("%x123", 0);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "0123", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_prints_text_around_number)
|
||||||
|
{
|
||||||
|
debug_printf("ABC%dDEF", 0);
|
||||||
|
ASSERT_EQ_STR(vga_recv, "ABC0DEF", BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
TEST(printf_keeps_going_for_unknown_format_specifier)
|
||||||
|
{
|
||||||
|
debug_printf("%y");
|
||||||
|
ASSERT_EQ_STR(vga_recv, "%y", BUFFER_SIZE);
|
||||||
|
}
|
9
src/kernel/include/debug.h
Normal file
9
src/kernel/include/debug.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void debug_putch(char c);
|
||||||
|
void debug_putsn(char *s, size_t n);
|
||||||
|
void debug_puts(char *s);
|
||||||
|
void debug_vprintf(char *fmt, va_list args);
|
||||||
|
void debug_printf(char *fmt, ...);
|
Loading…
x
Reference in New Issue
Block a user