Annotation of prex-old/sys/kern/debug.c, Revision 1.1
1.1 ! nbrk 1: /*-
! 2: * Copyright (c) 2005-2007, Kohsuke Ohtani
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. Neither the name of the author nor the names of any co-contributors
! 14: * may be used to endorse or promote products derived from this software
! 15: * without specific prior written permission.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 27: * SUCH DAMAGE.
! 28: */
! 29:
! 30: /*
! 31: * debug.c - kernel debug services
! 32: */
! 33:
! 34: #include <kernel.h>
! 35: #include <task.h>
! 36: #include <ipc.h>
! 37: #include <thread.h>
! 38: #include <device.h>
! 39: #include <page.h>
! 40: #include <kmem.h>
! 41: #include <vm.h>
! 42: #include <irq.h>
! 43:
! 44: #ifdef DEBUG
! 45:
! 46: #ifdef printk
! 47: #undef printk
! 48: #endif
! 49: #ifdef panic
! 50: #undef panic
! 51: #endif
! 52:
! 53: #ifdef CONFIG_DMESG
! 54: #define LOG_SIZE 2048 /* size of ring buffer for log */
! 55: #define LOG_MASK (LOG_SIZE-1)
! 56:
! 57: static void log_save(char *buf);
! 58:
! 59: static char log_buf[LOG_SIZE]; /* buffer for message log */
! 60: static u_long log_start; /* start index of log_buf */
! 61: static u_long log_end; /* end index of log_buf */
! 62: static u_long log_len; /* length of logged char */
! 63: #endif
! 64:
! 65: static char msg_buf[MSGBUFSZ]; /* temporary buffer for message */
! 66: static void (*alt_print)(char *); /* alternate print handler */
! 67:
! 68: /*
! 69: * Print out the specified string with a variable argument.
! 70: *
! 71: * An actual output is displayed via the platform specific device by
! 72: * diag_print() routine in kernel. As an alternate option, the device
! 73: * driver can replace the print routine by using debug_attach().
! 74: * All printk() inside the kernel are defined as a macro.
! 75: * The printk() macro is compiled only when the debug option is
! 76: * enabled (NDEBUG=0).
! 77: */
! 78: void
! 79: printk(const char *fmt, ...)
! 80: {
! 81: va_list args;
! 82:
! 83: irq_lock();
! 84: va_start(args, fmt);
! 85: vsprintf(msg_buf, fmt, args);
! 86: #ifdef CONFIG_DMESG
! 87: log_save(msg_buf);
! 88: #endif
! 89: if (alt_print != NULL)
! 90: alt_print(msg_buf);
! 91: else
! 92: diag_print(msg_buf);
! 93: va_end(args);
! 94: irq_unlock();
! 95: }
! 96:
! 97: /*
! 98: * Kernel assertion.
! 99: *
! 100: * assert() is called only when the expression is false in ASSERT()
! 101: * macro. ASSERT() macro is compiled only when the debug option is
! 102: * enabled.
! 103: */
! 104: void
! 105: assert(const char *file, int line, const char *exp)
! 106: {
! 107: irq_lock();
! 108: printk("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
! 109: BREAKPOINT();
! 110: for (;;)
! 111: machine_idle();
! 112: /* NOTREACHED */
! 113: }
! 114:
! 115: /*
! 116: * Kernel panic.
! 117: *
! 118: * panic() is called for a fatal kernel error. It shows specified
! 119: * message, and stops CPU. If the kernel is not debug version,
! 120: * panic() macro will reset the system instead of calling this
! 121: * routine.
! 122: */
! 123: void
! 124: panic(const char *fmt, ...)
! 125: {
! 126: va_list args;
! 127:
! 128: irq_lock();
! 129: printk("\nKernel panic: ");
! 130: va_start(args, fmt);
! 131: vsprintf(msg_buf, fmt, args);
! 132: printk(msg_buf);
! 133: va_end(args);
! 134: printk("\n");
! 135: irq_unlock();
! 136: BREAKPOINT();
! 137: for (;;)
! 138: machine_idle();
! 139: /* NOTREACHED */
! 140: }
! 141:
! 142: #ifdef CONFIG_DMESG
! 143: /*
! 144: * Save diag message to ring buffer
! 145: */
! 146: static void
! 147: log_save(char *buf)
! 148: {
! 149: char *p;
! 150:
! 151: for (p = buf; *p != '\0'; p++) {
! 152: log_buf[log_end & LOG_MASK] = *p;
! 153: log_end++;
! 154: if (log_end - log_start > LOG_SIZE)
! 155: log_start = log_end - LOG_SIZE;
! 156: if (log_len < LOG_SIZE)
! 157: log_len++;
! 158: }
! 159: /* Store end tag */
! 160: log_buf[log_end & LOG_MASK] = -1;
! 161: }
! 162: #endif
! 163:
! 164: /*
! 165: * Return infomation about log
! 166: */
! 167: int
! 168: log_get(char **buf, size_t *size)
! 169: {
! 170:
! 171: #ifdef CONFIG_DMESG
! 172: *buf = log_buf;
! 173: *size = LOG_SIZE;
! 174: return 0;
! 175: #else
! 176: return -1;
! 177: #endif
! 178: }
! 179:
! 180: #if defined(CONFIG_DMESG) && defined (CONFIG_KDUMP)
! 181: static void
! 182: log_dump(void)
! 183: {
! 184: int i, len;
! 185: u_long index;
! 186: char c;
! 187:
! 188: index = log_start;
! 189: len = log_len;
! 190: if (log_len == LOG_SIZE) {
! 191: /* Skip first line */
! 192: while (log_buf[index & LOG_MASK] != '\n') {
! 193: index++;
! 194: len--;
! 195: }
! 196: }
! 197: for (i = 0; i < len; i++) {
! 198: c = log_buf[index & LOG_MASK];
! 199: printk("%c", c);
! 200: index++;
! 201: }
! 202: }
! 203: #endif
! 204:
! 205: /*
! 206: * Dump system information.
! 207: *
! 208: * A keyboard driver may call this routine if a user presses
! 209: * a predefined "dump" key.
! 210: * Since interrupt is locked in this routine, there is no need
! 211: * to lock the interrupt/scheduler in each dump function.
! 212: */
! 213: int
! 214: debug_dump(int item)
! 215: {
! 216: #ifdef CONFIG_KDUMP
! 217: int err = 0;
! 218:
! 219: printk("\n");
! 220: irq_lock();
! 221: switch (item) {
! 222: case DUMP_THREAD:
! 223: thread_dump();
! 224: break;
! 225: case DUMP_TASK:
! 226: task_dump();
! 227: break;
! 228: case DUMP_OBJECT:
! 229: object_dump();
! 230: break;
! 231: case DUMP_TIMER:
! 232: timer_dump();
! 233: break;
! 234: case DUMP_IRQ:
! 235: irq_dump();
! 236: break;
! 237: case DUMP_DEVICE:
! 238: device_dump();
! 239: break;
! 240: case DUMP_VM:
! 241: page_dump();
! 242: kmem_dump();
! 243: vm_dump();
! 244: break;
! 245: #ifdef CONFIG_DMESG
! 246: case DUMP_MSGLOG:
! 247: log_dump();
! 248: break;
! 249: #endif
! 250: default:
! 251: err = 1;
! 252: break;
! 253: }
! 254: irq_unlock();
! 255: return err;
! 256: #else
! 257: return ENOSYS;
! 258: #endif
! 259: }
! 260:
! 261: /*
! 262: * Attach an alternate print handler.
! 263: * A device driver can hook the function to display message.
! 264: */
! 265: void
! 266: debug_attach(void (*fn)(char *))
! 267: {
! 268: ASSERT(fn);
! 269: alt_print = fn;
! 270: }
! 271:
! 272: #else /* !DEBUG */
! 273:
! 274: /*
! 275: * Stubs for the release build.
! 276: */
! 277: int
! 278: debug_dump(int item)
! 279: {
! 280: return ENOSYS;
! 281: }
! 282:
! 283: void
! 284: debug_attach(void (*fn)(char *))
! 285: {
! 286: }
! 287: #endif /* !DEBUG */
CVSweb