/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by Mike Parker.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <vax/mtpr.h>
#include <vax/psl.h>

#include "../sys/rciext/kacrash.h"

#include "regs.h"

arithtrap(args,regs)
struct {
  int type;
  int pc;
  int psl;
  } *args;
int regs[];
{
 static char *types[] = { "Type 0",
			  "Integer overflow trap",
			  "Integer divide-by-zero trap",
			  "Floating overflow trap",
			  "Floating/decimal divide-by-zero trap",
			  "Floating underflow trap",
			  "Decimal overflow trap",
			  "Subscript range trap",
			  "Floating overflow fault",
			  "Floating divide-by-zero fault",
			  "Floating underflow fault" };
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Arithmetic exception: pc = %08x, psl = %08x\n",args->pc,args->psl);
    if ((args->type < 1) || (args->type >= (sizeof(types)/sizeof(types[0]))))
     { printf("Unknown type %d\n",args->type);
     }
    else
     { printf("%s\n",types[args->type]);
     }
    regdump(regs);
    panic("arithmetic exception");
  }
 crashinfo.type = CI_ARITHTRAP;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = args->type;
 usercrash(regs);
}

bpt(args,regs)
struct {
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Breakpoint trap: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("breakpoint");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_BPT;
 usercrash(regs);
}

chmx(args,regs)
struct {
  int code;
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Change mode instruction in kernel: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("chm? in kernel");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_PRIVINST;
 usercrash(regs);
}

resoprnd(args,regs)
struct {
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Reserved operand fault: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("reserved operand");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_RESOPRND;
 usercrash(regs);
}

radrmod(args,regs)
struct {
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Reserved addressing mode: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("reserved addressing mode");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_RADRMOD;
 usercrash(regs);
}

privinst(args,regs)
struct {
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("Privileged instruction fault: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("privinst");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_PRIVINST;
 usercrash(regs);
}

xfc(args,regs)
struct {
  int pc;
  int psl;
  } *args;
int regs[];
{
 extern CRASHINFO crashinfo;

 if ((args->psl & PSL_CURMOD) != PSL_CURMOD)
  { printf("XFC instruction: pc = %08x, psl = %08x\n",args->pc,args->psl);
    regdump(regs);
    panic("xfc instruction");
  }
 crashinfo.type = CI_ILLINST;
 crashinfo.pc = args->pc;
 crashinfo.psl = args->psl;
 crashinfo.u.subtype = CI_II_PRIVINST;
 usercrash(regs);
}

kaqbmchk(mckinfo,addr)
struct {
  int type;
  int vaddr;
  int state;
  int pc;
  int psl;
  } *mckinfo;
int addr;
{
 extern CRASHINFO crashinfo;
 extern int trapregs[];

 crashinfo.type = CI_MEMFAULT;
 crashinfo.pc = mckinfo->pc;
 crashinfo.psl = mckinfo->psl;
 crashinfo.u.memfault.bits = ((mckinfo->type & 2) ? CI_MF_WRITE : CI_MF_READ) | CI_MF_PAGE | CI_MF_PROT | CI_MF_QBUS;
 crashinfo.u.memfault.vaddr = mckinfo->vaddr;
 usercrash(trapregs);
 return(1);
}

regdump(regs)
int regs[];
{
 printf("r0 = %08x   r4 = %08x   r8 = %08x   ap = %08x\n",
				regs[R0],regs[R4],regs[R8],regs[AP]);
 printf("r1 = %08x   r5 = %08x   r9 = %08x   fp = %08x\n",
				regs[R1],regs[R5],regs[R9],regs[FP]);
 printf("r2 = %08x   r6 = %08x  r10 = %08x  usp = %08x\n",
				regs[R2],regs[R6],regs[R10],mfpr(USP));
 printf("r3 = %08x   r7 = %08x  r11 = %08x\n",
				regs[R3],regs[R7],regs[R11]);
}
