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