|
|
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*/
1.1.1.4 ! root 59: void xpr(
! 60: char *msg,
! 61: int arg1,
! 62: int arg2,
! 63: int arg3,
! 64: int arg4,
! 65: int arg5)
1.1 root 66: {
1.1.1.4 ! root 67: spl_t s;
! 68: struct xprbuf *x;
1.1 root 69:
70: /* If we aren't initialized, ignore trace request */
71: if (!xprenable || (xprptr == 0))
72: return;
73: /* Guard against all interrupts and allocate next buffer. */
74: s = splhigh();
75: simple_lock(&xprlock);
76: x = xprptr++;
77: if (xprptr >= xprlast) {
78: /* wrap around */
79: xprptr = xprbase;
80: }
81: /* Save xprptr in allocated memory. */
82: *(struct xprbuf **)xprlast = xprptr;
83: simple_unlock(&xprlock);
84: splx(s);
85: x->msg = msg;
86: x->arg1 = arg1;
87: x->arg2 = arg2;
88: x->arg3 = arg3;
89: x->arg4 = arg4;
90: x->arg5 = arg5;
91: x->timestamp = XPR_TIMESTAMP;
92: x->cpuinfo = cpu_number();
93: }
94:
1.1.1.3 root 95: void xprbootstrap(void)
1.1 root 96: {
97: vm_offset_t addr;
98: vm_size_t size;
99: kern_return_t kr;
100:
101: simple_lock_init(&xprlock);
102: if (nxprbufs == 0)
103: return; /* assume XPR support not desired */
104:
105: /* leave room at the end for a saved copy of xprptr */
106: size = nxprbufs * sizeof(struct xprbuf) + sizeof xprptr;
107:
108: kr = kmem_alloc_wired(kernel_map, &addr, size);
109: if (kr != KERN_SUCCESS)
110: panic("xprbootstrap");
111:
112: if (xprenable) {
113: /*
114: * If xprenable is set (the default) then we zero
115: * the buffer so xpr_dump doesn't encounter bad pointers.
116: * If xprenable isn't set, then we preserve
117: * the original contents of the buffer. This is useful
118: * if memory survives reboots, so xpr_dump can show
119: * the previous buffer contents.
120: */
121:
1.1.1.4 ! root 122: memset((void *) addr, 0, size);
1.1 root 123: }
124:
125: xprbase = (struct xprbuf *) addr;
126: xprlast = &xprbase[nxprbufs];
127: xprptr = xprbase; /* setting xprptr enables tracing */
128: }
129:
130: int xprinitial = 0;
131:
1.1.1.3 root 132: void xprinit(void)
1.1 root 133: {
134: xprflags |= xprinitial;
135: }
136:
137: #if MACH_KDB
138: #include <machine/setjmp.h>
1.1.1.4 ! root 139: #include <ddb/db_output.h>
1.1 root 140:
141: extern jmp_buf_t *db_recover;
142:
143: /*
144: * Print current content of xpr buffers (KDB's sake)
145: * Use stack order to make it understandable.
146: *
147: * Called as "!xpr_dump" this dumps the kernel's xpr buffer.
148: * Called with arguments, it can dump xpr buffers in user tasks,
149: * assuming they use the same format as the kernel.
150: */
1.1.1.4 ! root 151: void xpr_dump(
! 152: struct xprbuf *base,
! 153: int nbufs)
1.1 root 154: {
155: jmp_buf_t db_jmpbuf;
156: jmp_buf_t *prev;
157: struct xprbuf *last, *ptr;
1.1.1.4 ! root 158: struct xprbuf *x;
1.1 root 159: int i;
1.1.1.4 ! root 160: spl_t s = s;
1.1 root 161:
162: if (base == 0) {
163: base = xprbase;
164: nbufs = nxprbufs;
165: }
166:
167: if (nbufs == 0)
168: return;
169:
170: if (base == xprbase) {
171: s = splhigh();
172: simple_lock(&xprlock);
173: }
174:
175: last = base + nbufs;
176: ptr = * (struct xprbuf **) last;
177:
178: prev = db_recover;
179: if (_setjmp(db_recover = &db_jmpbuf) == 0)
180: for (x = ptr, i = 0; i < nbufs; i++) {
181: if (--x < base)
182: x = last - 1;
183:
184: if (x->msg == 0)
185: break;
186:
187: db_printf("<%d:%x:%x> ", x - base, x->cpuinfo, x->timestamp);
188: db_printf(x->msg, x->arg1,x->arg2,x->arg3,x->arg4,x->arg5);
189: }
190: db_recover = prev;
191:
192: if (base == xprbase) {
193: simple_unlock(&xprlock);
194: (void) splx(s);
195: }
196: }
1.1.1.2 root 197: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.