Browse Source

Hex dumps are now integrated into the DBG() framework.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
3b77c7aa1b
2 changed files with 171 additions and 32 deletions
  1. 78
    27
      src/core/debug.c
  2. 93
    5
      src/include/compiler.h

+ 78
- 27
src/core/debug.c View File

@@ -15,25 +15,58 @@ void more ( void ) {
15 15
 	printf ( "\r          \r" );
16 16
 }
17 17
 
18
-/* Produce a paged hex dump of the specified data and length */
19
-void hex_dump ( const unsigned char *data, const unsigned int len ) {
20
-	unsigned int index;
21
-	for ( index = 0; index < len; index++ ) {
22
-		if ( ( index % 16 ) == 0 ) {
23
-			printf ( "\n" );
24
-		}
25
-		if ( ( index % 368 ) == 352 ) {
26
-			more();
18
+/**
19
+ * Print row of a hex dump with specified display address
20
+ *
21
+ * @v dispaddr		Display address
22
+ * @v data		Data to print
23
+ * @v len		Length of data
24
+ * @v offset		Starting offset within data
25
+ */
26
+static void dbg_hex_dump_da_row ( unsigned long dispaddr, const void *data,
27
+				  unsigned long len, unsigned int offset ) {
28
+	const uint8_t *bytes = data;
29
+	unsigned int i;
30
+	uint8_t byte;
31
+
32
+	printf ( "%08lx :", ( dispaddr + offset ) );
33
+	for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
34
+		if ( i >= len ) {
35
+			printf ( "   " );
36
+			continue;
27 37
 		}
28
-		if ( ( index % 16 ) == 0 ) {
29
-			printf ( "%p [%lx] : %04x :", data + index,
30
-				 virt_to_phys ( data + index ), index );
38
+		printf ( " %02x", bytes[i] );
39
+	}
40
+	printf ( " : " );
41
+	for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
42
+		if ( i >= len ) {
43
+			printf ( " " );
44
+			continue;
31 45
 		}
32
-		printf ( " %02x", data[index] );
46
+		byte = bytes[i];
47
+		if ( ( byte < 0x20 ) || ( byte >= 0x7f ) )
48
+			byte = '.';
49
+		printf ( "%c", byte );
33 50
 	}
34 51
 	printf ( "\n" );
35 52
 }
36 53
 
54
+/**
55
+ * Print hex dump with specified display address
56
+ *
57
+ * @v dispaddr		Display address
58
+ * @v data		Data to print
59
+ * @v len		Length of data
60
+ */
61
+void dbg_hex_dump_da ( unsigned long dispaddr, const void *data,
62
+		       unsigned long len ) {
63
+	unsigned int offset;
64
+
65
+	for ( offset = 0 ; offset < len ; offset += 16 ) {
66
+		dbg_hex_dump_da_row ( dispaddr, data, len, offset );
67
+	}
68
+}
69
+
37 70
 #define GUARD_SYMBOL ( ( 'M' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | 'E' )
38 71
 /* Fill a region with guard markers.  We use a 4-byte pattern to make
39 72
  * it less likely that check_region will find spurious 1-byte regions
@@ -87,14 +120,30 @@ int check_region ( void *region, size_t len ) {
87 120
 	return corrupted;
88 121
 }
89 122
 
123
+/**
124
+ * Maximum number of separately coloured message streams
125
+ *
126
+ * Six is the realistic maximum; there are 8 basic ANSI colours, one
127
+ * of which will be the terminal default and one of which will be
128
+ * invisible on the terminal because it matches the background colour.
129
+ */
90 130
 #define NUM_AUTO_COLOURS 6
91 131
 
132
+/** A colour assigned to an autocolourised debug message stream */
92 133
 struct autocolour {
93
-	void * id;
134
+	/** Message stream ID */
135
+	unsigned long stream;
136
+	/** Last recorded usage */
94 137
 	unsigned long last_used;
95 138
 };
96 139
 
97
-static int autocolourise ( void *id ) {
140
+/**
141
+ * Choose colour index for debug autocolourisation
142
+ *
143
+ * @v stream		Message stream ID
144
+ * @ret colour		Colour ID
145
+ */
146
+static int dbg_autocolour ( unsigned long stream ) {
98 147
 	static struct autocolour acs[NUM_AUTO_COLOURS];
99 148
 	static unsigned long use;
100 149
 	unsigned int i;
@@ -106,7 +155,7 @@ static int autocolourise ( void *id ) {
106 155
 
107 156
 	/* Scan through list for a currently assigned colour */
108 157
 	for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
109
-		if ( acs[i].id == id ) {
158
+		if ( acs[i].stream == stream ) {
110 159
 			acs[i].last_used = use;
111 160
 			return i;
112 161
 		}
@@ -121,23 +170,25 @@ static int autocolourise ( void *id ) {
121 170
 			oldest = i;
122 171
 		}
123 172
 	}
124
-	acs[oldest].id = id;
173
+	acs[oldest].stream = stream;
125 174
 	acs[oldest].last_used = use;
126 175
 	return oldest;
127 176
 }
128 177
 
129
-/** printf() for debugging with automatic colourisation
178
+/**
179
+ * Select automatic colour for debug messages
130 180
  *
131
- * @v id		Message stream ID
132
- * @v fmt		printf() format
133
- * @v ...		printf() argument list
181
+ * @v stream		Message stream ID
134 182
  */
135
-void dbg_printf_autocolour ( void *id, const char *fmt, ... ) {
136
-	va_list args;
183
+void dbg_autocolourise ( unsigned long stream ) {
184
+	printf ( "\033[%dm",
185
+		 ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) );
186
+}
137 187
 
138
-	printf ( "\033[%dm", ( id ? ( 31 + autocolourise ( id ) ) : 0 ) );
139
-	va_start ( args, fmt );
140
-	vprintf ( fmt, args );
141
-	va_end ( args );
188
+/**
189
+ * Revert to normal colour
190
+ *
191
+ */
192
+void dbg_decolourise ( void ) {
142 193
 	printf ( "\033[0m" );
143 194
 }

+ 93
- 5
src/include/compiler.h View File

@@ -127,8 +127,10 @@ __asm__ ( ".equ\tDBGLVL, " DEBUG_SYMBOL_STR );
127 127
 extern int __attribute__ (( format ( printf, 1, 2 ) )) 
128 128
 dbg_printf ( const char *fmt, ... ) asm ( "printf" );
129 129
 
130
-extern void __attribute__ (( format ( printf, 2, 3 ) )) 
131
-dbg_printf_autocolour ( void *id, const char *fmt, ... );
130
+extern void dbg_autocolourise ( unsigned long id );
131
+extern void dbg_decolourise ( void );
132
+extern void dbg_hex_dump_da ( unsigned long dispaddr,
133
+			      const void *data, unsigned long len );
132 134
 
133 135
 /* Compatibility with existing Makefile */
134 136
 #if DEBUG_SYMBOL >= 1
@@ -146,21 +148,107 @@ dbg_printf_autocolour ( void *id, const char *fmt, ... );
146 148
 #define DBGLVL_EXTRA	2
147 149
 #define DBG_EXTRA	( DBGLVL & DBGLVL_EXTRA )
148 150
 
151
+/**
152
+ * Print debugging message if we are at a certain debug level
153
+ *
154
+ * @v level		Debug level
155
+ * @v ...		printf() argument list
156
+ */
149 157
 #define DBG_IF( level, ... ) do {				\
150 158
 		if ( DBG_ ## level ) {				\
151 159
 			dbg_printf ( __VA_ARGS__ );		\
152 160
 		}						\
153 161
 	} while ( 0 )
154 162
 
155
-#define DBGC_IF( level, ... ) do {				\
163
+/**
164
+ * Print a hex dump if we are at a certain debug level
165
+ *
166
+ * @v level		Debug level
167
+ * @v dispaddr		Display address
168
+ * @v data		Data to print
169
+ * @v len		Length of data
170
+ */
171
+#define DBG_HDA_IF( level, dispaddr, data, len )  do {		\
172
+		if ( DBG_ ## level ) {				\
173
+			union {					\
174
+				unsigned long ul;		\
175
+				typeof ( dispaddr ) raw;	\
176
+			} da;					\
177
+			da.raw = dispaddr;			\
178
+			dbg_hex_dump_da ( da.ul, data, len );	\
179
+		}						\
180
+	} while ( 0 )
181
+
182
+/**
183
+ * Print a hex dump if we are at a certain debug level
184
+ *
185
+ * @v level		Debug level
186
+ * @v data		Data to print
187
+ * @v len		Length of data
188
+ */
189
+#define DBG_HD_IF( level, data, len ) do {			\
190
+		DBG_HDA_IF ( level, data, data, len );		\
191
+	} while ( 0 )
192
+
193
+/**
194
+ * Select colour for debug messages if we are at a certain debug level
195
+ *
196
+ * @v level		Debug level
197
+ * @v id		Message stream ID
198
+ */
199
+#define DBG_AC_IF( level, id ) do {				\
200
+		if ( DBG_ ## level ) {				\
201
+			union {					\
202
+				unsigned long ul;		\
203
+				typeof ( id ) raw;		\
204
+			} stream;				\
205
+			stream.raw = id;			\
206
+			dbg_autocolourise ( stream.ul );	\
207
+		}						\
208
+	} while ( 0 )
209
+
210
+/**
211
+ * Revert colour for debug messages if we are at a certain debug level
212
+ *
213
+ * @v level		Debug level
214
+ */
215
+#define DBG_DC_IF( level ) do {					\
156 216
 		if ( DBG_ ## level ) {				\
157
-			dbg_printf_autocolour ( __VA_ARGS__ );	\
217
+			dbg_decolourise();			\
158 218
 		}						\
