/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ident	"$Header: kp_nmi.c 1.8 89/08/07 $"

/* $Log:	kp_nmi.c,v $
 */

/*
 * kp_nmi.c - kernel profiler NMI handler
 */

#include "sys/types.h"
#include "sys/param.h"
#include "sys/debug.h"
#include "sys/vm.h"
#include "sys/mutex.h"
#include "sys/dir.h"
#include "sys/signal.h"
#include "sys/user.h"
#include "sys/conf.h"
#include "sys/buf.h"
#include "sys/uio.h"
#include "sys/systm.h"
#include "sys/ioctl.h"

#include "sys/slic.h"
#include "sys/cfg.h"

#include "sys/reg.h"
#include "sys/pte.h"
#include "sys/psl.h"
#include "sys/hwparam.h"
#include "sys/plocal.h"
#include "sys/intctl.h"
#include "sys/mftpr.h"

#include "sys/sec.h"
#include "sys/kp.h"

/*
 * Global data structures.
 */
extern ulong *kp_nmis;		/* ptr to # of NMI's recv'd per processor */
extern struct pc_mode *kp_pc_m;	/* ptr to pc/mode pairs */


/*
 * kp_nmi(): Handle profiler NMI's
 *		returns:	0 if profiler NMI
 *				1 otherwise
 */

/*ARGSUSED*/
kp_nmi(es, ds, type, edi, esi, ebp, unused, ebx, edx, ecx, eax, eip, cs, flags, sp, ss)
	unsigned es;
	unsigned ds;
	int	type;		/* type of trap */
	unsigned ss;		/* only if inter-segment (user->kernel) */
	unsigned sp;		/* only if inter-segment (user->kernel) */
	unsigned flags;		/* extended-flags (see machine/psl.h) */
	unsigned cs;		/* sense user-mode entry from RPL field */
	unsigned eip;		/* return context */
	unsigned eax;		/* scratch registers */
	unsigned ecx;		/* ditto */
	unsigned edx;		/* more such */
	unsigned ebx;		/* register variable */
	unsigned unused;	/* temp SP (from push-all instruction) */
	unsigned ebp;		/* of interrupted frame */
	unsigned esi;		/* register variable */
	unsigned edi;		/* register variable */
{
	register int me = l.me;

	if (va_slic->sl_nmiint == NMI_PROF) {
		/*
		 * store away the pc and mode for the SCED
		 */
		kp_pc_m[me].pm_pc = eip;
		kp_pc_m[me].pm_mode = USERMODE(cs);
		/* instrumentation */
		kp_nmis[me]++;
		return(0);
	} else {
		return(1);
	}
}
