Annotation of prex/sys/kern/debug.c, Revision 1.1
1.1 ! nbrk 1: /*-
! 2: * Copyright (c) 2005-2008, 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 <thread.h>
! 37: #include <vm.h>
! 38: #include <irq.h>
! 39:
! 40: #ifdef DEBUG
! 41:
! 42: /*
! 43: * diag_print() is provided by architecture dependent layer.
! 44: */
! 45: typedef void (*prtfn_t)(char *);
! 46: static prtfn_t print_func = &diag_print;
! 47:
! 48: static char dbg_msg[DBGMSG_SIZE];
! 49:
! 50: /*
! 51: * dmesg support
! 52: */
! 53: static char log_buf[LOGBUF_SIZE];
! 54: static u_long log_head;
! 55: static u_long log_tail;
! 56: static u_long log_len;
! 57:
! 58: #define LOGINDEX(x) ((x) & (LOGBUF_SIZE - 1))
! 59:
! 60: /*
! 61: * Print out the specified string.
! 62: *
! 63: * An actual output is displayed via the platform
! 64: * specific device by diag_print() routine in kernel.
! 65: * As an alternate option, the device driver can
! 66: * replace the print routine by using debug_attach().
! 67: */
! 68: void
! 69: printf(const char *fmt, ...)
! 70: {
! 71: va_list args;
! 72: int i;
! 73: char c;
! 74:
! 75: irq_lock();
! 76: va_start(args, fmt);
! 77:
! 78: vsprintf(dbg_msg, fmt, args);
! 79:
! 80: /* Print out */
! 81: (*print_func)(dbg_msg);
! 82:
! 83: /*
! 84: * Record to log buffer
! 85: */
! 86: for (i = 0; i < DBGMSG_SIZE; i++) {
! 87: c = dbg_msg[i];
! 88: if (c == '\0')
! 89: break;
! 90: log_buf[LOGINDEX(log_tail)] = c;
! 91: log_tail++;
! 92: if (log_len < LOGBUF_SIZE)
! 93: log_len++;
! 94: else
! 95: log_head = log_tail - LOGBUF_SIZE;
! 96: }
! 97: va_end(args);
! 98: irq_unlock();
! 99: }
! 100:
! 101: /*
! 102: * Kernel assertion.
! 103: *
! 104: * assert() is called only when the expression is false in
! 105: * ASSERT() macro. ASSERT() macro is compiled only when
! 106: * the debug option is enabled.
! 107: */
! 108: void
! 109: assert(const char *file, int line, const char *exp)
! 110: {
! 111:
! 112: irq_lock();
! 113: printf("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
! 114: BREAKPOINT();
! 115: for (;;)
! 116: machine_idle();
! 117: /* NOTREACHED */
! 118: }
! 119:
! 120: /*
! 121: * Kernel panic.
! 122: *
! 123: * panic() is called for a fatal kernel error. It shows
! 124: * specified message, and stops CPU.
! 125: */
! 126: void
! 127: panic(const char *msg)
! 128: {
! 129:
! 130: irq_lock();
! 131: printf("\nKernel panic: %s\n", msg);
! 132: irq_unlock();
! 133: BREAKPOINT();
! 134: for (;;)
! 135: machine_idle();
! 136: /* NOTREACHED */
! 137: }
! 138:
! 139: /*
! 140: * Copy log to user buffer.
! 141: */
! 142: int
! 143: debug_getlog(char *buf)
! 144: {
! 145: u_long i, len, index;
! 146: int err = 0;
! 147: char c;
! 148:
! 149: irq_lock();
! 150: index = log_head;
! 151: len = log_len;
! 152: if (len >= LOGBUF_SIZE) {
! 153: /*
! 154: * Overrun found. Discard broken message.
! 155: */
! 156: while (len > 0 && log_buf[LOGINDEX(index)] != '\n') {
! 157: index++;
! 158: len--;
! 159: }
! 160: }
! 161: for (i = 0; i < LOGBUF_SIZE; i++) {
! 162: if (i < len)
! 163: c = log_buf[LOGINDEX(index)];
! 164: else
! 165: c = '\0';
! 166: if (umem_copyout(&c, buf, 1)) {
! 167: err = EFAULT;
! 168: break;
! 169: }
! 170: index++;
! 171: buf++;
! 172: }
! 173: irq_unlock();
! 174: return err;
! 175: }
! 176:
! 177: /*
! 178: * Dump system information.
! 179: *
! 180: * A keyboard driver may call this routine if a user
! 181: * presses a predefined "dump" key. Since interrupt is
! 182: * locked in this routine, there is no need to lock the
! 183: * interrupt/scheduler in each dump function.
! 184: */
! 185: int
! 186: debug_dump(int item)
! 187: {
! 188: int err = 0;
! 189:
! 190: irq_lock();
! 191: switch (item) {
! 192: case DUMP_THREAD:
! 193: thread_dump();
! 194: break;
! 195: case DUMP_TASK:
! 196: task_dump();
! 197: break;
! 198: case DUMP_VM:
! 199: vm_dump();
! 200: break;
! 201: default:
! 202: err = ENOSYS;
! 203: break;
! 204: }
! 205: irq_unlock();
! 206: return err;
! 207: }
! 208:
! 209: /*
! 210: * Attach to a print handler.
! 211: * A device driver can hook the function to display message.
! 212: */
! 213: void
! 214: debug_attach(void (*fn)(char *))
! 215: {
! 216: ASSERT(fn);
! 217:
! 218: print_func = fn;
! 219: }
! 220:
! 221: #endif /* !DEBUG */
CVSweb