Hex dumps are now integrated into the DBG() framework.
authorMichael Brown <mcb30@etherboot.org>
Sat, 13 Jan 2007 16:49:38 +0000 (16:49 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 13 Jan 2007 16:49:38 +0000 (16:49 +0000)
src/core/debug.c
src/include/compiler.h

index 9ef25b8..4754bfd 100644 (file)
@@ -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" );
 }
index 49aaec6..8e5bd87 100644 (file)
@@ -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