iPXE
debug.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdio.h>
28#include <stdint.h>
29#include <stdarg.h>
30#include <ctype.h>
31#include <ipxe/console.h>
32
33/**
34 * Print debug message
35 *
36 * @v fmt Format string
37 * @v ... Arguments
38 */
39void dbg_printf ( const char *fmt, ... ) {
40 int saved_usage;
41 va_list args;
42
43 /* Mark console as in use for debugging messages */
45
46 /* Print message */
47 va_start ( args, fmt );
48 vprintf ( fmt, args );
49 va_end ( args );
50
51 /* Restore console usage */
53}
54
55/**
56 * Pause until a key is pressed
57 *
58 */
59void dbg_pause ( void ) {
60 dbg_printf ( "\nPress a key..." );
61 getchar();
62 dbg_printf ( "\r \r" );
63}
64
65/**
66 * Indicate more data to follow and pause until a key is pressed
67 *
68 */
69void dbg_more ( void ) {
70 dbg_printf ( "---more---" );
71 getchar();
72 dbg_printf ( "\r \r" );
73}
74
75/**
76 * Print row of a hex dump with specified display address
77 *
78 * @v dispaddr Display address
79 * @v data Data to print
80 * @v len Length of data
81 * @v offset Starting offset within data
82 */
83static void dbg_hex_dump_da_row ( unsigned long dispaddr, const void *data,
84 unsigned long len, unsigned int offset ) {
85 const uint8_t *bytes = data;
86 unsigned int i;
88
89 dbg_printf ( "%08lx :", ( dispaddr + offset ) );
90 for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
91 if ( i >= len ) {
92 dbg_printf ( " " );
93 continue;
94 }
95 dbg_printf ( "%c%02x",
96 ( ( ( i % 16 ) == 8 ) ? '-' : ' ' ), bytes[i] );
97 }
98 dbg_printf ( " : " );
99 for ( i = offset ; i < ( offset + 16 ) ; i++ ) {
100 if ( i >= len ) {
101 dbg_printf ( " " );
102 continue;
103 }
104 byte = bytes[i];
105 dbg_printf ( "%c", ( isprint ( byte ) ? byte : '.' ) );
106 }
107 dbg_printf ( "\n" );
108}
109
110/**
111 * Print hex dump with specified display address
112 *
113 * @v dispaddr Display address
114 * @v data Data to print
115 * @v len Length of data
116 */
117void dbg_hex_dump_da ( unsigned long dispaddr, const void *data,
118 unsigned long len ) {
119 unsigned int offset;
120
121 for ( offset = 0 ; offset < len ; offset += 16 ) {
122 dbg_hex_dump_da_row ( dispaddr, data, len, offset );
123 }
124}
125
126/**
127 * Base message stream colour
128 *
129 * We default to using 31 (red foreground) as the base colour.
130 */
131#ifndef DBGCOL_MIN
132#define DBGCOL_MIN 31
133#endif
134
135/**
136 * Maximum number of separately coloured message streams
137 *
138 * Six is the realistic maximum; there are 8 basic ANSI colours, one
139 * of which will be the terminal default and one of which will be
140 * invisible on the terminal because it matches the background colour.
141 */
142#ifndef DBGCOL_MAX
143#define DBGCOL_MAX ( DBGCOL_MIN + 6 - 1 )
144#endif
145
146/** A colour assigned to an autocolourised debug message stream */
148 /** Message stream ID */
149 unsigned long stream;
150 /** Last recorded usage */
151 unsigned long last_used;
152};
153
154/**
155 * Choose colour index for debug autocolourisation
156 *
157 * @v stream Message stream ID
158 * @ret colour Colour ID
159 */
160static int dbg_autocolour ( unsigned long stream ) {
161 static struct autocolour acs[ DBGCOL_MAX - DBGCOL_MIN + 1 ];
162 static unsigned long use;
163 unsigned int i;
164 unsigned int oldest;
165 unsigned int oldest_last_used;
166
167 /* Increment usage iteration counter */
168 use++;
169
170 /* Scan through list for a currently assigned colour */
171 for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
172 if ( acs[i].stream == stream ) {
173 acs[i].last_used = use;
174 return i;
175 }
176 }
177
178 /* No colour found; evict the oldest from the list */
179 oldest = 0;
180 oldest_last_used = use;
181 for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
182 if ( acs[i].last_used < oldest_last_used ) {
183 oldest_last_used = acs[i].last_used;
184 oldest = i;
185 }
186 }
187 acs[oldest].stream = stream;
188 acs[oldest].last_used = use;
189 return oldest;
190}
191
192/**
193 * Select automatic colour for debug messages
194 *
195 * @v stream Message stream ID
196 */
197void dbg_autocolourise ( unsigned long stream ) {
198
199 if ( DBGCOL_MIN ) {
200 dbg_printf ( "\033[%dm",
201 ( stream ?
202 ( DBGCOL_MIN + dbg_autocolour ( stream ) ) : 0));
203 }
204}
205
206/**
207 * Revert to normal colour
208 *
209 */
210void dbg_decolourise ( void ) {
211
212 if ( DBGCOL_MIN )
213 dbg_printf ( "\033[0m" );
214}
static unsigned int saved_usage
Definition ansi_screen.c:14
unsigned char uint8_t
Definition stdint.h:10
uint16_t offset
Offset to command line.
Definition bzimage.h:3
int getchar(void)
Read a single character from any console.
Definition console.c:86
Character types.
static int isprint(int character)
Check if character is printable.
Definition ctype.h:98
static void dbg_hex_dump_da_row(unsigned long dispaddr, const void *data, unsigned long len, unsigned int offset)
Print row of a hex dump with specified display address.
Definition debug.c:83
#define DBGCOL_MIN
Base message stream colour.
Definition debug.c:132
#define DBGCOL_MAX
Maximum number of separately coloured message streams.
Definition debug.c:143
static int dbg_autocolour(unsigned long stream)
Choose colour index for debug autocolourisation.
Definition debug.c:160
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define CONSOLE_USAGE_DEBUG
Debug messages.
Definition console.h:145
void dbg_pause(void)
Pause until a key is pressed.
Definition debug.c:59
void dbg_hex_dump_da(unsigned long dispaddr, const void *data, unsigned long len)
Print hex dump with specified display address.
Definition debug.c:117
void dbg_more(void)
Indicate more data to follow and pause until a key is pressed.
Definition debug.c:69
void dbg_decolourise(void)
Revert to normal colour.
Definition debug.c:210
void dbg_autocolourise(unsigned long stream)
Select automatic colour for debug messages.
Definition debug.c:197
void dbg_printf(const char *fmt,...)
Print debug message.
Definition debug.c:39
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
uint8_t bytes[64]
Definition ib_mad.h:5
User interaction.
static int console_set_usage(int usage)
Set console usage.
Definition console.h:188
unsigned char byte
Definition smc9000.h:38
#define va_end(ap)
Definition stdarg.h:10
#define va_start(ap, last)
Definition stdarg.h:8
__builtin_va_list va_list
Definition stdarg.h:7
A colour assigned to an autocolourised debug message stream.
Definition debug.c:147
unsigned long last_used
Last recorded usage.
Definition debug.c:151
unsigned long stream
Message stream ID.
Definition debug.c:149
int vprintf(const char *fmt, va_list args)
Write a formatted string to the console.
Definition vsprintf.c:450
int ssize_t const char * fmt
Definition vsprintf.h:73