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
++ ) {
40 ( ( ( i
% 16 ) == 8 ) ? '-' : ' ' ), bytes
[i
] );
43 for ( i
= offset
; i
< ( offset
+ 16 ) ; i
++ ) {
49 if ( ( byte
< 0x20 ) || ( byte
>= 0x7f ) )
51 printf ( "%c", byte
);
57 * Print hex dump with specified display address
59 * @v dispaddr Display address
60 * @v data Data to print
61 * @v len Length of data
63 void dbg_hex_dump_da ( unsigned long dispaddr
, const void *data
,
67 for ( offset
= 0 ; offset
< len
; offset
+= 16 ) {
68 dbg_hex_dump_da_row ( dispaddr
, data
, len
, offset
);
72 #define GUARD_SYMBOL ( ( 'M' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | 'E' )
73 /* Fill a region with guard markers. We use a 4-byte pattern to make
74 * it less likely that check_region will find spurious 1-byte regions
77 void guard_region ( void *region
, size_t len
) {
81 for ( offset
= 0; offset
< len
; offset
+= 4 ) {
82 *((uint32_t *)(region
+ offset
)) = GUARD_SYMBOL
;
86 /* Check a region that has been guarded with guard_region() for
89 int check_region ( void *region
, size_t len
) {
90 uint8_t corrupted
= 0;
91 uint8_t in_corruption
= 0;
96 for ( offset
= 0; offset
< len
; offset
+= 4 ) {
97 test
= *((uint32_t *)(region
+ offset
)) = GUARD_SYMBOL
;
98 if ( ( in_corruption
== 0 ) &&
99 ( test
!= GUARD_SYMBOL
) ) {
100 /* Start of corruption */
101 if ( corrupted
== 0 ) {
103 printf ( "Region %p-%p (physical %#lx-%#lx) "
105 region
, region
+ len
,
106 virt_to_phys ( region
),
107 virt_to_phys ( region
+ len
) );
110 printf ( "--- offset %#x ", offset
);
111 } else if ( ( in_corruption
!= 0 ) &&
112 ( test
== GUARD_SYMBOL
) ) {
113 /* End of corruption */
115 printf ( "to offset %#x", offset
);
119 if ( in_corruption
!= 0 ) {
120 printf ( "to offset %#zx (end of region)\n", len
-1 );
126 * Maximum number of separately coloured message streams
128 * Six is the realistic maximum; there are 8 basic ANSI colours, one
129 * of which will be the terminal default and one of which will be
130 * invisible on the terminal because it matches the background colour.
132 #define NUM_AUTO_COLOURS 6
134 /** A colour assigned to an autocolourised debug message stream */
136 /** Message stream ID */
137 unsigned long stream
;
138 /** Last recorded usage */
139 unsigned long last_used
;
143 * Choose colour index for debug autocolourisation
145 * @v stream Message stream ID
146 * @ret colour Colour ID
148 static int dbg_autocolour ( unsigned long stream
) {
149 static struct autocolour acs
[NUM_AUTO_COLOURS
];
150 static unsigned long use
;
153 unsigned int oldest_last_used
;
155 /* Increment usage iteration counter */
158 /* Scan through list for a currently assigned colour */
159 for ( i
= 0 ; i
< ( sizeof ( acs
) / sizeof ( acs
[0] ) ) ; i
++ ) {
160 if ( acs
[i
].stream
== stream
) {
161 acs
[i
].last_used
= use
;
166 /* No colour found; evict the oldest from the list */
168 oldest_last_used
= use
;
169 for ( i
= 0 ; i
< ( sizeof ( acs
) / sizeof ( acs
[0] ) ) ; i
++ ) {
170 if ( acs
[i
].last_used
< oldest_last_used
) {
171 oldest_last_used
= acs
[i
].last_used
;
175 acs
[oldest
].stream
= stream
;
176 acs
[oldest
].last_used
= use
;
181 * Select automatic colour for debug messages
183 * @v stream Message stream ID
185 void dbg_autocolourise ( unsigned long stream
) {
187 ( stream
? ( 31 + dbg_autocolour ( stream
) ) : 0 ) );
191 * Revert to normal colour
194 void dbg_decolourise ( void ) {
195 printf ( "\033[0m" );