#define DEBUG_TO_E9 1
#define DEBUG_TO_SERIAL 1
#define SERIAL_PORT 0x3F8
+#define GDB_SERIAL_PORT 0x2F8
// === IMPORTS ===
extern void Threads_Dump();
int gDebug_Level = 0;
int giDebug_KTerm = -1;
int gbDebug_SerialSetup = 0;
+ int gbGDB_SerialSetup = 0;
// === CODE ===
-static void E9(char ch)
+int putDebugChar(char ch)
+{
+ if(!gbGDB_SerialSetup) {
+ outb(GDB_SERIAL_PORT + 1, 0x00); // Disable all interrupts
+ outb(GDB_SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ outb(GDB_SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ outb(GDB_SERIAL_PORT + 1, 0x00); // (hi byte)
+ outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ outb(GDB_SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it
+ outb(GDB_SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ gbDebug_SerialSetup = 1;
+ }
+ while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
+ outb(GDB_SERIAL_PORT, ch);
+ return 0;
+}
+int getDebugChar()
+{
+ if(!gbGDB_SerialSetup) {
+ outb(GDB_SERIAL_PORT + 1, 0x00); // Disable all interrupts
+ outb(GDB_SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ outb(GDB_SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ outb(GDB_SERIAL_PORT + 1, 0x00); // (hi byte)
+ outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ outb(GDB_SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it
+ outb(GDB_SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ gbDebug_SerialSetup = 1;
+ }
+ while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0) ;
+ return inb(GDB_SERIAL_PORT);
+}
+
+static void Debug_Putchar(char ch)
{
if(giDebug_KTerm != -1)
VFS_Write(giDebug_KTerm, 1, &ch);
-
+
#if DEBUG_TO_SERIAL
if(!gbDebug_SerialSetup) {
- outb(SERIAL_PORT + 1, 0x00); // Disable all interrupts
- outb(SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
- outb(SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
- outb(SERIAL_PORT + 1, 0x00); // (hi byte)
- outb(SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
- outb(SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it
- outb(SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ outb(SERIAL_PORT + 1, 0x00); // Disable all interrupts
+ outb(SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ outb(SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ outb(SERIAL_PORT + 1, 0x00); // (hi byte)
+ outb(SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ outb(SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it
+ outb(SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
gbDebug_SerialSetup = 1;
}
while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
outb(SERIAL_PORT, ch);
#endif
-
+
#if DEBUG_TO_E9
__asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
#endif
}
-static void E9_Str(char *Str)
+static void Debug_Puts(char *Str)
{
- while(*Str) E9(*Str++);
+ while(*Str) Debug_Putchar(*Str++);
}
-void E9_Fmt(const char *format, va_list *args)
+void Debug_Fmt(const char *format, va_list *args)
{
char c, pad = ' ';
int minSize = 0;
char *p = NULL;
int isLongLong = 0;
Uint64 arg;
-
+
while((c = *format++) != 0)
{
// Non control character
if( c != '%' ) {
- E9(c);
+ Debug_Putchar(c);
continue;
}
-
+
c = *format++;
-
+
// Literal %
if(c == '%') {
- E9('%');
+ Debug_Putchar('%');
continue;
}
-
+
// Pointer
if(c == 'p') {
Uint ptr = va_arg(*args, Uint);
- E9('*'); E9('0'); E9('x');
+ Debug_Putchar('*'); Debug_Putchar('0'); Debug_Putchar('x');
p = tmpBuf;
itoa(p, ptr, 16, BITS/4, '0');
goto printString;
}
-
+
// Get Argument
arg = va_arg(*args, Uint);
-
+
// Padding
if(c == '0') {
pad = '0';
c = *format++;
} else
pad = ' ';
-
+
// Minimum length
minSize = 1;
if('1' <= c && c <= '9')
c = *format++;
}
}
-
+
// Long (default)
isLongLong = 0;
if(c == 'l') {
isLongLong = 1;
}
}
-
+
p = tmpBuf;
switch (c) {
case 'd':
case 'i':
if( (isLongLong && arg >> 63) || (!isLongLong && arg >> 31) ) {
- E9('-');
+ Debug_Putchar('-');
arg = -arg;
}
itoa(p, arg, 10, minSize, pad);
goto printString;
case 'B': //Boolean
- if(arg) E9_Str("True");
- else E9_Str("False");
+ if(arg) Debug_Puts("True");
+ else Debug_Puts("False");
break;
-
+
case 's':
p = (char*)(Uint)arg;
printString:
if(!p) p = "(null)";
- while(*p) E9(*p++);
+ while(*p) Debug_Putchar(*p++);
+ break;
+
+ // Single Character / Array
+ case 'c':
+ if(minSize == 1) {
+ Debug_Putchar(arg);
+ break;
+ }
+ p = (char*)(Uint)arg;
+ if(!p) goto printString;
+ while(minSize--) Debug_Putchar(*p++);
+ break;
+
+ default:
+ Debug_Putchar(arg);
break;
-
- default: E9(arg); break;
}
}
}
-/**
- * \fn void LogV(char *Fmt, va_list Args)
- */
-void LogV(char *Fmt, va_list Args)
-{
- E9_Str("Log: ");
- E9_Fmt(Fmt, &Args);
- E9('\n');
-}
/**
* \fn void LogF(char *Msg, ...)
*/
void LogF(char *Fmt, ...)
{
va_list args;
-
+
va_start(args, Fmt);
-
- E9_Fmt(Fmt, &args);
-
+
+ Debug_Fmt(Fmt, &args);
+
va_end(args);
}
/**
void Log(char *Fmt, ...)
{
va_list args;
-
- E9_Str("Log: ");
+
+ Debug_Puts("Log: ");
va_start(args, Fmt);
- E9_Fmt(Fmt, &args);
+ Debug_Fmt(Fmt, &args);
va_end(args);
- E9('\n');
+ Debug_Putchar('\n');
}
void Warning(char *Fmt, ...)
{
va_list args;
- E9_Str("Warning: ");
+ Debug_Puts("Warning: ");
va_start(args, Fmt);
- E9_Fmt(Fmt, &args);
+ Debug_Fmt(Fmt, &args);
va_end(args);
- E9('\n');
+ Debug_Putchar('\n');
}
void Panic(char *Fmt, ...)
{
va_list args;
- E9_Str("Panic: ");
+ Debug_Puts("Panic: ");
va_start(args, Fmt);
- E9_Fmt(Fmt, &args);
+ Debug_Fmt(Fmt, &args);
va_end(args);
- E9('\n');
-
+ Debug_Putchar('\n');
+
Threads_Dump();
-
+
__asm__ __volatile__ ("xchg %bx, %bx");
__asm__ __volatile__ ("cli;\n\thlt");
for(;;) __asm__ __volatile__ ("hlt");
va_list args;
int i = gDebug_Level ++;
int pos;
-
+
va_start(args, ArgTypes);
-
- while(i--) E9(' ');
-
- E9_Str(FuncName); E9_Str(": (");
-
+
+ while(i--) Debug_Putchar(' ');
+
+ Debug_Puts(FuncName); Debug_Puts(": (");
+
while(*ArgTypes)
{
pos = strpos(ArgTypes, ' ');
if(pos != -1) ArgTypes[pos] = '\0';
if(pos == -1 || pos > 1) {
- E9_Str(ArgTypes+1);
- E9('=');
+ Debug_Puts(ArgTypes+1);
+ Debug_Putchar('=');
}
if(pos != -1) ArgTypes[pos] = ' ';
switch(*ArgTypes)
{
- case 'p': E9_Fmt("%p", &args); break;
- case 's': E9_Fmt("'%s'", &args); break;
- case 'i': E9_Fmt("%i", &args); break;
- case 'u': E9_Fmt("%u", &args); break;
- case 'x': E9_Fmt("0x%x", &args); break;
- case 'b': E9_Fmt("0b%b", &args); break;
+ case 'p': Debug_Fmt("%p", &args); break;
+ case 's': Debug_Fmt("'%s'", &args); break;
+ case 'i': Debug_Fmt("%i", &args); break;
+ case 'u': Debug_Fmt("%u", &args); break;
+ case 'x': Debug_Fmt("0x%x", &args); break;
+ case 'b': Debug_Fmt("0b%b", &args); break;
// Extended (64-Bit)
- case 'X': E9_Fmt("0x%llx", &args); break;
- case 'B': E9_Fmt("0b%llb", &args); break;
+ case 'X': Debug_Fmt("0x%llx", &args); break;
+ case 'B': Debug_Fmt("0b%llb", &args); break;
}
if(pos != -1) {
- E9(','); E9(' ');
+ Debug_Putchar(','); Debug_Putchar(' ');
}
-
+
if(pos == -1) break;
ArgTypes = &ArgTypes[pos+1];
}
-
+
va_end(args);
- E9(')'); E9('\n');
+ Debug_Putchar(')'); Debug_Putchar('\n');
}
void Debug_Log(char *FuncName, char *Fmt, ...)
{
va_list args;
int i = gDebug_Level;
-
+
va_start(args, Fmt);
-
- while(i--) E9(' ');
-
- E9_Str(FuncName); E9_Str(": ");
- E9_Fmt(Fmt, &args);
-
+
+ while(i--) Debug_Putchar(' ');
+
+ Debug_Puts(FuncName); Debug_Puts(": ");
+ Debug_Fmt(Fmt, &args);
+
va_end(args);
- E9('\n');
+ Debug_Putchar('\n');
}
void Debug_Leave(char *FuncName, char RetType, ...)
{
va_list args;
int i = --gDebug_Level;
-
+
va_start(args, RetType);
-
+
+ if( i == -1 ) {
+ gDebug_Level = 0;
+ i = 0;
+ }
// Indenting
- while(i--) E9(' ');
-
- E9_Str(FuncName); E9_Str(": RETURN");
-
+ while(i--) Debug_Putchar(' ');
+
+ Debug_Puts(FuncName); Debug_Puts(": RETURN");
+
// No Return
if(RetType == '-') {
- E9('\n');
+ Debug_Putchar('\n');
return;
}
-
- E9(' ');
+
+ Debug_Putchar(' ');
switch(RetType)
{
- case 'n': E9_Str("NULL"); break;
- case 'p': E9_Fmt("%p", &args); break;
- case 's': E9_Fmt("'%s'", &args); break;
- case 'i': E9_Fmt("%i", &args); break;
- case 'u': E9_Fmt("%u", &args); break;
- case 'x': E9_Fmt("0x%x", &args); break;
+ case 'n': Debug_Puts("NULL"); break;
+ case 'p': Debug_Fmt("%p", &args); break;
+ case 's': Debug_Fmt("'%s'", &args); break;
+ case 'i': Debug_Fmt("%i", &args); break;
+ case 'u': Debug_Fmt("%u", &args); break;
+ case 'x': Debug_Fmt("0x%x", &args); break;
// Extended (64-Bit)
- case 'X': E9_Fmt("0x%llx", &args); break;
+ case 'X': Debug_Fmt("0x%llx", &args); break;
}
- E9('\n');
-
+ Debug_Putchar('\n');
+
va_end(args);
}
{
Uint8 *cdat = Data;
Uint pos = 0;
- E9_Str(Header);
+ Debug_Puts(Header);
LogF(" (Hexdump of %p)\n", Data);
-
+
while(Length >= 16)
{
- Log("%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ #define CH(n) ((' '<=cdat[(n)]&&cdat[(n)]<=0x7F) ? cdat[(n)] : '.')
+ Log("%04x: %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c",
pos,
cdat[0], cdat[1], cdat[2], cdat[3], cdat[4], cdat[5], cdat[6], cdat[7],
- cdat[8], cdat[9], cdat[10], cdat[11], cdat[12], cdat[13], cdat[14], cdat[15]
+ cdat[8], cdat[9], cdat[10], cdat[11], cdat[12], cdat[13], cdat[14], cdat[15],
+ CH(0), CH(1), CH(2), CH(3), CH(4), CH(5), CH(6), CH(7),
+ CH(8), CH(9), CH(10), CH(11), CH(12), CH(13), CH(14), CH(15)
);
Length -= 16;
cdat += 16;
pos += 16;
}
-
+
LogF("Log: %04x: ", pos);
while(Length)
{
Length--;
cdat ++;
}
- E9('\n');
+ Debug_Putchar('\n');
}
// --- EXPORTS ---