159 219
 	} while ( 0 )
160 220
 
221
+/* Autocolourising versions of the DBGxxx_IF() macros */
222
+
223
+#define DBGC_IF( level, id, ... ) do {				\
224
+		DBG_AC_IF ( level, id );			\
225
+		DBG_IF ( level, __VA_ARGS__ );			\
226
+		DBG_DC_IF ( level );				\
227
+	} while ( 0 )
228
+
229
+#define DBGC_HDA_IF( level, id, ... ) do {			\
230
+		DBG_AC_IF ( level, id );			\
231
+		DBG_HDA_IF ( level, __VA_ARGS__ );		\
232
+		DBG_DC_IF ( level );				\
233
+	} while ( 0 )
234
+
235
+#define DBGC_HD_IF( level, id, ... ) do {			\
236
+		DBG_AC_IF ( level, id );			\
237
+		DBG_HD_IF ( level, __VA_ARGS__ );		\
238
+		DBG_DC_IF ( level );				\
239
+	} while ( 0 )
240
+
241
+/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( LOG, ... )*/
242
+
161 243
 #define DBG( ... )	DBG_IF ( LOG, __VA_ARGS__ )
162
-#define DBG2( ... )	DBG_IF ( EXTRA, __VA_ARGS__ )
244
+#define DBG_HDA( ... )	DBG_HDA_IF ( LOG, __VA_ARGS__ )
245
+#define DBG_HD( ... )	DBG_HD_IF ( LOG, __VA_ARGS__ )
163 246
 #define DBGC( ... )	DBGC_IF ( LOG, __VA_ARGS__ )
247
+#define DBGC_HDA( ... )	DBGC_HDA_IF ( LOG, __VA_ARGS__ )
248
+#define DBGC_HD( ... )	DBGC_HD_IF ( LOG, __VA_ARGS__ )
249
+
250
+/* Backwards compatibility */
251
+#define DBG2( ... )	DBG_IF ( EXTRA, __VA_ARGS__ )
164 252
 
165 253
 #if DEBUG_SYMBOL == 0
166 254
 #define NDEBUG

Loading…
Cancel
Save