Interdata732/usr/sys/trap.c

Compare this file to the similar file:
Show the results in this format:

#
#include "param.h"
#include "systm.h"
#include "user.h"
#include "proc.h"
#include "reg.h"
#include "seg.h"

#define	EBIT	010	/*** user err bit in psw: C-bit ***/
#define	UMODE	01<<8	/*** user-mode bit in tsw (prot bit) ***/
#define	SYS	0341	/*** svc (trap) instruction ***/
#define	USER	020	/* user-mode flag added to dev */

/*
 * structure of the system entry table (sysent.c)
 */
extern struct sysent	{
	int	count;		/* argument count */
	int	(*call)();	/* name of handler */
} sysent[64];

/*
 * Offsets of the user's registers relative to
 * the saved r0. See reg.h
 */
int	regloc[18]
{
	R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,		/***/
	R8,  R9,  R10, R11, R12, R13, R14, R15,		/***/
	RPS, RPC
};

/*
 * Called from low.s when a processor trap occurs.
 * The arguments are the words saved on the system stack
 * by the software during the trap processing.
 * Their order is dictated by the details
 * of C's calling sequence. They are peculiar in that
 * this call is not 'by value' and changed user registers
 * get copied back on return.
 * dev is the kind of trap that occurred.
 */
trap(dev, stat, r0, r1, r2, r3, r4, r5, r6, asp, rf, ps, pc, nps) /***/
{
	register i, a;
	register struct sysent *callp;

	trace(02, "trap", dev);
	trace(02, "psw", pc);

#ifdef FPREGS
	savfp();
#endif

	if ((ps&UMODE) == UMODE)
		dev =| USER;
	u.u_ar0 = &r0;
	switch(dev) {

	/*
	 * Trap not expected.
	 * Usually a kernel mode address error.
	 */
	default:
		printf("Useg = %x\n", *ka6);
		printf("PSW = %x %x\n", ps, pc);
		printf("SP = %x\n", asp);
		printf("trap type %d\n", dev);
		panic("trap");

	case 0+USER: /* address error */
		i = SIGBUS;
		break;

	case 1+USER: /* illegal instruction */

#ifdef FPTRAP
	/****	if illegal instruction assume it to be a floating
	point one and call fptrap.
		passing fptrap a pointer to the user's saved r0
	( see reg.h ) and a pointer to his fp regs in the ppda  ****/
		if ( i=fptrap(&r0,u.u_fsav))
			break;			/***  error returned by fptrap ***/
		goto out;
#else
		i = SIGINS;
		break;
#endif

	case 2+USER: /* bpt or trace */
		i = SIGTRC;
		break;

	case 3+USER: /* iot */
		i = SIGIOT;
		break;

	case 5+USER: /* emt */
		i = SIGEMT;
		break;

	case 6+USER: /* sys call */
		u.u_error = 0;
		ps =& ~EBIT;
		callp = &sysent[stat&077];	/*** stat is svc no. ***/
		if (callp == sysent) { /* indirect */
			a = fuiword(pc);
			pc =+ 4;		/***/
			i = fuword(a);
			if ((i >> 24) != SYS)
				i = 077;	/* illegal */
			callp = &sysent[i&077];
			for(i=0; i<callp->count; i++)
				u.u_arg[i] = fuword(a =+ 4);	/***/
		} else {
			for(i=0; i<callp->count; i++) {
				u.u_arg[i] = fuiword(pc);
				pc =+ 4;		/***/
			}
		}
		trace(04, "svc", callp-sysent);
		u.u_dirp = u.u_arg[0];
		trap1(callp->call);
		if(u.u_intflg)
			u.u_error = EINTR;
		if(u.u_error < 100) {
			if(u.u_error) {
				ps =| EBIT;
				r0 = u.u_error;
			}
			goto out;
		}
		i = SIGSYS;
		break;

	/*
	 * Since the floating exception is an
	 * imprecise trap, a user generated
	 * trap may actually come from kernel
	 * mode. In this case, a signal is sent
	 * to the current process to be picked
	 * up later.
	 */
	case 8: /* floating exception */
		psignal(u.u_procp, SIGFPT);
		return;

	case 8+USER:
		i = SIGFPT;
		break;

	/*
	 * If the user SP is below the stack segment,
	 * grow the stack automatically.
	 * This relies on the ability of the hardware
	 * to restart a half executed instruction.
	 * At the moment this is unimplemented (and possibly
	 * unimplementable) on the Interdata.
	 */
	case 9+USER: /* segmentation exception */

/***
		a = asp;
		if(backup(u.u_ar0) == 0)
		if(grow(a))
			goto out;
***/

		i = SIGSEG;
		break;

	case 10+USER: /* illegal svc number */
		i = SIGSYS;
		break;
	}
	psignal(u.u_procp, i);

out:
	if(issig())
		psig();
	setpri(u.u_procp);
}

/*
 * Call the system-entry routine f (out of the
 * sysent table). This is a subroutine for trap, and
 * not in-line, because if a signal occurs
 * during processing, an (abnormal) return is simulated from
 * the last caller to savu(qsav); if this took place
 * inside of trap, it wouldn't have a chance to clean up.
 *
 * If this occurs, the return takes place without
 * clearing u_intflg; if it's still set, trap
 * marks an error which means that a system
 * call (like read on a typewriter) got interrupted
 * by a signal.
 */
trap1(f)
int (*f)();
{

	u.u_intflg = 1;
	savu(u.u_qsav);
	(*f)();
	u.u_intflg = 0;
}

/*
 * nonexistent system call-- set fatal error code.
 */
nosys()
{
	u.u_error = 100;
}

/*
 * Ignored system call
 */
nullsys()
{
}