File:  [Apple Darwin 0.x] / driverkit / libDriver / User / debugging.m
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:37:51 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin02
Darwin 0.2 Driver Kit

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.1 (the "License").  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/* 	Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
 *
 * debugging.m - driverkit debugging module.
 *
 * HISTORY
 * 22-Feb-91    Doug Mitchell at NeXT
 *      Created. 
 */

#import <bsd/sys/types.h>
#import <driverkit/debugging.h>
#import <driverkit/ddmPrivate.h>
#import <driverkit/generalFuncs.h>
#import <machkit/NXLock.h>
#import <driverkit/return.h>
#ifdef	KERNEL
#import <kernserv/prototypes.h>
#import <kernserv/machine/cpu_number.h>
#else	KERNEL
#import <bsd/libc.h>
#endif	KERNEL

#if	KERNEL && __nrw__
#define _MON_TYPES_BOOLEAN_
#define _MON_TYPES_CPUTYPES_
#define _MON_TYPES_SIZE_
#define	_MON_BIT_MACROS_
#import <mon/mon_global.h>
#endif	KERNEL && __nrw__

#if	TIMESTAMP_HALF_USEC
static unsigned xprTimeStamp();
#endif	TIMESTAMP_HALF_USEC

/*
 * xprbuf_t's are kept in a circular buffer, uxprGlobal.xprArray. New 
 * entries are added when the client calls xprAdd. The buffer is examined 
 * from an external task which communicates with xprServerThread via 
 * simple Mach messages.
 */
 
/*
 * Globals.
 */
unsigned	IODDMMasks[IO_NUM_DDM_MASKS];	
					/* an array of task-specific bits. 
					 * Typically tweaked at run time. */
uxprGlobal_t	uxprGlobal;
id		xprLock;		/* NXSpinLock. protects xprLocked */
int 		xprLocked = 0;		/* Simple flag used to prevent adding 
					 * xpr entries while server is 
					 * accessing xprArray. Only written by
					 * server. */

static xprbuf_t *xprEnd;		/* Pointer to entry at end of 
					 * xprArray */
static int	xprInitialized;

/*
 * Initialize. Client must call this once, before using any services.
 */
#ifdef	KERNEL
void IOInitDDM(int numBufs)
#else	KERNEL
void IOInitDDM(int numBufs, char *serverPortName)
#endif	KERNEL
{
	if(xprInitialized) {
		return;
	}
	uxprGlobal.xprArray = IOMalloc(sizeof(xprbuf_t) * numBufs);
	uxprGlobal.numXprBufs = numBufs;
	xprEnd = uxprGlobal.xprArray + uxprGlobal.numXprBufs - 1;
	IOClearDDM();
	xprLock = [NXSpinLock new];
	
#ifndef	KERNEL
	/*
	 * Start up the server thread for user version. Kernel server 
	 * is implemented via kernserv.
	 */
	IOForkThread((IOThreadFunc)xprServerThread, serverPortName);
#else	KERNEL
#if	__nrw__
	mon_global->machdep_global.uxpr_global = &uxprGlobal;
#endif	__nrw__
#endif	KERNEL
	xprInitialized = 1;
}

/*
 * add one entry to xprArray.
 */
void IOAddDDMEntry(char *str, int arg1, int arg2, 
				    int arg3, int arg4, int arg5)
{
	xprbuf_t *last;
	
	if(uxprGlobal.xprArray == NULL)
		return;				/* not initialized */
	[xprLock lock];
	if(xprLocked) {
		[xprLock unlock];
		return;
	}
	if(++uxprGlobal.xprLast > xprEnd)	/* wrap around */
		uxprGlobal.xprLast = uxprGlobal.xprArray;	
	last = uxprGlobal.xprLast;
	last->msg = str;
	last->arg1 = arg1;
	last->arg2 = arg2;
	last->arg3 = arg3;
	last->arg4 = arg4;
	last->arg5 = arg5;
	
	/*
	 * As of 17-Aug-92, timestamp is 32 bits of 
	 * half-microseconds.
	 */
#if	TIMESTAMP_HALF_USEC
	last->timestamp = (unsigned long long)xprTimeStamp();
#else	TIMESTAMP_HALF_USEC
	IOGetTimestamp(&last->timestamp);
#endif	TIMESTAMP_HALF_USEC

#if	KERNEL && __nrw__
	last->cpu_num = cpu_number();
#else	KERNEL && __nrw__
	last->cpu_num = 0;
#endif	KERNEL && __nrw__
	if(uxprGlobal.numValidEntries < uxprGlobal.numXprBufs)
		uxprGlobal.numValidEntries++;
	[xprLock unlock];
}

/*
 * Clear the array.
 */
void IOClearDDM()
{
	uxprGlobal.xprLast = xprEnd;		/* last entry */
	uxprGlobal.numValidEntries = 0;
}

/*
 * Set bit mask of IODDMMasks[index]. Typically used by both client and 
 * the server thread.
 */
void IOSetDDMMask(int index, unsigned int bitmask)
{
	if(index > IO_NUM_DDM_MASKS) {
		IOLog("xprSetBitmask: illegal index (%d)\n", index);
		return;
	}
	IODDMMasks[index] = bitmask;
}

unsigned IOGetDDMMask(int index)
{
	if(index > IO_NUM_DDM_MASKS) {
		IOLog("xprGetBitmask: illegal index (%d)\n", index);
		return(0);
	}
	return IODDMMasks[index];
}

/*
 * Obtain one sprintf'd entry from the xprArray. index indicates which entry 
 * to return, counting backwards from the last (latest) entry. Returns 
 * nonzero if specified entry does not exist.
 */
int IOGetDDMEntry(
	int 		index, 		// desired entry
	int 		outStringSize,	// memory available in outString
	char 		*outString, 	// result goes here
	unsigned long long *timestamp,	// returned
	int 		*cpu_num)	// returned
{
	xprbuf_t *xprbuf;
	char xprstring[300];

	if(index >= uxprGlobal.numValidEntries) {
		/*
		 * Ran off the end of the buffer.
		 */
		return -1;
	}
	xprbuf = uxprGlobal.xprLast - index;
	if(xprbuf < uxprGlobal.xprArray)
		xprbuf += uxprGlobal.numXprBufs;		
	
	sprintf(xprstring, xprbuf->msg, xprbuf->arg1, 
		xprbuf->arg2, 
		xprbuf->arg3, 
		xprbuf->arg4, 
		xprbuf->arg5); 
	if(strlen(xprstring) > outStringSize)
		xprstring[outStringSize - 1] = '\0';
	strcpy(outString, xprstring);
	*timestamp = xprbuf->timestamp;
	*cpu_num   = xprbuf->cpu_num;
	return 0;
}

/*
 * return a malloc'd copy of instring. To be used when a string to 
 * be XPR'd is volatile; the memory malloc'd here is never
 * freed!
 */
const char *IOCopyString(const char *instring)
{
	char *outstring = IOMalloc(strlen((char *)instring));
	
	strcpy(outstring, instring);
	return((const char *)outstring);
}

#if	TIMESTAMP_HALF_USEC
/*
 * Obtain timestamp - 32 bits of half-microseconds.
 */
static unsigned xprTimeStamp()
{
	struct tsval ts;
	
	kern_timestamp(&ts);
	return (ts.low_val * 2);
}

#endif	TIMESTAMP_HALF_USEC

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.