|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 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.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26:
27: /*
28: * xpr silent tracing circular buffer.
29: */
1.1.1.3 ! root 30: #include <string.h>
! 31:
! 32: #include <kern/debug.h>
1.1 root 33: #include <kern/xpr.h>
34: #include <kern/lock.h>
35: #include "cpu_number.h"
36: #include <machine/machspl.h>
37: #include <vm/vm_kern.h>
38:
39:
40: /*
41: * After a spontaneous reboot, it is desirable to look
42: * at the old xpr buffer. Assuming xprbootstrap allocates
43: * the buffer in the same place in physical memory and
44: * the reboot doesn't clear memory, this should work.
45: * xprptr will be reset, but the saved value should be OK.
46: * Just set xprenable false so the buffer isn't overwritten.
47: */
48:
49: decl_simple_lock_data(, xprlock)
50:
51: boolean_t xprenable = TRUE; /* Enable xpr tracing */
52: int nxprbufs = 0; /* Number of contiguous xprbufs allocated */
53: int xprflags = 0; /* Bit mask of xpr flags enabled */
54: struct xprbuf *xprbase; /* Pointer to circular buffer nxprbufs*sizeof(xprbuf)*/
55: struct xprbuf *xprptr; /* Currently allocated xprbuf */
56: struct xprbuf *xprlast; /* Pointer to end of circular buffer */
57:
58: /*VARARGS1*/
59: void xpr(msg, arg1, arg2, arg3, arg4, arg5)
60: char *msg;
61: int arg1, arg2, arg3, arg4, arg5;
62: {
63: register spl_t s;
64: register struct xprbuf *x;
65:
66: /* If we aren't initialized, ignore trace request */
67: if (!xprenable || (xprptr == 0))
68: return;
69: /* Guard against all interrupts and allocate next buffer. */
70: s = splhigh();
71: simple_lock(&xprlock);
72: x = xprptr++;
73: if (xprptr >= xprlast) {
74: /* wrap around */
75: xprptr = xprbase;
76: }
77: /* Save xprptr in allocated memory. */
78: *(struct xprbuf **)xprlast = xprptr;
79: simple_unlock(&xprlock);
80: splx(s);
81: x->msg = msg;
82: x->arg1 = arg1;
83: x->arg2 = arg2;
84: x->arg3 = arg3;
85: x->arg4 = arg4;
86: x->arg5 = arg5;
87: x->timestamp = XPR_TIMESTAMP;
88: x->cpuinfo = cpu_number();
89: }
90:
1.1.1.3 ! root 91: void xprbootstrap(void)
1.1 root 92: {
93: vm_offset_t addr;
94: vm_size_t size;
95: kern_return_t kr;
96:
97: simple_lock_init(&xprlock);
98: if (nxprbufs == 0)
99: return; /* assume XPR support not desired */
100:
101: /* leave room at the end for a saved copy of xprptr */
102: size = nxprbufs * sizeof(struct xprbuf) + sizeof xprptr;
103:
104: kr = kmem_alloc_wired(kernel_map, &addr, size);
105: if (kr != KERN_SUCCESS)
106: panic("xprbootstrap");
107:
108: if (xprenable) {
109: /*
110: * If xprenable is set (the default) then we zero
111: * the buffer so xpr_dump doesn't encounter bad pointers.
112: * If xprenable isn't set, then we preserve
113: * the original contents of the buffer. This is useful
114: * if memory survives reboots, so xpr_dump can show
115: * the previous buffer contents.
116: */
117:
1.1.1.3 ! root 118: memset((char *) addr, 0, size);
1.1 root 119: }
120:
121: xprbase = (struct xprbuf *) addr;
122: xprlast = &xprbase[nxprbufs];
123: xprptr = xprbase; /* setting xprptr enables tracing */
124: }
125:
126: int xprinitial = 0;
127:
1.1.1.3 ! root 128: void xprinit(void)
1.1 root 129: {
130: xprflags |= xprinitial;
131: }
132:
133: #if MACH_KDB
134: #include <machine/setjmp.h>
135:
136:
137: extern void db_printf();
138: extern jmp_buf_t *db_recover;
139:
140: /*
141: * Print current content of xpr buffers (KDB's sake)
142: * Use stack order to make it understandable.
143: *
144: * Called as "!xpr_dump" this dumps the kernel's xpr buffer.
145: * Called with arguments, it can dump xpr buffers in user tasks,
146: * assuming they use the same format as the kernel.
147: */
148: void xpr_dump(base, nbufs)
149: struct xprbuf *base;
150: int nbufs;
151: {
152: jmp_buf_t db_jmpbuf;
153: jmp_buf_t *prev;
154: struct xprbuf *last, *ptr;
155: register struct xprbuf *x;
156: int i;
157: spl_t s;
158:
159: if (base == 0) {
160: base = xprbase;
161: nbufs = nxprbufs;
162: }
163:
164: if (nbufs == 0)
165: return;
166:
167: if (base == xprbase) {
168: s = splhigh();
169: simple_lock(&xprlock);
170: }
171:
172: last = base + nbufs;
173: ptr = * (struct xprbuf **) last;
174:
175: prev = db_recover;
176: if (_setjmp(db_recover = &db_jmpbuf) == 0)
177: for (x = ptr, i = 0; i < nbufs; i++) {
178: if (--x < base)
179: x = last - 1;
180:
181: if (x->msg == 0)
182: break;
183:
184: db_printf("<%d:%x:%x> ", x - base, x->cpuinfo, x->timestamp);
185: db_printf(x->msg, x->arg1,x->arg2,x->arg3,x->arg4,x->arg5);
186: }
187: db_recover = prev;
188:
189: if (base == xprbase) {
190: simple_unlock(&xprlock);
191: (void) splx(s);
192: }
193: }
1.1.1.2 root 194: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.