FreeBSD/Linux Kernel Cross Reference
sys/kern/xpr.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,1991,1990,1989,1988,1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: xpr.c,v $
29 * Revision 2.14 93/11/17 17:33:15 dbg
30 * ANSI-fied (except for varargs functions)
31 * [93/10/12 dbg]
32 *
33 * Revision 2.13 93/05/15 18:56:18 mrt
34 * machparam.h -> machspl.h
35 *
36 * Revision 2.12 93/01/14 17:37:26 danner
37 * Proper spl typing.
38 * [92/12/01 af]
39 *
40 * Revision 2.11 92/08/03 17:40:31 jfriedl
41 * removed silly prototypes
42 * [92/08/02 jfriedl]
43 *
44 * Revision 2.10 92/05/21 17:17:12 jfriedl
45 * tried prototypes.
46 * [92/05/20 jfriedl]
47 *
48 * 16-May-92 Jeffrey Friedl (jfriedl) at Carnegie-Mellon University
49 * Added void to fcns that still needed it.
50 * Revision 2.9 91/10/09 16:11:50 af
51 * Removed xpr_save. Modified xpr_dump to make it useful
52 * for dumping xpr buffers in user space tasks.
53 * [91/09/20 rpd]
54 *
55 * Turned on xprenable by default. xprbootstrap now preserves
56 * the original contents of the buffer if xprenable is off.
57 * [91/09/18 rpd]
58 *
59 * Revision 2.8 91/08/28 11:14:56 jsb
60 * Fixed xprbootstrap to zero the allocate memory.
61 * [91/08/18 rpd]
62 *
63 * Revision 2.7 91/05/18 14:34:37 rpd
64 * Added xprenable and other minor changes so that the xpr buffer
65 * may be examined after a spontaneous reboot.
66 * [91/05/03 rpd]
67 * Fixed the initialization check in xpr.
68 * Fixed xpr_dump.
69 * [91/04/02 rpd]
70 *
71 * Revision 2.6 91/05/14 16:50:09 mrt
72 * Correcting copyright
73 *
74 * Revision 2.5 91/03/16 14:53:24 rpd
75 * Updated for new kmem_alloc interface.
76 * [91/03/03 rpd]
77 *
78 * Revision 2.4 91/02/05 17:31:13 mrt
79 * Changed to new Mach copyright
80 * [91/02/01 16:21:17 mrt]
81 *
82 * Revision 2.3 90/09/09 14:33:04 rpd
83 * Use decl_simple_lock_data.
84 * [90/08/30 rpd]
85 *
86 * Revision 2.2 89/11/29 14:09:21 af
87 * Added xpr_dump() to print on console the content of the buffer,
88 * only valid for KDB usage.
89 * [89/11/12 af]
90 *
91 * MACH_KERNEL: include sys/cpu_number.h instead of machine/cpu.h.
92 * Clean up comments.
93 * [88/12/19 dbg]
94 *
95 * Revision 2.1 89/08/03 15:49:11 rwd
96 * Created.
97 *
98 * Revision 2.2 88/12/19 02:48:30 mwyoung
99 * Fix include file references.
100 * [88/11/22 02:17:01 mwyoung]
101 *
102 * Separate initialization into two phases.
103 * [88/11/22 01:13:11 mwyoung]
104 *
105 * 6-Jan-88 Michael Young (mwyoung) at Carnegie-Mellon University
106 * Eliminate use of arg6 in order to allow a more shapely event structure.
107 *
108 * 30-Dec-87 David Golub (dbg) at Carnegie-Mellon University
109 * Delinted.
110 *
111 * 7-Dec-87 Richard Sanzi (sanzi) at Carnegie-Mellon University
112 * Added xpr_save() routine.
113 *
114 */
115 #include <mach_kdb.h>
116 /*
117 * xpr silent tracing circular buffer.
118 */
119 #include <kern/xpr.h>
120 #include <kern/lock.h>
121 #include <kern/memory.h>
122 #include <kern/cpu_number.h>
123 #include <machine/machspl.h>
124 #include <vm/vm_kern.h>
125
126
127 /*
128 * After a spontaneous reboot, it is desirable to look
129 * at the old xpr buffer. Assuming xprbootstrap allocates
130 * the buffer in the same place in physical memory and
131 * the reboot doesn't clear memory, this should work.
132 * xprptr will be reset, but the saved value should be OK.
133 * Just set xprenable false so the buffer isn't overwritten.
134 */
135
136 decl_simple_lock_data(, xprlock)
137
138 boolean_t xprenable = TRUE; /* Enable xpr tracing */
139 int nxprbufs = 0; /* Number of contiguous xprbufs allocated */
140 int xprflags = 0; /* Bit mask of xpr flags enabled */
141 struct xprbuf *xprbase; /* Pointer to circular buffer nxprbufs*sizeof(xprbuf)*/
142 struct xprbuf *xprptr; /* Currently allocated xprbuf */
143 struct xprbuf *xprlast; /* Pointer to end of circular buffer */
144
145 /*VARARGS1*/
146 void xpr(msg, arg1, arg2, arg3, arg4, arg5)
147 char *msg;
148 int arg1, arg2, arg3, arg4, arg5;
149 {
150 register spl_t s;
151 register struct xprbuf *x;
152
153 /* If we aren't initialized, ignore trace request */
154 if (!xprenable || (xprptr == 0))
155 return;
156 /* Guard against all interrupts and allocate next buffer. */
157 s = splhigh();
158 simple_lock(&xprlock);
159 x = xprptr++;
160 if (xprptr >= xprlast) {
161 /* wrap around */
162 xprptr = xprbase;
163 }
164 /* Save xprptr in allocated memory. */
165 *(struct xprbuf **)xprlast = xprptr;
166 simple_unlock(&xprlock);
167 splx(s);
168 x->msg = msg;
169 x->arg1 = arg1;
170 x->arg2 = arg2;
171 x->arg3 = arg3;
172 x->arg4 = arg4;
173 x->arg5 = arg5;
174 x->timestamp = XPR_TIMESTAMP;
175 x->cpuinfo = cpu_number();
176 }
177
178 void xprbootstrap(void)
179 {
180 vm_offset_t addr;
181 vm_size_t size;
182 kern_return_t kr;
183
184 simple_lock_init(&xprlock);
185 if (nxprbufs == 0)
186 return; /* assume XPR support not desired */
187
188 /* leave room at the end for a saved copy of xprptr */
189 size = nxprbufs * sizeof(struct xprbuf) + sizeof xprptr;
190
191 kr = kmem_alloc_wired(kernel_map, &addr, size);
192 if (kr != KERN_SUCCESS)
193 panic("xprbootstrap");
194
195 if (xprenable) {
196 /*
197 * If xprenable is set (the default) then we zero
198 * the buffer so xpr_dump doesn't encounter bad pointers.
199 * If xprenable isn't set, then we preserve
200 * the original contents of the buffer. This is useful
201 * if memory survives reboots, so xpr_dump can show
202 * the previous buffer contents.
203 */
204
205 bzero((void *) addr, size);
206 }
207
208 xprbase = (struct xprbuf *) addr;
209 xprlast = &xprbase[nxprbufs];
210 xprptr = xprbase; /* setting xprptr enables tracing */
211 }
212
213 int xprinitial = 0;
214
215 void xprinit(void)
216 {
217 xprflags |= xprinitial;
218 }
219
220 #if MACH_KDB
221 #include <machine/setjmp.h>
222
223
224 extern void db_printf();
225 extern jmp_buf_t *db_recover;
226
227 /*
228 * Print current content of xpr buffers (KDB's sake)
229 * Use stack order to make it understandable.
230 *
231 * Called as "!xpr_dump" this dumps the kernel's xpr buffer.
232 * Called with arguments, it can dump xpr buffers in user tasks,
233 * assuming they use the same format as the kernel.
234 */
235 void xpr_dump(
236 struct xprbuf * base,
237 int nbufs)
238 {
239 jmp_buf_t db_jmpbuf;
240 jmp_buf_t *prev;
241 struct xprbuf *last, *ptr;
242 register struct xprbuf *x;
243 int i;
244 spl_t s;
245
246 if (base == 0) {
247 base = xprbase;
248 nbufs = nxprbufs;
249 }
250
251 if (nbufs == 0)
252 return;
253
254 if (base == xprbase) {
255 s = splhigh();
256 simple_lock(&xprlock);
257 }
258
259 last = base + nbufs;
260 ptr = * (struct xprbuf **) last;
261
262 prev = db_recover;
263 if (_setjmp(db_recover = &db_jmpbuf) == 0)
264 for (x = ptr, i = 0; i < nbufs; i++) {
265 if (--x < base)
266 x = last - 1;
267
268 if (x->msg == 0)
269 break;
270
271 db_printf("<%d:%x:%x> ", x - base, x->cpuinfo, x->timestamp);
272 db_printf(x->msg, x->arg1,x->arg2,x->arg3,x->arg4,x->arg5);
273 }
274 db_recover = prev;
275
276 if (base == xprbase) {
277 simple_unlock(&xprlock);
278 splx(s);
279 }
280 }
281 #endif /* MACH_KDB */
Cache object: 0ed11a31b862860ddd93097444450340
|