Home | History | Annotate | Download | only in core
      1 #include <stdio.h>
      2 #include <stdint.h>
      3 #include <stdarg.h>
      4 #include <gpxe/io.h>
      5 #include <console.h>
      6 
      7 void pause ( void ) {
      8 	printf ( "\nPress a key" );
      9 	getchar();
     10 	printf ( "\r           \r" );
     11 }
     12 
     13 void more ( void ) {
     14 	printf ( "---more---" );
     15 	getchar();
     16 	printf ( "\r          \r" );
     17 }
     18 
     19 /**
     20  * Print row of a hex dump with specified display address
     21  *
     22  * @v dispaddr		Display address
     23  * @v data		Data to print
     24  * @v len		Length of data
     25  * @v offset		Starting offset within data
     26  */
     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;
     30 	unsigned int i;
     31 	uint8_t byte;
     32 
     33 	printf ( "%08lx :", ( dispaddr + offset ) );
     34 	for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
     35 		if ( i >= len ) {
     36 			printf ( "   " );
     37 			continue;
     38 		}
     39 		printf ( "%c%02x",
     40 			 ( ( ( i % 16 ) == 8 ) ? '-' : ' ' ), bytes[i] );
     41 	}
     42 	printf ( " : " );
     43 	for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
     44 		if ( i >= len ) {
     45 			printf ( " " );
     46 			continue;
     47 		}
     48 		byte = bytes[i];
     49 		if ( ( byte < 0x20 ) || ( byte >= 0x7f ) )
     50 			byte = '.';
     51 		printf ( "%c", byte );
     52 	}
     53 	printf ( "\n" );
     54 }
     55 
     56 /**
     57  * Print hex dump with specified display address
     58  *
     59  * @v dispaddr		Display address
     60  * @v data		Data to print
     61  * @v len		Length of data
     62  */
     63 void dbg_hex_dump_da ( unsigned long dispaddr, const void *data,
     64 		       unsigned long len ) {
     65 	unsigned int offset;
     66 
     67 	for ( offset = 0 ; offset < len ; offset += 16 ) {
     68 		dbg_hex_dump_da_row ( dispaddr, data, len, offset );
     69 	}
     70 }
     71 
     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
     75  * of non-corruption.
     76  */
     77 void guard_region ( void *region, size_t len ) {
     78 	uint32_t offset = 0;
     79 
     80 	len &= ~0x03;
     81 	for ( offset = 0; offset < len ; offset += 4 ) {
     82 		*((uint32_t *)(region + offset)) = GUARD_SYMBOL;
     83 	}
     84 }
     85 
     86 /* Check a region that has been guarded with guard_region() for
     87  * corruption.
     88  */
     89 int check_region ( void *region, size_t len ) {
     90 	uint8_t corrupted = 0;
     91 	uint8_t in_corruption = 0;
     92 	uint32_t offset = 0;
     93 	uint32_t test = 0;
     94 
     95 	len &= ~0x03;
     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 ) {
    102 				corrupted = 1;
    103 				printf ( "Region %p-%p (physical %#lx-%#lx) "
    104 					 "corrupted\n",
    105 					 region, region + len,
    106 					 virt_to_phys ( region ),
    107 					 virt_to_phys ( region + len ) );
    108 			}
    109 			in_corruption = 1;
    110 			printf ( "--- offset %#x ", offset );
    111 		} else if ( ( in_corruption != 0 ) &&
    112 			    ( test == GUARD_SYMBOL ) ) {
    113 			/* End of corruption */
    114 			in_corruption = 0;
    115 			printf ( "to offset %#x", offset );
    116 		}
    117 
    118 	}
    119 	if ( in_corruption != 0 ) {
    120 		printf ( "to offset %#zx (end of region)\n", len-1 );
    121 	}
    122 	return corrupted;
    123 }
    124 
    125 /**
    126  * Maximum number of separately coloured message streams
    127  *
    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.
    131  */
    132 #define NUM_AUTO_COLOURS 6
    133 
    134 /** A colour assigned to an autocolourised debug message stream */
    135 struct autocolour {
    136 	/** Message stream ID */
    137 	unsigned long stream;
    138 	/** Last recorded usage */
    139 	unsigned long last_used;
    140 };
    141 
    142 /**
    143  * Choose colour index for debug autocolourisation
    144  *
    145  * @v stream		Message stream ID
    146  * @ret colour		Colour ID
    147  */
    148 static int dbg_autocolour ( unsigned long stream ) {
    149 	static struct autocolour acs[NUM_AUTO_COLOURS];
    150 	static unsigned long use;
    151 	unsigned int i;
    152 	unsigned int oldest;
    153 	unsigned int oldest_last_used;
    154 
    155 	/* Increment usage iteration counter */
    156 	use++;
    157 
    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;
    162 			return i;
    163 		}
    164 	}
    165 
    166 	/* No colour found; evict the oldest from the list */
    167 	oldest = 0;
    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;
    172 			oldest = i;
    173 		}
    174 	}
    175 	acs[oldest].stream = stream;
    176 	acs[oldest].last_used = use;
    177 	return oldest;
    178 }
    179 
    180 /**
    181  * Select automatic colour for debug messages
    182  *
    183  * @v stream		Message stream ID
    184  */
    185 void dbg_autocolourise ( unsigned long stream ) {
    186 	printf ( "\033[%dm",
    187 		 ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) );
    188 }
    189 
    190 /**
    191  * Revert to normal colour
    192  *
    193  */
    194 void dbg_decolourise ( void ) {
    195 	printf ( "\033[0m" );
    196 }
    197