|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
26: *
27: * ddm.c - driverkit debugging module, NRW kernel version.
28: *
29: * HISTORY
30: * 08-Feb-92 Doug Mitchell at NeXT
31: * Converted to kernel version (no Objective C).
32: * 22-Feb-91 Doug Mitchell at NeXT
33: * Created.
34: */
35:
36: #import "xpr_debug.h"
37: #import <bsd/sys/types.h>
38: #import <driverkit/debugging.h>
39: #import <driverkit/ddmPrivate.h>
40: #import <driverkit/generalFuncs.h>
41: #import <kernserv/lock.h>
42: #import <kernserv/prototypes.h>
43: #import <bsd/machine/spl.h>
44: #import <mach/machine/simple_lock.h>
45:
46: #if __nrw__
47: #import <architecture/nrw/clock.h>
48: #import <kernserv/machine/cpu_number.h>
49: #define _MON_TYPES_BOOLEAN_
50: #define _MON_TYPES_CPUTYPES_
51: #define _MON_TYPES_SIZE_
52: #define _MON_BIT_MACROS_
53: #import <mon/mon_global.h>
54: #endif __nrw__
55:
56: #if i386
57: #import <machdep/i386/timer.h>
58: #import <machdep/i386/timer_inline.h>
59: #endif i386
60:
61: #define CLOCK_CALIBRATE 0
62:
63: /*
64: * xprbuf_t's are kept in a circular buffer, xprArray. New entries are added
65: * when the client calls xprAdd. The buffer is examined from an external
66: * task which communicates with xprServerThread via simple Mach messages.
67: */
68:
69: /*
70: * Globals.
71: */
72: u_int IODDMMasks[IO_NUM_DDM_MASKS];
73: // an array of task-specific
74: // bits. Typically tweaked
75: // at run time.
76: uxprGlobal_t uxprGlobal;
77: simple_lock_data_t xpr_lock; // protects xprLocked
78: int xprLocked = 0; // Simple flag used to prevent
79: // adding xpr entries while
80: // server is accessing
81: // xprArray. Only written by
82: // server.
83:
84: static xprbuf_t *xprEnd; // Pointer to entry at end of
85: // xprArray
86: static int xprInitialized;
87:
88: /*
89: * DEBUG kernels have a static array of xprBufs so XPRs work before
90: * kalloc() is usable.
91: */
92: #if XPR_DEBUG
93: #define XPR_STATIC_ARRAY_SIZE 2048
94: xprbuf_t xprbuf_static[XPR_STATIC_ARRAY_SIZE];
95: #endif XPR_DEBUG
96:
97: /*
98: * Initialize. Client must call this once, before using any services.
99: */
100: void IOInitDDM(int numBufs)
101: {
102: if(xprInitialized) {
103: return;
104: }
105: #if XPR_DEBUG
106: uxprGlobal.xprArray = xprbuf_static;
107: uxprGlobal.numXprBufs = XPR_STATIC_ARRAY_SIZE;
108: #else XPR_DEBUG
109: uxprGlobal.xprArray = IOMalloc(sizeof(xprbuf_t) * numBufs);
110: uxprGlobal.numXprBufs = numBufs;
111: #endif XPR_DEBUG
112: xprEnd = uxprGlobal.xprArray + uxprGlobal.numXprBufs - 1;
113: IOClearDDM();
114: simple_lock_init(&xpr_lock);
115: #if __nrw__
116: /*
117: * This lets the boot program and the ROM get to the XPR buffer.
118: */
119: mon_global->machdep_global.uxpr_global = &uxprGlobal;
120: #endif __nrw__
121: xprInitialized = 1;
122:
123: #if CLOCK_CALIBRATE
124: {
125: int i;
126: timer_cnt_val_t time;
127:
128: for(i=0; i<100; i++) {
129: timer_latch(TIMER_CNT0_SEL);
130: time = timer_read(TIMER_CNT0_SEL);
131: IOAddDDMEntry("test entry %d time %d\n",
132: i,time,3,4,5);
133: }
134: }
135: #endif CLOCK_CALIBRATE
136: }
137:
138: /*
139: * add one entry to xprArray.
140: */
141: void IOAddDDMEntry(char *str, int arg1, int arg2, int arg3, int arg4, int arg5)
142: {
143: xprbuf_t *last;
144: boolean_t rtn;
145: unsigned s;
146:
147: if(uxprGlobal.xprArray == NULL)
148: return; /* not initialized */
149: s = splhigh();
150: rtn = simple_lock_try(&xpr_lock);
151: if(!rtn) {
152: splx(s);
153: return; /* in case of recursion (e.g.,
154: * in IOTimeStamp()) */
155: }
156: if(xprLocked) {
157: goto out; /* server is messing with
158: * xprArray[] */
159: }
160: if(++uxprGlobal.xprLast > xprEnd) /* wrap around */
161: uxprGlobal.xprLast = uxprGlobal.xprArray;
162: last = uxprGlobal.xprLast;
163: last->msg = str;
164: last->arg1 = arg1;
165: last->arg2 = arg2;
166: last->arg3 = arg3;
167: last->arg4 = arg4;
168: last->arg5 = arg5;
169:
170: #if __nrw__
171: /*
172: * Note that for nrw kernel, timestamp is 32 bits of
173: * half-microseconds.
174: */
175: last->timestamp = (unsigned long long)SYSCLK;
176: last->cpu_num = cpu_number();
177: #else __nrw__
178: last->cpu_num = 0;
179: #if i386 || hppa || ppc
180: IOGetTimestamp(&last->timestamp);
181: #else i386 || hppa || ppc
182: #error machine dependent time stamp needed in ddm.c
183: #endif i386
184: #endif __nrw__
185: if(uxprGlobal.numValidEntries < uxprGlobal.numXprBufs)
186: uxprGlobal.numValidEntries++;
187: out:
188: simple_unlock(&xpr_lock);
189: splx(s);
190: }
191:
192: /*
193: * Clear the array.
194: */
195: void IOClearDDM()
196: {
197: uxprGlobal.xprLast = xprEnd; /* last entry */
198: uxprGlobal.numValidEntries = 0;
199: }
200:
201: /*
202: * Set bit mask of IODDMMasks[index]. Typically used by both client and
203: * the server thread.
204: */
205: void IOSetDDMMask(int index, unsigned int bitmask)
206: {
207: if(index > IO_NUM_DDM_MASKS) {
208: IOLog("xprSetBitmask: illegal index (%d)\n", index);
209: return;
210: }
211: IODDMMasks[index] = bitmask;
212: }
213:
214: unsigned IOGetDDMMask(int index)
215: {
216: if(index > IO_NUM_DDM_MASKS) {
217: IOLog("xprGetBitmask: illegal index (%d)\n", index);
218: return(0);
219: }
220: return IODDMMasks[index];
221: }
222:
223: /*
224: * Obtain one sprintf'd entry from the xprArray. index indicates which entry
225: * to return, counting backwards from the last (latest) entry. Returns
226: * nonzero if specified entry does not exist.
227: */
228: int IOGetDDMEntry(
229: int index, // desired entry
230: int outStringSize, // memory available in outString
231: char *outString, // result goes here
232: unsigned long long *timestamp, // returned
233: int *cpu_num) // returned
234: {
235: xprbuf_t *xprbuf;
236: char xprstring[300];
237:
238: if(index >= uxprGlobal.numValidEntries) {
239: /*
240: * Ran off the end of the buffer.
241: */
242: return -1;
243: }
244: xprbuf = uxprGlobal.xprLast - index;
245: if(xprbuf < uxprGlobal.xprArray)
246: xprbuf += uxprGlobal.numXprBufs;
247:
248: sprintf(xprstring, xprbuf->msg, xprbuf->arg1,
249: xprbuf->arg2,
250: xprbuf->arg3,
251: xprbuf->arg4,
252: xprbuf->arg5);
253: if(strlen(xprstring) > outStringSize)
254: xprstring[outStringSize - 1] = '\0';
255: strcpy(outString, xprstring);
256: *timestamp = xprbuf->timestamp;
257: *cpu_num = xprbuf->cpu_num;
258: return 0;
259: }
260:
261: /*
262: * return a malloc'd copy of instring. To be used when a string to
263: * be XPR'd is volatile; the memory malloc'd here is never
264: * freed!
265: */
266: const char *IOCopyString(const char *instring)
267: {
268: char *outstring = IOMalloc(strlen((char *)instring) + 1);
269:
270: strcpy(outstring, instring);
271: return((const char *)outstring);
272: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.