|
|
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: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
25: *
26: * debugging.m - driverkit debugging module.
27: *
28: * HISTORY
29: * 22-Feb-91 Doug Mitchell at NeXT
30: * Created.
31: */
32:
33: #import <bsd/sys/types.h>
34: #import <driverkit/debugging.h>
35: #import <driverkit/ddmPrivate.h>
36: #import <driverkit/generalFuncs.h>
37: #import <machkit/NXLock.h>
38: #import <driverkit/return.h>
39: #ifdef KERNEL
40: #import <kernserv/prototypes.h>
41: #import <kernserv/machine/cpu_number.h>
42: #else KERNEL
43: #import <bsd/libc.h>
44: #endif KERNEL
45:
46: #if KERNEL && __nrw__
47: #define _MON_TYPES_BOOLEAN_
48: #define _MON_TYPES_CPUTYPES_
49: #define _MON_TYPES_SIZE_
50: #define _MON_BIT_MACROS_
51: #import <mon/mon_global.h>
52: #endif KERNEL && __nrw__
53:
54: #if TIMESTAMP_HALF_USEC
55: static unsigned xprTimeStamp();
56: #endif TIMESTAMP_HALF_USEC
57:
58: /*
59: * xprbuf_t's are kept in a circular buffer, uxprGlobal.xprArray. New
60: * entries are added when the client calls xprAdd. The buffer is examined
61: * from an external task which communicates with xprServerThread via
62: * simple Mach messages.
63: */
64:
65: /*
66: * Globals.
67: */
68: unsigned IODDMMasks[IO_NUM_DDM_MASKS];
69: /* an array of task-specific bits.
70: * Typically tweaked at run time. */
71: uxprGlobal_t uxprGlobal;
72: id xprLock; /* NXSpinLock. protects xprLocked */
73: int xprLocked = 0; /* Simple flag used to prevent adding
74: * xpr entries while server is
75: * accessing xprArray. Only written by
76: * server. */
77:
78: static xprbuf_t *xprEnd; /* Pointer to entry at end of
79: * xprArray */
80: static int xprInitialized;
81:
82: /*
83: * Initialize. Client must call this once, before using any services.
84: */
85: #ifdef KERNEL
86: void IOInitDDM(int numBufs)
87: #else KERNEL
88: void IOInitDDM(int numBufs, char *serverPortName)
89: #endif KERNEL
90: {
91: if(xprInitialized) {
92: return;
93: }
94: uxprGlobal.xprArray = IOMalloc(sizeof(xprbuf_t) * numBufs);
95: uxprGlobal.numXprBufs = numBufs;
96: xprEnd = uxprGlobal.xprArray + uxprGlobal.numXprBufs - 1;
97: IOClearDDM();
98: xprLock = [NXSpinLock new];
99:
100: #ifndef KERNEL
101: /*
102: * Start up the server thread for user version. Kernel server
103: * is implemented via kernserv.
104: */
105: IOForkThread((IOThreadFunc)xprServerThread, serverPortName);
106: #else KERNEL
107: #if __nrw__
108: mon_global->machdep_global.uxpr_global = &uxprGlobal;
109: #endif __nrw__
110: #endif KERNEL
111: xprInitialized = 1;
112: }
113:
114: /*
115: * add one entry to xprArray.
116: */
117: void IOAddDDMEntry(char *str, int arg1, int arg2,
118: int arg3, int arg4, int arg5)
119: {
120: xprbuf_t *last;
121:
122: if(uxprGlobal.xprArray == NULL)
123: return; /* not initialized */
124: [xprLock lock];
125: if(xprLocked) {
126: [xprLock unlock];
127: return;
128: }
129: if(++uxprGlobal.xprLast > xprEnd) /* wrap around */
130: uxprGlobal.xprLast = uxprGlobal.xprArray;
131: last = uxprGlobal.xprLast;
132: last->msg = str;
133: last->arg1 = arg1;
134: last->arg2 = arg2;
135: last->arg3 = arg3;
136: last->arg4 = arg4;
137: last->arg5 = arg5;
138:
139: /*
140: * As of 17-Aug-92, timestamp is 32 bits of
141: * half-microseconds.
142: */
143: #if TIMESTAMP_HALF_USEC
144: last->timestamp = (unsigned long long)xprTimeStamp();
145: #else TIMESTAMP_HALF_USEC
146: IOGetTimestamp(&last->timestamp);
147: #endif TIMESTAMP_HALF_USEC
148:
149: #if KERNEL && __nrw__
150: last->cpu_num = cpu_number();
151: #else KERNEL && __nrw__
152: last->cpu_num = 0;
153: #endif KERNEL && __nrw__
154: if(uxprGlobal.numValidEntries < uxprGlobal.numXprBufs)
155: uxprGlobal.numValidEntries++;
156: [xprLock unlock];
157: }
158:
159: /*
160: * Clear the array.
161: */
162: void IOClearDDM()
163: {
164: uxprGlobal.xprLast = xprEnd; /* last entry */
165: uxprGlobal.numValidEntries = 0;
166: }
167:
168: /*
169: * Set bit mask of IODDMMasks[index]. Typically used by both client and
170: * the server thread.
171: */
172: void IOSetDDMMask(int index, unsigned int bitmask)
173: {
174: if(index > IO_NUM_DDM_MASKS) {
175: IOLog("xprSetBitmask: illegal index (%d)\n", index);
176: return;
177: }
178: IODDMMasks[index] = bitmask;
179: }
180:
181: unsigned IOGetDDMMask(int index)
182: {
183: if(index > IO_NUM_DDM_MASKS) {
184: IOLog("xprGetBitmask: illegal index (%d)\n", index);
185: return(0);
186: }
187: return IODDMMasks[index];
188: }
189:
190: /*
191: * Obtain one sprintf'd entry from the xprArray. index indicates which entry
192: * to return, counting backwards from the last (latest) entry. Returns
193: * nonzero if specified entry does not exist.
194: */
195: int IOGetDDMEntry(
196: int index, // desired entry
197: int outStringSize, // memory available in outString
198: char *outString, // result goes here
199: unsigned long long *timestamp, // returned
200: int *cpu_num) // returned
201: {
202: xprbuf_t *xprbuf;
203: char xprstring[300];
204:
205: if(index >= uxprGlobal.numValidEntries) {
206: /*
207: * Ran off the end of the buffer.
208: */
209: return -1;
210: }
211: xprbuf = uxprGlobal.xprLast - index;
212: if(xprbuf < uxprGlobal.xprArray)
213: xprbuf += uxprGlobal.numXprBufs;
214:
215: sprintf(xprstring, xprbuf->msg, xprbuf->arg1,
216: xprbuf->arg2,
217: xprbuf->arg3,
218: xprbuf->arg4,
219: xprbuf->arg5);
220: if(strlen(xprstring) > outStringSize)
221: xprstring[outStringSize - 1] = '\0';
222: strcpy(outString, xprstring);
223: *timestamp = xprbuf->timestamp;
224: *cpu_num = xprbuf->cpu_num;
225: return 0;
226: }
227:
228: /*
229: * return a malloc'd copy of instring. To be used when a string to
230: * be XPR'd is volatile; the memory malloc'd here is never
231: * freed!
232: */
233: const char *IOCopyString(const char *instring)
234: {
235: char *outstring = IOMalloc(strlen((char *)instring));
236:
237: strcpy(outstring, instring);
238: return((const char *)outstring);
239: }
240:
241: #if TIMESTAMP_HALF_USEC
242: /*
243: * Obtain timestamp - 32 bits of half-microseconds.
244: */
245: static unsigned xprTimeStamp()
246: {
247: struct tsval ts;
248:
249: kern_timestamp(&ts);
250: return (ts.low_val * 2);
251: }
252:
253: #endif TIMESTAMP_HALF_USEC
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.