Warning, cross-references for /kernel/util/debug.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "kernel.h"
0019 #include "util/printf.h"
0020
0021 #ifndef GDBSTUB_TCP
0022 void putDebugChar (int c)
0023 {
0024 while (!(inb (serial_port1 + 5) & 0x20));
0025 outb (c, serial_port1);
0026 }
0027
0028 int getDebugChar (void)
0029 {
0030 while (!(inb (serial_port1 + 5) & 1));
0031 return inb (serial_port1);
0032 }
0033 #endif
0034
0035 void
0036 com1_putc (char c)
0037 {
0038 #ifdef COM1_TO_SCREEN
0039 _putchar (c);
0040 #elif !defined(ENABLE_GDBSTUB) || defined(GDBSTUB_TCP)
0041 if (c == '\n') {
0042
0043 while (!(inb (serial_port1 + 5) & 0x20));
0044 outb ('\r', serial_port1);
0045 }
0046
0047 while (!(inb (serial_port1 + 5) & 0x20));
0048 outb (c, serial_port1);
0049 #endif
0050 }
0051
0052 void
0053 com1_puts (char *p)
0054 {
0055 while (*p)
0056 com1_putc (*p++);
0057 }
0058
0059 void
0060 com1_putx (uint32 l)
0061 {
0062 int i, li;
0063
0064 for (i = 7; i >= 0; i--)
0065 if ((li = (l >> (i << 2)) & 0x0F) > 9)
0066 com1_putc ('A' + li - 0x0A);
0067 else
0068 com1_putc ('0' + li);
0069 }
0070
0071 void
0072 stacktrace (void)
0073 {
0074 uint32 esp, ebp;
0075 extern void com1_putc (char);
0076 extern void com1_puts (char *);
0077 extern void com1_putx (uint32);
0078 asm volatile ("movl %%esp, %0":"=r" (esp));
0079 asm volatile ("movl %%ebp, %0":"=r" (ebp));
0080 com1_printf ("Stacktrace:\n");
0081 while (ebp >= KERN_STK && ebp <= KERN_STK + 0x1000) {
0082 com1_printf ("%0.8X\n", *((uint32 *) (ebp + 4)));
0083 ebp = *((uint32 *) ebp);
0084 }
0085 }
0086
0087 void
0088 stacktrace_frame (uint esp, uint ebp)
0089 {
0090 uint min = esp & (~0xFFF), max = min + 0x1000;
0091 extern void com1_putc (char);
0092 extern void com1_puts (char *);
0093 extern void com1_putx (uint32);
0094 com1_printf ("Stacktrace:\n");
0095 while (ebp >= min && ebp <= max) {
0096 com1_printf ("%0.8X\n", *((uint32 *) (ebp + 4)));
0097 ebp = *((uint32 *) ebp);
0098 }
0099 }
0100
0101 static char b64lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0102
0103
0104
0105 union v8 {
0106 struct {
0107 u8 a:2;
0108 u8 b:2;
0109 u8 c:2;
0110 u8 d:2;
0111 };
0112 struct {
0113 u8 ab:4;
0114 u8 cd:4;
0115 };
0116 struct {
0117 u8 _a_:2;
0118 u8 bcd:6;
0119 };
0120 struct {
0121 u8 abc:6;
0122 u8 _d_:2;
0123 };
0124 } __attribute__((packed));
0125
0126 #define OUT(c) logger_putc(c)
0127 void
0128 base64encode_dump (u8 *str, int n)
0129 {
0130 int i;
0131 for (i=0; i<n; i+=3) {
0132 union v8 *p = (union v8 *)&str[i];
0133 OUT (b64lookup[p[0].bcd]);
0134 if (i+1 < n)
0135 OUT (b64lookup[(p[0].a << 4) | (p[1].cd)]);
0136 else {
0137 OUT (b64lookup[p[0].a << 4]);
0138 OUT ('=');
0139 OUT ('=');
0140 break;
0141 }
0142 if (i+2 < n)
0143 OUT (b64lookup[(p[1].ab << 2) | p[2].d]);
0144 else {
0145 OUT (b64lookup[p[1].ab << 2]);
0146 OUT ('=');
0147 break;
0148 }
0149 OUT (b64lookup[p[2].abc]);
0150 }
0151 }
0152 #undef OUT
0153
0154 void
0155 dump_page (u8 *addr)
0156 {
0157 logger_printf ("***dump 0x%p\n", addr);
0158 base64encode_dump (addr, 0x1000);
0159 logger_printf ("\n");
0160 }
0161
0162 static int getc (void)
0163 {
0164 while (!(inb (serial_port1 + 5) & 1));
0165 return inb (serial_port1);
0166 }
0167
0168 void
0169 crash_debug (char *reason)
0170 {
0171 extern void acpi_reboot (void);
0172 extern bool mp_ACPI_enabled;
0173 char c;
0174 u8 state;
0175
0176 com1_printf ("Entering crash debug: %s\n", reason);
0177 for (;;) {
0178 com1_printf ("crash> ");
0179 c = getc ();
0180 com1_printf ("\nyou typed '%c' (=%d)\n", c, c);
0181 if (c == '6') {
0182 com1_printf ("REBOOTING...\n");
0183 tsc_delay_usec (100000);
0184 if (mp_ACPI_enabled) acpi_reboot ();
0185 #define KEYBOARD_STATUS_PORT 0x64
0186 while (((state = inb (KEYBOARD_STATUS_PORT)) & 2) != 0);
0187 outb (0xFE, KEYBOARD_STATUS_PORT);
0188 }
0189 }
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201