diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-03-26 16:25:35 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-03-26 16:25:35 -0700 |
commit | 9eddd22a7b53b1d02fbae0d987df8af122924248 (patch) | |
tree | 882f5152880b0b1aa2d7a0619d30065acc69fb16 /gpxe/src/core/debug.c | |
parent | bbb8f15936b851e6a0ef6f7bb2c95197bff35994 (diff) | |
download | syslinux-9eddd22a7b53b1d02fbae0d987df8af122924248.tar.gz |
Add gPXE into the source tree; build unified imagesyslinux-3.70-pre7
Diffstat (limited to 'gpxe/src/core/debug.c')
-rw-r--r-- | gpxe/src/core/debug.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/gpxe/src/core/debug.c b/gpxe/src/core/debug.c new file mode 100644 index 00000000..09830420 --- /dev/null +++ b/gpxe/src/core/debug.c @@ -0,0 +1,195 @@ +#include <stdio.h> +#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" ); +} + +/** + * 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; + } + printf ( " %02x", bytes[i] ); + } + printf ( " : " ); + for ( i = offset ; i < ( offset + 16 ) ; i++ ) { + if ( i >= len ) { + printf ( " " ); + continue; + } + 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 + * 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 %#zx (end of region)\n", len-1 ); + } + 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 { + /** Message stream ID */ + unsigned long stream; + /** Last recorded usage */ + unsigned long last_used; +}; + +/** + * 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; + 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].stream == stream ) { + 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].stream = stream; + acs[oldest].last_used = use; + return oldest; +} + +/** + * Select automatic colour for debug messages + * + * @v stream Message stream ID + */ +void dbg_autocolourise ( unsigned long stream ) { + printf ( "\033[%dm", + ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) ); +} + +/** + * Revert to normal colour + * + */ +void dbg_decolourise ( void ) { + printf ( "\033[0m" ); +} |