- Add new type of debug print for windows loader
[reactos.git] / reactos / boot / freeldr / freeldr / debug.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21
22 #include <debug.h>
23
24 #ifdef DEBUG
25
26 //#define DEBUG_ALL
27 //#define DEBUG_INIFILE
28 //#define DEBUG_REACTOS
29 //#define DEBUG_CUSTOM
30 #define DEBUG_NONE
31
32 #if defined (DEBUG_ALL)
33 ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
34 DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
35 DPRINT_LINUX | DPRINT_HWDETECT;
36 #elif defined (DEBUG_INIFILE)
37 ULONG DebugPrintMask = DPRINT_INIFILE;
38 #elif defined (DEBUG_REACTOS)
39 ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY;
40 #elif defined (DEBUG_CUSTOM)
41 ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY |
42 DPRINT_REACTOS | DPRINT_WINDOWS | DPRINT_HWDETECT;
43 #else //#elif defined (DEBUG_NONE)
44 ULONG DebugPrintMask = 0;
45 #endif
46
47 #define SCREEN 1
48 #define RS232 2
49 #define BOCHS 4
50
51 #define COM1 1
52 #define COM2 2
53 #define COM3 3
54 #define COM4 4
55
56 #define BOCHS_OUTPUT_PORT 0xe9
57
58 ULONG DebugPort = RS232;
59 //ULONG DebugPort = SCREEN;
60 //ULONG DebugPort = BOCHS;
61 //ULONG DebugPort = SCREEN|BOCHS;
62 ULONG ComPort = COM1;
63 //ULONG BaudRate = 19200;
64 ULONG BaudRate = 115200;
65
66 BOOLEAN DebugStartOfLine = TRUE;
67
68 VOID DebugInit(VOID)
69 {
70 if (DebugPort & RS232)
71 {
72 Rs232PortInitialize(ComPort, BaudRate);
73 }
74 }
75
76 VOID DebugPrintChar(UCHAR Character)
77 {
78 if (Character == '\n')
79 {
80 DebugStartOfLine = TRUE;
81 }
82
83 if (DebugPort & RS232)
84 {
85 if (Character == '\n')
86 {
87 Rs232PortPutByte('\r');
88 }
89 Rs232PortPutByte(Character);
90 }
91 if (DebugPort & BOCHS)
92 {
93 WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
94 }
95 if (DebugPort & SCREEN)
96 {
97 MachConsPutChar(Character);
98 }
99 }
100
101 VOID DebugPrintHeader(ULONG Mask)
102 {
103 /* No header */
104 if (Mask == 0)
105 return;
106
107 switch (Mask)
108 {
109 case DPRINT_WARNING:
110 DebugPrintChar('W');
111 DebugPrintChar('A');
112 DebugPrintChar('R');
113 DebugPrintChar('N');
114 DebugPrintChar('I');
115 DebugPrintChar('N');
116 DebugPrintChar('G');
117 DebugPrintChar(':');
118 DebugPrintChar(' ');
119 break;
120 case DPRINT_MEMORY:
121 DebugPrintChar('M');
122 DebugPrintChar('E');
123 DebugPrintChar('M');
124 DebugPrintChar('O');
125 DebugPrintChar('R');
126 DebugPrintChar('Y');
127 DebugPrintChar(':');
128 DebugPrintChar(' ');
129 break;
130 case DPRINT_FILESYSTEM:
131 DebugPrintChar('F');
132 DebugPrintChar('I');
133 DebugPrintChar('L');
134 DebugPrintChar('E');
135 DebugPrintChar('S');
136 DebugPrintChar('Y');
137 DebugPrintChar('S');
138 DebugPrintChar(':');
139 DebugPrintChar(' ');
140 break;
141 case DPRINT_INIFILE:
142 DebugPrintChar('I');
143 DebugPrintChar('N');
144 DebugPrintChar('I');
145 DebugPrintChar('F');
146 DebugPrintChar('I');
147 DebugPrintChar('L');
148 DebugPrintChar('E');
149 DebugPrintChar(':');
150 DebugPrintChar(' ');
151 break;
152 case DPRINT_UI:
153 DebugPrintChar('U');
154 DebugPrintChar('I');
155 DebugPrintChar(':');
156 DebugPrintChar(' ');
157 break;
158 case DPRINT_DISK:
159 DebugPrintChar('D');
160 DebugPrintChar('I');
161 DebugPrintChar('S');
162 DebugPrintChar('K');
163 DebugPrintChar(':');
164 DebugPrintChar(' ');
165 break;
166 case DPRINT_CACHE:
167 DebugPrintChar('C');
168 DebugPrintChar('A');
169 DebugPrintChar('C');
170 DebugPrintChar('H');
171 DebugPrintChar('E');
172 DebugPrintChar(':');
173 DebugPrintChar(' ');
174 break;
175 case DPRINT_REGISTRY:
176 DebugPrintChar('R');
177 DebugPrintChar('E');
178 DebugPrintChar('G');
179 DebugPrintChar('I');
180 DebugPrintChar('S');
181 DebugPrintChar('T');
182 DebugPrintChar('R');
183 DebugPrintChar('Y');
184 DebugPrintChar(':');
185 DebugPrintChar(' ');
186 break;
187 case DPRINT_REACTOS:
188 DebugPrintChar('R');
189 DebugPrintChar('E');
190 DebugPrintChar('A');
191 DebugPrintChar('C');
192 DebugPrintChar('T');
193 DebugPrintChar('O');
194 DebugPrintChar('S');
195 DebugPrintChar(':');
196 DebugPrintChar(' ');
197 break;
198 case DPRINT_LINUX:
199 DebugPrintChar('L');
200 DebugPrintChar('I');
201 DebugPrintChar('N');
202 DebugPrintChar('U');
203 DebugPrintChar('X');
204 DebugPrintChar(':');
205 DebugPrintChar(' ');
206 break;
207 case DPRINT_WINDOWS:
208 DebugPrintChar('W');
209 DebugPrintChar('I');
210 DebugPrintChar('N');
211 DebugPrintChar('L');
212 DebugPrintChar('D');
213 DebugPrintChar('R');
214 DebugPrintChar(':');
215 DebugPrintChar(' ');
216 break;
217 case DPRINT_HWDETECT:
218 DebugPrintChar('H');
219 DebugPrintChar('W');
220 DebugPrintChar('D');
221 DebugPrintChar('E');
222 DebugPrintChar('T');
223 DebugPrintChar('E');
224 DebugPrintChar('C');
225 DebugPrintChar('T');
226 DebugPrintChar(':');
227 DebugPrintChar(' ');
228 break;
229 default:
230 DebugPrintChar('U');
231 DebugPrintChar('N');
232 DebugPrintChar('K');
233 DebugPrintChar('N');
234 DebugPrintChar('O');
235 DebugPrintChar('W');
236 DebugPrintChar('N');
237 DebugPrintChar(':');
238 DebugPrintChar(' ');
239 break;
240 }
241 }
242
243 VOID DebugPrint(ULONG Mask, char *format, ...)
244 {
245 va_list ap;
246 char Buffer[4096];
247 char *ptr = Buffer;
248
249 // Mask out unwanted debug messages
250 if (!(Mask & DebugPrintMask))
251 {
252 return;
253 }
254
255 // Print the header if we have started a new line
256 if (DebugStartOfLine)
257 {
258 DebugPrintHeader(Mask);
259 DebugStartOfLine = FALSE;
260 }
261
262 va_start(ap, format);
263 vsprintf(Buffer, format, ap);
264 va_end(ap);
265 while (*ptr)
266 {
267 DebugPrintChar(*ptr++);
268 }
269 }
270
271 VOID DebugPrint1(char *format, ...)
272 {
273 va_list ap;
274 char Buffer[4096];
275 char *ptr = Buffer;
276
277 va_start(ap, format);
278 vsprintf(Buffer, format, ap);
279 va_end(ap);
280 while (*ptr)
281 {
282 DebugPrintChar(*ptr++);
283 }
284 }
285
286 VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
287 {
288 PUCHAR BufPtr = (PUCHAR)Buffer;
289 ULONG Idx;
290 ULONG Idx2;
291
292 // Mask out unwanted debug messages
293 if (!(Mask & DebugPrintMask))
294 {
295 return;
296 }
297
298 DebugStartOfLine = FALSE; // We don't want line headers
299 DebugPrint(Mask, "Dumping buffer at 0x%x with length of %d bytes:\n", Buffer, Length);
300
301 for (Idx=0; Idx<Length; )
302 {
303 DebugStartOfLine = FALSE; // We don't want line headers
304
305 if (Idx < 0x0010)
306 {
307 DebugPrint(Mask, "000%x:\t", Idx);
308 }
309 else if (Idx < 0x0100)
310 {
311 DebugPrint(Mask, "00%x:\t", Idx);
312 }
313 else if (Idx < 0x1000)
314 {
315 DebugPrint(Mask, "0%x:\t", Idx);
316 }
317 else
318 {
319 DebugPrint(Mask, "%x:\t", Idx);
320 }
321
322 for (Idx2=0; Idx2<16; Idx2++,Idx++)
323 {
324 if (BufPtr[Idx] < 0x10)
325 {
326 DebugPrint(Mask, "0");
327 }
328 DebugPrint(Mask, "%x", BufPtr[Idx]);
329
330 if (Idx2 == 7)
331 {
332 DebugPrint(Mask, "-");
333 }
334 else
335 {
336 DebugPrint(Mask, " ");
337 }
338 }
339
340 Idx -= 16;
341 DebugPrint(Mask, " ");
342
343 for (Idx2=0; Idx2<16; Idx2++,Idx++)
344 {
345 if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80))
346 {
347 DebugPrint(Mask, "%c", BufPtr[Idx]);
348 }
349 else
350 {
351 DebugPrint(Mask, ".");
352 }
353 }
354
355 DebugPrint(Mask, "\n");
356 }
357 }
358
359 #endif // defined DEBUG