summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/debug.c105
-rw-r--r--src/include/compiler.h98
2 files changed, 171 insertions, 32 deletions
diff --git a/src/core/debug.c b/src/core/debug.c
index 9ef25b89b..4754bfdee 100644
--- a/src/core/debug.c
+++ b/src/core/debug.c
@@ -15,25 +15,58 @@ void more ( void ) {
printf ( "\r \r" );
}
-/* Produce a paged hex dump of the specified data and length */
-void hex_dump ( const unsigned char *data, const unsigned int len ) {
- unsigned int index;
- for ( index = 0; index < len; index++ ) {
- if ( ( index % 16 ) == 0 ) {
- printf ( "\n" );
- }
- if ( ( index % 368 ) == 352 ) {
- more();
+/**
+ * Print row of a hex dump with specified display address
+ *
+ * @v dispaddr Display address
+ * @v data Data to print
+ * @v len Length of data
+ * @v offset Starting offset within data
+ */
+static void dbg_hex_dump_da_row ( unsigned long dispaddr, const void *data,
+ unsigned long len, unsigned int offset ) {
+ const uint8_t *bytes = data;
+ unsigned int i;
+ uint8_t byte;
+
+ printf ( "%08lx :", ( dispaddr + offset ) );
+ for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
+ if ( i >= len ) {
+ printf ( " " );
+ continue;
}
- if ( ( index % 16 ) == 0 ) {
- printf ( "%p [%lx] : %04x :", data + index,
- virt_to_phys ( data + index ), index );
+ printf ( " %02x", bytes[i] );
+ }
+ printf ( " : " );
+ for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
+ if ( i >= len ) {
+ printf ( " " );
+ continue;
}
- printf ( " %02x", data[index] );
+ byte = bytes[i];
+ if ( ( byte < 0x20 ) || ( byte >= 0x7f ) )
+ byte = '.';
+ printf ( "%c", byte );
}
printf ( "\n" );
}
+/**
+ * Print hex dump with specified display address
+ *
+ * @v dispaddr Display address
+ * @v data Data to print
+ * @v len Length of data
+ */
+void dbg_hex_dump_da ( unsigned long dispaddr, const void *data,
+ unsigned long len ) {
+ unsigned int offset;
+
+ for ( offset = 0 ; offset < len ; offset += 16 ) {
+ dbg_hex_dump_da_row ( dispaddr, data, len, offset );
+ }
+}
+
#define GUARD_SYMBOL ( ( 'M' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | 'E' )
/* Fill a region with guard markers. We use a 4-byte pattern to make
* it less likely that check_region will find spurious 1-byte regions
@@ -87,14 +120,30 @@ int check_region ( void *region, size_t len ) {
return corrupted;
}
+/**
+ * Maximum number of separately coloured message streams
+ *
+ * Six is the realistic maximum; there are 8 basic ANSI colours, one
+ * of which will be the terminal default and one of which will be
+ * invisible on the terminal because it matches the background colour.
+ */
#define NUM_AUTO_COLOURS 6
+/** A colour assigned to an autocolourised debug message stream */
struct autocolour {
- void * id;
+ /** Message stream ID */
+ unsigned long stream;
+ /** Last recorded usage */
unsigned long last_used;
};
-static int autocolourise ( void *id ) {
+/**
+ * Choose colour index for debug autocolourisation
+ *
+ * @v stream Message stream ID
+ * @ret colour Colour ID
+ */
+static int dbg_autocolour ( unsigned long stream ) {
static struct autocolour acs[NUM_AUTO_COLOURS];
static unsigned long use;
unsigned int i;
@@ -106,7 +155,7 @@ static int autocolourise ( void *id ) {
/* Scan through list for a currently assigned colour */
for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
- if ( acs[i].id == id ) {
+ if ( acs[i].stream == stream ) {
acs[i].last_used = use;
return i;
}
@@ -121,23 +170,25 @@ static int autocolourise ( void *id ) {
oldest = i;
}
}
- acs[oldest].id = id;
+ acs[oldest].stream = stream;
acs[oldest].last_used = use;
return oldest;
}
-/** printf() for debugging with automatic colourisation
+/**
+ * Select automatic colour for debug messages
*
- * @v id Message stream ID
- * @v fmt printf() format
- * @v ... printf() argument list
+ * @v stream Message stream ID
*/
-void dbg_printf_autocolour ( void *id, const char *fmt, ... ) {
- va_list args;
+void dbg_autocolourise ( unsigned long stream ) {
+ printf ( "\033[%dm",
+ ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) );
+}
- printf ( "\033[%dm", ( id ? ( 31 + autocolourise ( id ) ) : 0 ) );
- va_start ( args, fmt );
- vprintf ( fmt, args );
- va_end ( args );
+/**
+ * Revert to normal colour
+ *
+ */
+void dbg_decolourise ( void ) {
printf ( "\033[0m" );
}
diff --git a/src/include/compiler.h b/src/include/compiler.h
index 49aaec632..8e5bd87d6 100644
--- a/src/include/compiler.h
+++ b/src/include/compiler.h
@@ -127,8 +127,10 @@ __asm__ ( ".equ\tDBGLVL, " DEBUG_SYMBOL_STR );
extern int __attribute__ (( format ( printf, 1, 2 ) ))
dbg_printf ( const char *fmt, ... ) asm ( "printf" );
-extern void __attribute__ (( format ( printf, 2, 3 ) ))
-dbg_printf_autocolour ( void *id, const char *fmt, ... );
+extern void dbg_autocolourise ( unsigned long id );
+extern void dbg_decolourise ( void );
+extern void dbg_hex_dump_da ( unsigned long dispaddr,
+ const void *data, unsigned long len );
/* Compatibility with existing Makefile */
#if DEBUG_SYMBOL >= 1
@@ -146,21 +148,107 @@ dbg_printf_autocolour ( void *id, const char *fmt, ... );
#define DBGLVL_EXTRA 2
#define DBG_EXTRA ( DBGLVL & DBGLVL_EXTRA )
+/**
+ * Print debugging message if we are at a certain debug level
+ *
+ * @v level Debug level
+ * @v ... printf() argument list
+ */
#define DBG_IF( level, ... ) do { \
if ( DBG_ ## level ) { \
dbg_printf ( __VA_ARGS__ ); \
} \
} while ( 0 )
-#define DBGC_IF( level, ... ) do { \
+/**
+ * Print a hex dump if we are at a certain debug level
+ *
+ * @v level Debug level
+ * @v dispaddr Display address
+ * @v data Data to print
+ * @v len Length of data
+ */
+#define DBG_HDA_IF( level, dispaddr, data, len ) do { \
+ if ( DBG_ ## level ) { \
+ union { \
+ unsigned long ul; \
+ typeof ( dispaddr ) raw; \
+ } da; \
+ da.raw = dispaddr; \
+ dbg_hex_dump_da ( da.ul, data, len ); \
+ } \
+ } while ( 0 )
+
+/**
+ * Print a hex dump if we are at a certain debug level
+ *
+ * @v level Debug level
+ * @v data Data to print
+ * @v len Length of data
+ */
+#define DBG_HD_IF( level, data, len ) do { \
+ DBG_HDA_IF ( level, data, data, len ); \
+ } while ( 0 )
+
+/**
+ * Select colour for debug messages if we are at a certain debug level
+ *
+ * @v level Debug level
+ * @v id Message stream ID
+ */
+#define DBG_AC_IF( level, id ) do { \
+ if ( DBG_ ## level ) { \
+ union { \
+ unsigned long ul; \
+ typeof ( id ) raw; \
+ } stream; \
+ stream.raw = id; \
+ dbg_autocolourise ( stream.ul ); \
+ } \
+ } while ( 0 )
+
+/**
+ * Revert colour for debug messages if we are at a certain debug level
+ *
+ * @v level Debug level
+ */
+#define DBG_DC_IF( level ) do { \
if ( DBG_ ## level ) { \
- dbg_printf_autocolour ( __VA_ARGS__ ); \
+ dbg_decolourise(); \
} \
} while ( 0 )
+/* Autocolourising versions of the DBGxxx_IF() macros */
+
+#define DBGC_IF( level, id, ... ) do { \
+ DBG_AC_IF ( level, id ); \
+ DBG_IF ( level, __VA_ARGS__ ); \
+ DBG_DC_IF ( level ); \
+ } while ( 0 )
+
+#define DBGC_HDA_IF( level, id, ... ) do { \
+ DBG_AC_IF ( level, id ); \
+ DBG_HDA_IF ( level, __VA_ARGS__ ); \
+ DBG_DC_IF ( level ); \
+ } while ( 0 )
+
+#define DBGC_HD_IF( level, id, ... ) do { \
+ DBG_AC_IF ( level, id ); \
+ DBG_HD_IF ( level, __VA_ARGS__ ); \
+ DBG_DC_IF ( level ); \
+ } while ( 0 )
+
+/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( LOG, ... )*/
+
#define DBG( ... ) DBG_IF ( LOG, __VA_ARGS__ )
-#define DBG2( ... ) DBG_IF ( EXTRA, __VA_ARGS__ )
+#define DBG_HDA( ... ) DBG_HDA_IF ( LOG, __VA_ARGS__ )
+#define DBG_HD( ... ) DBG_HD_IF ( LOG, __VA_ARGS__ )
#define DBGC( ... ) DBGC_IF ( LOG, __VA_ARGS__ )
+#define DBGC_HDA( ... ) DBGC_HDA_IF ( LOG, __VA_ARGS__ )
+#define DBGC_HD( ... ) DBGC_HD_IF ( LOG, __VA_ARGS__ )
+
+/* Backwards compatibility */
+#define DBG2( ... ) DBG_IF ( EXTRA, __VA_ARGS__ )
#if DEBUG_SYMBOL == 0
#define NDEBUG