File:  [MW Coherent from dump] / coherent / d / PS2_KERNEL / i286 / trap.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/* $Header: /var/lib/cvsd/repos/coherent/coherent/d/PS2_KERNEL/i286/trap.c,v 1.1.1.1 2019/05/29 04:56:39 root Exp $ */
/* (lgl-
 *	The information contained herein is a trade secret of Mark Williams
 *	Company, and  is confidential information.  It is provided  under a
 *	license agreement,  and may be  copied or disclosed  only under the
 *	terms of  that agreement.  Any  reproduction or disclosure  of this
 *	material without the express written authorization of Mark Williams
 *	Company or persuant to the license agreement is unlawful.
 *
 *	COHERENT Version 2.3.37
 *	Copyright (c) 1982, 1983, 1984.
 *	An unpublished work by Mark Williams Company, Chicago.
 *	All rights reserved.
 -lgl) */
/*
 * Trap handler.
 * 8086/8088 Coherent, IBM PC.
 *
 * $Log: trap.c,v $
 * Revision 1.1.1.1  2019/05/29 04:56:39  root
 * coherent
 *
 * Revision 1.1  92/07/17  15:21:35  bin
 * Initial revision
 * 
 * Revision 1.1	88/03/24  17:39:53	src
 * Initial revision
 * 
 * 88/03/06	Allan Cornish		/usr/src/sys/i8086/src/trap.c
 * Exception diagnostistics extended.
 *
 * 87/11/02	Allan Cornish		/usr/src/sys/i8086/src/trap.c
 * iAPX 286 exception traps added.
 */
#include <sys/coherent.h>
#include <sys/i8086.h>
#include <sys/systab.h>
#include <errno.h>
#include <sys/proc.h>
#include <sys/seg.h>
#include <signal.h>

#ifndef	EBUG
#define	EBUG 1
#endif

/*
 * Trap handler.
 * The arguments are the registers,
 * saved on the stack by machine code. This call
 * is different from most C calls in that the registers
 * get copied back; if you change a "trap" parameter then
 * the machine register will be altered when the trap is
 * dismissed.
 */
