aboutsummaryrefslogtreecommitdiff
path: root/common/debug.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-06-11 23:35:33 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-06-11 23:35:33 +0300
commit62ee0f7e1936a9eccb55fa360a1dce223819e0b8 (patch)
tree2c67698cac4e94cd7643f7acf19f1ada12f37472 /common/debug.c
parent56fb0b774a8e89be1cb7ab1e5f464bbedd19fb22 (diff)
downloadkmi-62ee0f7e1936a9eccb55fa360a1dce223819e0b8.tar.gz
kmi-62ee0f7e1936a9eccb55fa360a1dce223819e0b8.zip
continue documentation
Diffstat (limited to 'common/debug.c')
-rw-r--r--common/debug.c226
1 files changed, 193 insertions, 33 deletions
diff --git a/common/debug.c b/common/debug.c
index 2bcdf7f..924c0dd 100644
--- a/common/debug.c
+++ b/common/debug.c
@@ -14,10 +14,18 @@
#include <stdarg.h>
#if defined(DEBUG)
-static struct dbg_info {
+
+/** Debug context structure. */
+struct dbg_info {
+ /** Address of serial device in memory. */
pm_t dbg_ptr;
+
+ /** Type of serial device. */
enum serial_dev dev;
-} dbg_info = (struct dbg_info){ 0 };
+};
+
+/** Static debugging information. */
+static struct dbg_info dbg_info = (struct dbg_info){ 0 };
/* forward declarations. */
static void __setup_dbg(pm_t pt, enum serial_dev dev);
@@ -43,43 +51,78 @@ void setup_io_dbg(struct vmem *b)
* try to implement some kind of basic driver subsystem, but this is good enough
* for now. */
+/** NS16550A and compatible serial drivers. */
struct __packed ns16550a {
- union {
- struct {
- uint8_t data;
- uint8_t irq;
- };
+ /** Receiver buffer/transmitter holding register. */
+ uint8_t data;
- struct {
- uint8_t lsbr;
- uint8_t msbr;
- };
- };
+ /** Interrupt enable register. */
+ uint8_t irq;
+ /** Interrupt identity/FIFO control register. */
uint8_t irq_id;
+
+ /** Line control register. */
uint8_t lcr;
+
+ /** Modem control register. */
uint8_t mcr;
+
+ /** Line status register. */
uint8_t lsr;
+
+ /** Modem status register. */
uint8_t msr;
+
+ /** Scratch register. */
uint8_t scr;
};
+/** Line status data ready. */
#define LSR_DR (1 << 0)
+
+/** Line status overrun error. */
#define LSR_OE (1 << 1)
+
+/** Line status parity error. */
#define LSR_PE (1 << 2)
+
+/** Line status framing error. */
#define LSR_FE (1 << 3)
+
+/** Line status break interrupt. */
#define LSR_BI (1 << 4)
+
+/** Line status transmitter holding register. */
#define LSR_THRE (1 << 5)
+
+/** Line status transmitter empty. */
#define LSR_TEMT (1 << 6)
+
+/** Line status error in RCVR FIFO. */
#define LSR_ERR (1 << 7)
+/**
+ * Address of ns16550a port. If other serial drivers are added, this should
+ * maybe be made a void *.
+ */
static struct ns16550a *port = 0;
+/**
+ * Serial transmitter empty.
+ *
+ * @return \c 0 if not empty, non-zero otherwise.
+ */
static int __serial_tx_empty()
{
return port->lsr & LSR_THRE;
}
+/**
+ * Put character out onto serial lines.
+ *
+ * @param c Character to output.
+ */
static void __putchar(char c)
{
if (!port)
@@ -91,6 +134,12 @@ static void __putchar(char c)
port->data = c;
}
+/**
+ * Convert serial device name (from FDT) to serial device enumerator.
+ *
+ * @param dev_name Device name string.
+ * @return Corresponding enumerator value.
+ */
static enum serial_dev __serial_dev_enum(const char *dev_name)
{
if (strncmp("ns16550", dev_name, 7) == 0)
@@ -99,6 +148,12 @@ static enum serial_dev __serial_dev_enum(const char *dev_name)
return -1;
}
+/**
+ * Get debugging info from FDT.
+ *
+ * @param fdt Global FDT pointer.
+ * @return Filled \ref dbg_info structure.
+ */
static struct dbg_info __dbg_from_fdt(const void *fdt)
{
int chosen_offset = fdt_path_offset(fdt, "/chosen");
@@ -122,6 +177,12 @@ static struct dbg_info __dbg_from_fdt(const void *fdt)
return (struct dbg_info){ dbg_ptr, dev };
}
+/**
+ * Set static port.
+ *
+ * @param pt Address of memory mapped serial device.
+ * @param dev Chosen device.
+ */
void __setup_dbg(vm_t pt, enum serial_dev dev)
{
switch (dev) {
@@ -134,29 +195,71 @@ void __setup_dbg(vm_t pt, enum serial_dev dev)
* defaults (set by U-boot) seem to work alright */
}
+/** Printf formatting left align flag. */
#define LEFT_FLAG (1 << 0)
+
+/** Printf formatting explicit sign flag. */
#define SIGN_FLAG (1 << 1)
+
+/** Printf formatting hash sign flag. */
#define HASH_FLAG (1 << 2)
+
+/** Printf formatting zero padding flag. */
#define ZERO_FLAG (1 << 3)
+
+/** Printf formatting ' flag. */
#define FMT_FLAG (1 << 4)
+
+/** Printf formatting space flag. */
#define SPACE_FLAG (1 << 5)
+
+/** Printf formatting long specifier flag. */
#define LONG_FLAG (1 << 6)
+
+/** Printf formatting long long specifier flag. */
#define LLONG_FLAG (1 << 7)
+
+/** Printf formatting short flag. */
#define SHORT_FLAG (1 << 8)
+
+/** Printf formatting char flag. */
#define CHAR_FLAG (1 << 9)
+
+/** Printf precision flag. */
#define PRECS_FLAG (1 << 11)
+
+/** Printf unsigned flag. */
#define UNSIGN_FLAG (1 << 12)
+
+/** Printf width flag. */
#define WIDTH_FLAG (1 << 13)
+
+/** Printf padding flag. */
#define PAD_FLAG (1 << 14)
+/** Printf continue flag. */
#define CONT 1
+
+/** Printf stop flag. */
#define STOP 0
+/**
+ * Check if character is ASCII decimal digit.
+ *
+ * @param c Character to check.
+ * @return \c true if character is ASCII decimal digit, \c false otherwise.
+ */
static bool __is_digit(char c)
{
return (c >= '0') && (c <= '9');
}
+/**
+ * Convert string to corresponding number (assuming int).
+ *
+ * @param s Number string.
+ * @return Corresponding number.
+ */
static int __atoi(const char *s)
{
unsigned int i = 0;
@@ -167,6 +270,25 @@ static int __atoi(const char *s)
return i;
}
+/**
+ * Calculate signed char from value using type interpretation.
+ *
+ * @param x Type to interpret value as.
+ * @param value Value to interpret.
+ * @param base Base to interpret value in.
+ */
+#define handle_type(x, value, base) \
+ c = (x)value % (x)base; \
+ value = (x)value / (x)base;
+/**
+ * Convert number to string length.
+ *
+ * @param value Number to print.
+ * @param base Base to print in.
+ * @param flags Flags to output.
+ * @param print Print number as well.
+ * @return Length of corresponding string.
+ */
static size_t __integral_val(ssize_t value, size_t base, size_t flags,
bool print)
{
@@ -174,22 +296,19 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags,
size_t ret = 0;
signed char c = 0;
-#define handle_type(x) \
- c = (x)value % (x)base; \
- value = (x)value / (x)base;
if (!is_set(flags, UNSIGN_FLAG)) {
/* signed values, only with i format */
if (is_set(flags, LLONG_FLAG)) {
- handle_type(signed long long);
+ handle_type(signed long long, value, base);
} else if (is_set(flags, LONG_FLAG)) {
- handle_type(signed long);
+ handle_type(signed long, value, base);
} else if (is_set(flags, SHORT_FLAG)) {
- handle_type(signed short);
+ handle_type(signed short, value, base);
} else if (is_set(flags, CHAR_FLAG)) {
- handle_type(signed char);
+ handle_type(signed char, value, base);
} else {
- handle_type(signed int);
+ handle_type(signed int, value, base);
}
/* convert negative results into actual characters */
@@ -198,20 +317,18 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags,
} else {
/* unsigned values, everything else */
if (is_set(flags, LLONG_FLAG)) {
- handle_type(unsigned long long);
+ handle_type(unsigned long long, value, base);
} else if (is_set(flags, LONG_FLAG)) {
- handle_type(unsigned long);
+ handle_type(unsigned long, value, base);
} else if (is_set(flags, SHORT_FLAG)) {
- handle_type(unsigned short);
+ handle_type(unsigned short, value, base);
} else if (is_set(flags, CHAR_FLAG)) {
- handle_type(unsigned char);
+ handle_type(unsigned char, value, base);
} else {
- handle_type(unsigned int);
+ handle_type(unsigned int, value, base);
}
}
-#undef handle_type
-
if (base == 16)
c += c > 9 ? 'a' - 10 : '0';
else
@@ -226,6 +343,12 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags,
return ret + 1;
}
+/**
+ * Print prefix corresponding to \c base.
+ *
+ * @param base Base to integer.
+ * @return Length of prefix as string.
+ */
static size_t __print_prefix(size_t base)
{
size_t i = 0;
@@ -252,6 +375,13 @@ static size_t __print_prefix(size_t base)
return i;
}
+/**
+ * Print padding.
+ *
+ * @param pad Number of characters to print.
+ * @param pad_char Character to use as padding.
+ * @return Number of characters printed.
+ */
static size_t __print_padding(size_t pad, char pad_char)
{
size_t i = 0;
@@ -262,6 +392,13 @@ static size_t __print_padding(size_t pad, char pad_char)
return i;
}
+/**
+ * Print signed value.
+ *
+ * @param value Value to print.
+ * @param flags Flags to printing.
+ * @return Number of characters written.
+ */
static size_t __print_sign(ssize_t value, size_t flags)
{
if (is_set(flags, LLONG_FLAG))
@@ -286,12 +423,38 @@ static size_t __print_sign(ssize_t value, size_t flags)
return 0;
}
+/**
+ * Length of integral value as string.
+ *
+ * @param value Value to convert to string.
+ * @param base Base to interpret value as.
+ * @param flags Formatting flags.
+ * @return \see __integral_val().
+ */
+#define __integral_len(value, base, flags) __integral_val((value), (base), (flags), false)
+
+/**
+ * Print integral value as string.
+ *
+ * @param value Value to convert to string.
+ * @param base Base to interpret value as.
+ * @param flags Formatting flags.
+ * @return \see __integral_val().
+ */
+#define __integral_print(value, base, flags) __integral_val((value), (base), (flags), true)
+
+/**
+ * Print integral value.
+ *
+ * @param value Value to print.
+ * @param base Base to print value in.
+ * @param flags Flags to printing.
+ * @param width Minimum width of printing.
+ * @return Number of characters written.
+ */
static size_t __print_integral(ssize_t value, size_t base, size_t flags,
size_t width)
{
-#define __integral_len(a, b, c) __integral_val((a), (b), (c), false)
-#define __integral_print(a, b, c) __integral_val((a), (b), (c), true)
-
size_t ret = 0;
size_t raw_len = __integral_len(value, base, flags);
ssize_t pad = is_set(flags, PAD_FLAG) ? width - raw_len : 0;
@@ -338,9 +501,6 @@ static size_t __print_integral(ssize_t value, size_t base, size_t flags,
}
return ret;
-
-#undef __integral_len
-#undef __integral_print
}
void dbg(const char *fmt, ...)