Annotation of prex-old/sys/kern/debug.c, Revision 1.1.1.1.2.1
1.1 nbrk 1: /*-
1.1.1.1.2.1! nbrk 2: * Copyright (c) 2005-2008, Kohsuke Ohtani
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 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;
1.1 nbrk 47:
1.1.1.1.2.1! nbrk 48: static char dbg_msg[DBGMSG_SIZE];
1.1 nbrk 49:
50: /*
1.1.1.1.2.1! nbrk 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.
1.1 nbrk 62: *
1.1.1.1.2.1! nbrk 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().
1.1 nbrk 67: */
68: void
1.1.1.1.2.1! nbrk 69: printf(const char *fmt, ...)
1.1 nbrk 70: {
71: va_list args;
1.1.1.1.2.1! nbrk 72: int i;
! 73: char c;
1.1 nbrk 74:
75: irq_lock();
76: va_start(args, fmt);
1.1.1.1.2.1! nbrk 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: }
1.1 nbrk 97: va_end(args);
98: irq_unlock();
99: }
100:
101: /*
102: * Kernel assertion.
103: *
1.1.1.1.2.1! nbrk 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.
1.1 nbrk 107: */
108: void
109: assert(const char *file, int line, const char *exp)
110: {
1.1.1.1.2.1! nbrk 111:
1.1 nbrk 112: irq_lock();
1.1.1.1.2.1! nbrk 113: printf("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
1.1 nbrk 114: BREAKPOINT();
115: for (;;)
116: machine_idle();
117: /* NOTREACHED */
118: }
119:
120: /*
121: * Kernel panic.
122: *
1.1.1.1.2.1! nbrk 123: * panic() is called for a fatal kernel error. It shows
! 124: * specified message, and stops CPU.
1.1 nbrk 125: */
126: void
1.1.1.1.2.1! nbrk 127: panic(const char *msg)
1.1 nbrk 128: {
129:
130: irq_lock();
1.1.1.1.2.1! nbrk 131: printf("\nKernel panic: %s\n", msg);
1.1 nbrk 132: irq_unlock();
133: BREAKPOINT();
134: for (;;)
135: machine_idle();
136: /* NOTREACHED */
137: }
138:
139: /*
1.1.1.1.2.1! nbrk 140: * Copy log to user buffer.
1.1 nbrk 141: */
142: int
1.1.1.1.2.1! nbrk 143: debug_getlog(char *buf)
1.1 nbrk 144: {
1.1.1.1.2.1! nbrk 145: u_long i, len, index;
! 146: int err = 0;
1.1 nbrk 147: char c;
148:
1.1.1.1.2.1! nbrk 149: irq_lock();
! 150: index = log_head;
1.1 nbrk 151: len = log_len;
1.1.1.1.2.1! nbrk 152: if (len >= LOGBUF_SIZE) {
! 153: /*
! 154: * Overrun found. Discard broken message.
! 155: */
! 156: while (len > 0 && log_buf[LOGINDEX(index)] != '\n') {
1.1 nbrk 157: index++;
158: len--;
159: }
160: }
1.1.1.1.2.1! nbrk 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: }
1.1 nbrk 170: index++;
1.1.1.1.2.1! nbrk 171: buf++;
1.1 nbrk 172: }
1.1.1.1.2.1! nbrk 173: irq_unlock();
! 174: return err;
1.1 nbrk 175: }
176:
177: /*
178: * Dump system information.
179: *
1.1.1.1.2.1! nbrk 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.
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 202: err = ENOSYS;
1.1 nbrk 203: break;
204: }
205: irq_unlock();
206: return err;
207: }
208:
209: /*
1.1.1.1.2.1! nbrk 210: * Attach to a print handler.
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 218: print_func = fn;
1.1 nbrk 219: }
220:
221: #endif /* !DEBUG */
CVSweb