trap(es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw)
unsigned es, cx, dx, ax, bx, ds, usp, uss, id, ip, cs, fw;
{
	register struct	systab	*stp;
	register int	syscall;
	register int	callnum;
	register int	sigcode;
	long		l;

	if ( (id >> 8) == SINMI )
		panic( "Parity error: cs=%x ip=%x\n", cs, ip );

	if (depth != 0) {
#if EBUG > 0
		faddr_t fp;
		FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
		FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
		FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
		FP_SEL(fp) = es;  printf("es "); vprint(fp);
		FP_SEL(fp) = uss; printf("ss "); vprint(fp);
#endif
		panic("system trap: id=%x ip=%x ax=%x", id, ip, ax);
	}

	if ((SELF->p_flags&PFKERN) != 0) {
#if EBUG > 0
		faddr_t fp;
		FP_SEL(fp) = ax;  printf("ax "); vprint(fp);
		FP_SEL(fp) = cs;  printf("cs "); vprint(fp);
		FP_SEL(fp) = ds;  printf("ds "); vprint(fp);
		FP_SEL(fp) = es;  printf("es "); vprint(fp);
		FP_SEL(fp) = uss; printf("ss "); vprint(fp);
#endif
		panic("pid%d: kernel process trap: id=%x, ip=%x ax=%d",
			SELF->p_pid, id, ip, ax);
	}

	/*
	 * System call.
	 */
	if ( (id >> 8) == SISYS ) {
		u.u_error = 0;
		sigcode = 0;
		syscall = getuwi(ip-2);
		if (u.u_error != 0 || (syscall&0xFF) != 0xCD) {
			sigcode = SIGSYS;
			goto trapend;
		}
		callnum = (syscall>>8) & 0x7F;
		if (callnum >= NMICALL) {
			sigcode = SIGSYS;
			goto trapend;
		}
		stp = &sysitab[callnum];
		ukcopy(usp+2, u.u_args, stp->s_alen);
		if (u.u_error != 0) {
			sigcode = SIGSYS;
			goto trapend;
		}
		u.u_io.io_seg = IOUSR;
		if (envsave(&u.u_sigenv) != 0)
			u.u_error = EINTR;
		else if ( stp->s_alen <= (3 * sizeof(int)) ) {
			l = (*(long(*)())stp->s_func)(u.u_args[0],
						      u.u_args[1],
						      u.u_args[2] );
			ax = ((struct l *) &l)->l_lo;
			dx = ((struct l *) &l)->l_hi;
		}
		else {
			l = (*(long(*)())stp->s_func)(u.u_args[0],
						      u.u_args[1],
						      u.u_args[2],
						      u.u_args[3],
						      u.u_args[4],
						      u.u_args[5]);
			ax = ((struct l *) &l)->l_lo;
			dx = ((struct l *) &l)->l_hi;
		}
		if (u.u_error != 0) {
			ax = -1;
			dx = -1;
			putuwd(MUERR, u.u_error);
			if (u.u_error == EFAULT)
				sigcode = SIGSYS;
		}
	}

	/*
	 * Trap.
	 */
	else switch (id>>8) {

	case SIDIV:
		sigcode = SIGDIVE;
		break;

	case SISST:
		sigcode = SIGTRAP;
		break;

	case SIBPT:
		sigcode = SIGTRAP;
		break;

	case SIOVF:
		sigcode = SIGOVFL;
		break;

	case SIBND:
		/*
		 * Bound
		 */
		sigcode = SIGOVFL;
		break;

	case SIOP:
		/*
		 * Invalid opcode
		 */
		sigcode = SIGSEGV;
		break;

	case SIXNP:
		/*
		 * Processor extension not available
		 */
		sigcode = SIGSEGV;
		break;

	case SIDBL:
		/*
		 * Double exception
		 */
		panic("double exception: cs=%x ip=%x", cs, ip);
		sigcode = SIGSEGV;
		break;

	case SIXS:
		/*
		 * Processor extension segment overrun
		 */
		sigcode = SIGSEGV;
		break;

	case SITS:
		/*
		 * Invalid task state segment
		 */
		panic("invalid tss: cs=%x ip=%x", cs, ip);
		sigcode = SIGSEGV;
		break;

	case SINP:
		/*
		 * Segment not present
		 */
		sigcode = SIGSEGV;
		break;

	case SISS:
		/*
		 * Stack segment overrun/not present
		 */
		sigcode = SIGKILL;
		break;

	case SIGP:
		/*
		 * General protection.
		 */
		sigcode = SIGSEGV;
		break;

	default:
		panic("user trap: id=%x ip=%x\n", id, ip );
	}

trapend:
	if ( sigcode != 0 ) {
		if ( sigcode == SIGSEGV ) {
#if EBUG > 0
			faddr_t fp;
			FP_SEL(fp) = ax;  printf("\tax "); vprint(fp);
			FP_SEL(fp) = cs;  printf("\tcs "); vprint(fp);
			FP_SEL(fp) = ds;  printf("\tds "); vprint(fp);
			FP_SEL(fp) = es;  printf("\tes "); vprint(fp);
			FP_SEL(fp) = uss; printf("\tss "); vprint(fp);
			printf("user trap: SEGV id=%x ax=%x pid=%d\n",
				id, ax, SELF->p_pid );
		{  char cmd[11]; int i;
			for (i = 0; i < 10; i++) {
				cmd[i] = u.u_comm[i];
			}
			cmd[10] = '\0';
			printf("\tip=%x sp=%x cmd=%s\n", ip, usp, cmd);
		}

			/*
			 * Force core dump.
			 */
			u.u_sfunc[SIGSEGV] = SIG_DFL;
#endif
		}
		sendsig(sigcode, SELF);
	}
}

unix.superglobalmegacorp.com

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