Annotation of prex/sys/kern/debug.c, Revision 1.1.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