|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 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 [email protected] ! 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: #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: } ! 192: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.