2 * AcessOS Microkernel Version
8 #define DEBUG_MAX_LINE_LEN 256
9 #define LOCK_DEBUG_OUTPUT 1 // Avoid interleaving of output lines?
10 #define TRACE_TO_KTERM 0 // Send ENTER/DEBUG/LEAVE to debug?
13 extern void Threads_Dump(void);
14 extern void Heap_Dump(void)
16 extern void KernelPanic_SetMode(void);
17 extern void KernelPanic_PutChar(char Ch);
18 extern void IPStack_SendDebugText(const char *Text);
21 static void Debug_Putchar(char ch);
22 static void Debug_Puts(int bUseKTerm, const char *Str);
23 void Debug_DbgOnlyFmt(const char *format, va_list args);
24 void Debug_FmtS(int bUseKTerm, const char *format, ...);
25 void Debug_Fmt(int bUseKTerm, const char *format, va_list args);
26 void Debug_SetKTerminal(const char *File);
27 void LogFV(const char *Fmt, va_list args);
31 int giDebug_KTerm = -1;
32 int gbDebug_IsKPanic = 0;
33 volatile int gbInPutChar = 0;
35 tShortSpinlock glDebug_Lock;
37 // - Disabled because it breaks shit
38 int gbSendNetworkDebug = 0;
41 static void Debug_Putchar(char ch)
43 Debug_PutCharDebug(ch);
45 if( gbDebug_IsKPanic )
46 KernelPanic_PutChar(ch);
48 if( gbDebug_IsKPanic < 2 )
50 if(gbInPutChar) return ;
52 if(giDebug_KTerm != -1)
53 VFS_Write(giDebug_KTerm, 1, &ch);
57 if( gbSendNetworkDebug )
59 char str[2] = {ch, 0};
60 IPStack_SendDebugText(str);
64 static void Debug_Puts(int UseKTerm, const char *Str)
68 Debug_PutStringDebug(Str);
70 if( gbDebug_IsKPanic )
72 for( len = 0; Str[len]; len ++ )
73 KernelPanic_PutChar( Str[len] );
76 for( len = 0; Str[len]; len ++ );
78 if( gbSendNetworkDebug )
79 IPStack_SendDebugText(Str);
81 // Output to the kernel terminal
82 if( UseKTerm && gbDebug_IsKPanic < 2 && giDebug_KTerm != -1)
84 if(gbInPutChar) return ;
86 VFS_Write(giDebug_KTerm, len, Str);
91 void Debug_DbgOnlyFmt(const char *format, va_list args)
93 Debug_Fmt(0, format, args);
96 void Debug_Fmt(int bUseKTerm, const char *format, va_list args)
98 char buf[DEBUG_MAX_LINE_LEN];
100 buf[DEBUG_MAX_LINE_LEN-1] = 0;
101 /*len = */vsnprintf(buf, DEBUG_MAX_LINE_LEN-1, format, args);
102 //if( len < DEBUG_MAX_LINE )
104 Debug_Puts(bUseKTerm, buf);
108 void Debug_FmtS(int bUseKTerm, const char *format, ...)
111 va_start(args, format);
112 Debug_Fmt(bUseKTerm, format, args);
116 void Debug_KernelPanic(void)
118 #if LOCK_DEBUG_OUTPUT
119 SHORTREL(&glDebug_Lock);
122 KernelPanic_SetMode();
126 * \fn void LogF(const char *Msg, ...)
127 * \brief Raw debug log (no new line, no prefix)
129 void LogF(const char *Fmt, ...)
133 #if LOCK_DEBUG_OUTPUT
134 SHORTLOCK(&glDebug_Lock);
139 Debug_Fmt(1, Fmt, args);
143 #if LOCK_DEBUG_OUTPUT
144 SHORTREL(&glDebug_Lock);
148 * \fn void Debug(const char *Msg, ...)
149 * \brief Print only to the debug channel (not KTerm)
151 void Debug(const char *Fmt, ...)
155 #if LOCK_DEBUG_OUTPUT
156 if(!CPU_HAS_LOCK(&glDebug_Lock)) SHORTLOCK(&glDebug_Lock);
159 Debug_Puts(0, "Debug: ");
161 Debug_DbgOnlyFmt(Fmt, args);
163 Debug_PutCharDebug('\r');
164 Debug_PutCharDebug('\n');
165 #if LOCK_DEBUG_OUTPUT
166 SHORTREL(&glDebug_Lock);
171 void LogFV(const char *Fmt, va_list args)
173 #if LOCK_DEBUG_OUTPUT
174 SHORTLOCK(&glDebug_Lock);
177 Debug_Fmt(1, Fmt, args);
179 #if LOCK_DEBUG_OUTPUT
180 SHORTREL(&glDebug_Lock);
184 void LogV(const char *Fmt, va_list args)
186 #if LOCK_DEBUG_OUTPUT
187 SHORTLOCK(&glDebug_Lock);
190 Debug_Puts(1, "Log: ");
191 Debug_Fmt(1, Fmt, args);
192 Debug_Puts(1, "\r\n");
194 #if LOCK_DEBUG_OUTPUT
195 SHORTREL(&glDebug_Lock);
200 * \fn void Log(const char *Msg, ...)
202 void Log(const char *Fmt, ...)
210 void Warning(const char *Fmt, ...)
214 #if LOCK_DEBUG_OUTPUT
215 SHORTLOCK(&glDebug_Lock);
218 Debug_Puts(1, "Warning: ");
220 Debug_Fmt(1, Fmt, args);
225 #if LOCK_DEBUG_OUTPUT
226 SHORTREL(&glDebug_Lock);
229 void Panic(const char *Fmt, ...)
233 #if LOCK_DEBUG_OUTPUT
234 if( !CPU_HAS_LOCK(&glDebug_Lock) )
235 SHORTLOCK(&glDebug_Lock);
237 // And never SHORTREL
241 Debug_Puts(1, "Panic: ");
243 Debug_Fmt(1, Fmt, args);
254 void Debug_SetKTerminal(const char *File)
257 if(giDebug_KTerm != -1) {
262 tmp = VFS_Open(File, VFS_OPENFLAG_WRITE);
263 // Log_Log("Debug", "Opened '%s' as 0x%x", File, tmp);
265 // Log_Log("Debug", "Returning to %p", __builtin_return_address(0));
268 void Debug_Enter(const char *FuncName, const char *ArgTypes, ...)
273 tTID tid = Threads_GetTID();
275 #if LOCK_DEBUG_OUTPUT
276 SHORTLOCK(&glDebug_Lock);
281 va_start(args, ArgTypes);
283 Debug_FmtS(TRACE_TO_KTERM, "%014lli ", now());
284 while(i--) Debug_Puts(TRACE_TO_KTERM, " ");
286 Debug_Puts(TRACE_TO_KTERM, FuncName);
287 Debug_FmtS(TRACE_TO_KTERM, "[%i]", tid);
288 Debug_Puts(TRACE_TO_KTERM, ": (");
292 pos = strpos(ArgTypes, ' ');
293 if(pos == -1 || pos > 1) {
295 Debug_Puts(TRACE_TO_KTERM, ArgTypes+1);
297 Debug_FmtS(TRACE_TO_KTERM, "%.*s", pos-1, ArgTypes+1);
299 Debug_Puts(TRACE_TO_KTERM, "=");
303 case 'p': Debug_FmtS(TRACE_TO_KTERM, "%p", va_arg(args, void*)); break;
304 case 'P': Debug_FmtS(TRACE_TO_KTERM, "%P", va_arg(args, tPAddr)); break;
305 case 's': Debug_FmtS(TRACE_TO_KTERM, "'%s'", va_arg(args, char*)); break;
306 case 'i': Debug_FmtS(TRACE_TO_KTERM, "%i", va_arg(args, int)); break;
307 case 'u': Debug_FmtS(TRACE_TO_KTERM, "%u", va_arg(args, Uint)); break;
308 case 'x': Debug_FmtS(TRACE_TO_KTERM, "0x%x", va_arg(args, Uint)); break;
309 case 'b': Debug_FmtS(TRACE_TO_KTERM, "0b%b", va_arg(args, Uint)); break;
310 case 'X': Debug_FmtS(TRACE_TO_KTERM, "0x%llx", va_arg(args, Uint64)); break; // Extended (64-Bit)
311 case 'B': Debug_FmtS(TRACE_TO_KTERM, "0b%llb", va_arg(args, Uint64)); break; // Extended (64-Bit)
314 Debug_Puts(TRACE_TO_KTERM, ", ");
318 ArgTypes = &ArgTypes[pos+1];
322 Debug_Puts(TRACE_TO_KTERM, ")\r\n");
324 #if LOCK_DEBUG_OUTPUT
325 SHORTREL(&glDebug_Lock);
329 void Debug_Log(const char *FuncName, const char *Fmt, ...)
332 int i = gDebug_Level;
333 tTID tid = Threads_GetTID();
335 #if LOCK_DEBUG_OUTPUT
336 SHORTLOCK(&glDebug_Lock);
339 Debug_FmtS(TRACE_TO_KTERM, "%014lli ", now());
340 while(i--) Debug_Puts(TRACE_TO_KTERM, " ");
342 Debug_Puts(TRACE_TO_KTERM, FuncName);
343 Debug_FmtS(TRACE_TO_KTERM, "[%i]", tid);
344 Debug_Puts(TRACE_TO_KTERM, ": ");
347 Debug_Fmt(TRACE_TO_KTERM, Fmt, args);
350 Debug_Puts(TRACE_TO_KTERM, "\r\n");
352 #if LOCK_DEBUG_OUTPUT
353 SHORTREL(&glDebug_Lock);
357 void Debug_Leave(const char *FuncName, char RetType, ...)
361 tTID tid = Threads_GetTID();
363 #if LOCK_DEBUG_OUTPUT
364 SHORTLOCK(&glDebug_Lock);
369 va_start(args, RetType);
375 Debug_FmtS(TRACE_TO_KTERM, "%014lli ", now());
377 while(i--) Debug_Puts(TRACE_TO_KTERM, " ");
379 Debug_Puts(TRACE_TO_KTERM, FuncName);
380 Debug_FmtS(TRACE_TO_KTERM, "[%i]", tid);
381 Debug_Puts(TRACE_TO_KTERM, ": RETURN");
385 Debug_Puts(TRACE_TO_KTERM, "\r\n");
386 #if LOCK_DEBUG_OUTPUT
387 SHORTREL(&glDebug_Lock);
394 case 'n': Debug_Puts(TRACE_TO_KTERM, " NULL"); break;
395 case 'p': Debug_Fmt(TRACE_TO_KTERM, " %p", args); break;
396 case 'P': Debug_Fmt(TRACE_TO_KTERM, " %P", args); break; // PAddr
397 case 's': Debug_Fmt(TRACE_TO_KTERM, " '%s'", args); break;
398 case 'i': Debug_Fmt(TRACE_TO_KTERM, " %i", args); break;
399 case 'u': Debug_Fmt(TRACE_TO_KTERM, " %u", args); break;
400 case 'x': Debug_Fmt(TRACE_TO_KTERM, " 0x%x", args); break;
402 case 'X': Debug_Fmt(TRACE_TO_KTERM, " 0x%llx", args); break;
404 Debug_Puts(TRACE_TO_KTERM, "\r\n");
408 #if LOCK_DEBUG_OUTPUT
409 SHORTREL(&glDebug_Lock);
413 void Debug_HexDump(const char *Header, const void *Data, size_t Length)
415 const Uint8 *cdat = Data;
417 LogF("%014lli ", now());
418 Debug_Puts(1, Header);
419 LogF(" (Hexdump of %p)\r\n", Data);
421 #define CH(n) ((' '<=cdat[(n)]&&cdat[(n)]<0x7F) ? cdat[(n)] : '.')
425 LogF("%014lli Log: %04x:"
426 " %02x %02x %02x %02x %02x %02x %02x %02x"
427 " %02x %02x %02x %02x %02x %02x %02x %02x"
428 " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c\r\n",
431 cdat[ 0], cdat[ 1], cdat[ 2], cdat[ 3], cdat[ 4], cdat[ 5], cdat[ 6], cdat[ 7],
432 cdat[ 8], cdat[ 9], cdat[10], cdat[11], cdat[12], cdat[13], cdat[14], cdat[15],
433 CH(0), CH(1), CH(2), CH(3), CH(4), CH(5), CH(6), CH(7),
434 CH(8), CH(9), CH(10), CH(11), CH(12), CH(13), CH(14), CH(15)
443 LogF("%014lli Log: %04x: ", now(), pos);
444 for(i = 0; i < Length; i ++)
446 LogF("%02x ", cdat[i]);
448 for( ; i < 16; i ++) LogF(" ");
450 for(i = 0; i < Length; i ++)
452 if( i == 8 ) LogF(" ");