8 printf ( "\nPress a key" );
14 printf ( "---more---" );
20 * Print row of a hex dump with specified display address
22 * @v dispaddr Display address
23 * @v data Data to print
24 * @v len Length of data
25 * @v offset Starting offset within data
27 static void dbg_hex_dump_da_row ( unsigned long dispaddr
, const void *data
,
28 unsigned long len
, unsigned int offset
) {
29 const uint8_t *bytes
= data
;
33 printf ( "%08lx :", ( dispaddr
+ offset
) );
34 for ( i
= offset
; i
< ( offset
+ 16 ) ; i
++ ) {
39 printf ( " %02x", bytes
[i
] );
42 for ( i
= offset
; i
< ( offset
+ 16 ) ; i
++ ) {
48 if ( ( byte
< 0x20 ) || ( byte
>= 0x7f ) )
50 printf ( "%c", byte
);
56 * Print hex dump with specified display address
58 * @v dispaddr Display address
59 * @v data Data to print
60 * @v len Length of data
62 void dbg_hex_dump_da ( unsigned long dispaddr
, const void *data
,
66 for ( offset
= 0 ; offset
< len
; offset
+= 16 ) {
67 dbg_hex_dump_da_row ( dispaddr
, data
, len
, offset
);
71 #define GUARD_SYMBOL ( ( 'M' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | 'E' )
72 /* Fill a region with guard markers. We use a 4-byte pattern to make
73 * it less likely that check_region will find spurious 1-byte regions
76 void guard_region ( void *region
, size_t len
) {
80 for ( offset
= 0; offset
< len
; offset
+= 4 ) {
81 *((uint32_t *)(region
+ offset
)) = GUARD_SYMBOL
;
85 /* Check a region that has been guarded with guard_region() for
88 int check_region ( void *region
, size_t len
) {
89 uint8_t corrupted
= 0;
90 uint8_t in_corruption
= 0;
95 for ( offset
= 0; offset
< len
; offset
+= 4 ) {
96 test
= *((uint32_t *)(region
+ offset
)) = GUARD_SYMBOL
;
97 if ( ( in_corruption
== 0 ) &&
98 ( test
!= GUARD_SYMBOL
) ) {
99 /* Start of corruption */
100 if ( corrupted
== 0 ) {
102 printf ( "Region %p-%p (physical %#lx-%#lx) "
104 region
, region
+ len
,
105 virt_to_phys ( region
),
106 virt_to_phys ( region
+ len
) );
109 printf ( "--- offset %#lx ", offset
);
110 } else if ( ( in_corruption
!= 0 ) &&
111 ( test
== GUARD_SYMBOL
) ) {
112 /* End of corruption */
114 printf ( "to offset %#lx", offset
);
118 if ( in_corruption
!= 0 ) {
119 printf ( "to offset %#x (end of region)\n", len
-1 );
125 * Maximum number of separately coloured message streams
127 * Six is the realistic maximum; there are 8 basic ANSI colours, one
128 * of which will be the terminal default and one of which will be
129 * invisible on the terminal because it matches the background colour.
131 #define NUM_AUTO_COLOURS 6
133 /** A colour assigned to an autocolourised debug message stream */
135 /** Message stream ID */
136 unsigned long stream
;
137 /** Last recorded usage */
138 unsigned long last_used
;
142 * Choose colour index for debug autocolourisation
144 * @v stream Message stream ID
145 * @ret colour Colour ID
147 static int dbg_autocolour ( unsigned long stream
) {
148 static struct autocolour acs
[NUM_AUTO_COLOURS
];
149 static unsigned long use
;
152 unsigned int oldest_last_used
;
154 /* Increment usage iteration counter */
157 /* Scan through list for a currently assigned colour */
158 for ( i
= 0 ; i
< ( sizeof ( acs
) / sizeof ( acs
[0] ) ) ; i
++ ) {
159 if ( acs
[i
].stream
== stream
) {
160 acs
[i
].last_used
= use
;
165 /* No colour found; evict the oldest from the list */
167 oldest_last_used
= use
;
168 for ( i
= 0 ; i
< ( sizeof ( acs
) / sizeof ( acs
[0] ) ) ; i
++ ) {
169 if ( acs
[i
].last_used
< oldest_last_used
) {
170 oldest_last_used
= acs
[i
].last_used
;
174 acs
[oldest
].stream
= stream
;
175 acs
[oldest
].last_used
= use
;
180 * Select automatic colour for debug messages
182 * @v stream Message stream ID
184 void dbg_autocolourise ( unsigned long stream
) {
186 ( stream
? ( 31 + dbg_autocolour ( stream
) ) : 0 ) );
190 * Revert to normal colour
193 void dbg_decolourise ( void ) {
194 printf ( "\033[0m" );