1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#include <stdint.h>
#include <stdarg.h>
#include <io.h>
#include <console.h>
void pause ( void ) {
printf ( "\nPress a key" );
getchar();
printf ( "\r \r" );
}
void more ( void ) {
printf ( "---more---" );
getchar();
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();
}
if ( ( index % 16 ) == 0 ) {
printf ( "%p [%lx] : %04x :", data + index,
virt_to_phys ( data + index ), index );
}
printf ( " %02x", data[index] );
}
printf ( "\n" );
}
#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
* of non-corruption.
*/
void guard_region ( void *region, size_t len ) {
uint32_t offset = 0;
len &= ~0x03;
for ( offset = 0; offset < len ; offset += 4 ) {
*((uint32_t *)(region + offset)) = GUARD_SYMBOL;
}
}
/* Check a region that has been guarded with guard_region() for
* corruption.
*/
int check_region ( void *region, size_t len ) {
uint8_t corrupted = 0;
uint8_t in_corruption = 0;
uint32_t offset = 0;
uint32_t test = 0;
len &= ~0x03;
for ( offset = 0; offset < len ; offset += 4 ) {
test = *((uint32_t *)(region + offset)) = GUARD_SYMBOL;
if ( ( in_corruption == 0 ) &&
( test != GUARD_SYMBOL ) ) {
/* Start of corruption */
if ( corrupted == 0 ) {
corrupted = 1;
printf ( "Region %p-%p (physical %#lx-%#lx) "
"corrupted\n",
region, region + len,
virt_to_phys ( region ),
virt_to_phys ( region + len ) );
}
in_corruption = 1;
printf ( "--- offset %#lx ", offset );
} else if ( ( in_corruption != 0 ) &&
( test == GUARD_SYMBOL ) ) {
/* End of corruption */
in_corruption = 0;
printf ( "to offset %#lx", offset );
}
}
if ( in_corruption != 0 ) {
printf ( "to offset %#x (end of region)\n", len-1 );
}
return corrupted;
}
#define NUM_AUTO_COLOURS 6
struct autocolour {
void * id;
unsigned long last_used;
};
static int autocolourise ( void *id ) {
static struct autocolour acs[NUM_AUTO_COLOURS];
static unsigned long use;
unsigned int i;
unsigned int oldest;
unsigned int oldest_last_used;
/* Increment usage iteration counter */
use++;
/* Scan through list for a currently assigned colour */
for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
if ( acs[i].id == id ) {
acs[i].last_used = use;
return i;
}
}
/* No colour found; evict the oldest from the list */
oldest = 0;
oldest_last_used = use;
for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
if ( acs[i].last_used < oldest_last_used ) {
oldest_last_used = acs[i].last_used;
oldest = i;
}
}
acs[oldest].id = id;
acs[oldest].last_used = use;
return oldest;
}
/** printf() for debugging with automatic colourisation
*
* @v id Message stream ID
* @v fmt printf() format
* @v ... printf() argument list
*/
void dbg_printf_autocolour ( void *id, const char *fmt, ... ) {
va_list args;
printf ( "\033[%dm", ( id ? ( 31 + autocolourise ( id ) ) : 0 ) );
va_start ( args, fmt );
vprintf ( fmt, args );
va_end ( args );
printf ( "\033[0m" );
}
|