diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-06-11 23:35:33 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-06-11 23:35:33 +0300 |
| commit | 62ee0f7e1936a9eccb55fa360a1dce223819e0b8 (patch) | |
| tree | 2c67698cac4e94cd7643f7acf19f1ada12f37472 /common/debug.c | |
| parent | 56fb0b774a8e89be1cb7ab1e5f464bbedd19fb22 (diff) | |
| download | kmi-62ee0f7e1936a9eccb55fa360a1dce223819e0b8.tar.gz kmi-62ee0f7e1936a9eccb55fa360a1dce223819e0b8.zip | |
continue documentation
Diffstat (limited to 'common/debug.c')
| -rw-r--r-- | common/debug.c | 226 |
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, ...) |
