--- cci/sys/tahoe/trap.c 2019/07/28 12:24:19 1.1 +++ cci/sys/tahoe/trap.c 2019/07/28 12:30:01 1.1.1.2 @@ -14,12 +14,14 @@ #include "../h/acct.h" #include "../h/kernel.h" #include "../machine/mtpr.h" +#include "../machine/alignment.h" #ifdef SYSCALLTRACE #include "../sys/syscalls.c" #endif #include "../machine/fp_in_krnl.h" #define USER 040 /* user-mode flag added to type */ +#define SYSTEM 0xc0000000 /* system space */ struct sysent sysent[]; int nsysent; @@ -27,7 +29,7 @@ int nsysent; /* * Called from the trap handler when a processor trap occurs. */ -trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) +trap(sP, type, hfs, accmst, acclst, dbl, code, pC, psL) unsigned code; { /* Next 2 dummy variables MUST BE the first local */ @@ -39,17 +41,23 @@ unsigned code; register dumm3; /* register 12 is the 1'st register variable */ /* in TAHOE (register 11 in VAX) */ - register int *locr0 = ((int *)&psl)-PS; + register int *locr0 = ((int *)&psL)-PS; register int i; register struct proc *p; struct timeval syst; char *typename; + process_info *infop; syst = u.u_ru.ru_stime; if (USERMODE(locr0[PS])) { type |= USER; u.u_ar0 = locr0; + } else if (u.u_eosys & EMULATEALIGN) { + type |= USER; + u.u_ar0 = locr0; + locr0[PS] |= PSL_USERSET; } + switch (type) { default: switch (type) { @@ -83,10 +91,14 @@ unsigned code; typename = "kernel stack not valid";break; } printf("System trap (%s), code = %x, pc = %x\n", - typename, code, pc); + typename, code, pC); panic("trap"); case T_PROTFLT + USER: /* protection fault */ + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + } i = SIGBUS; break; @@ -94,6 +106,12 @@ unsigned code; case T_RESADFLT + USER: /* reserved addressing fault */ case T_RESOPFLT + USER: /* resereved operand fault */ case T_ALIGNFLT + USER: /* unaligned data fault */ + if (u.u_eosys & EMULATEALIGN) { + typename="miscellaneous illegal user instruction"; + printf("In this System trap (%s), code = %x, pc = %x\n", + typename, code, pC); + panic("trap"); + } u.u_code = type &~ USER; i = SIGILL; break; @@ -102,12 +120,22 @@ unsigned code; case T_ASTFLT: astoff(); if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) { - addupc(pc, &u.u_prof, 1); + addupc(pC, &u.u_prof, 1); u.u_procp->p_flag &= ~SOWEUPC; } + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + locr0[PS] &= ~PSL_USERSET; + } goto out; case T_ARITHTRAP + USER: + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + printf("in arithtrap with emulation,locr0[PC] = 0x%x, locr0[PS] = 0x%x \n",locr0[PC],locr0[PS]); + } u.u_code = code; i = SIGFPE; break; @@ -117,8 +145,15 @@ unsigned code; * grow the stack automatically. */ case T_SEGFLT + USER: - if (grow((unsigned)locr0[SP]) || grow(code)) + if (grow((unsigned)locr0[SP]) || grow(code)) { + if (u.u_eosys & EMULATEALIGN) + locr0[PS] &= ~PSL_USERSET; goto out; + } + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + } i = SIGSEGV; break; @@ -131,17 +166,29 @@ unsigned code; i = u.u_error; pagein(code, 0); u.u_error = i; + if (u.u_eosys & EMULATEALIGN) { + locr0[PS] &= ~PSL_USERSET; + return; + } if (type == T_PAGEFLT) return; goto out; case T_BPTFLT + USER: /* bpt instruction fault */ case T_TRCTRAP + USER: /* trace trap */ + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + } locr0[PS] &= ~PSL_T; i = SIGTRAP; break; case T_KSPNOTVAL: case T_KSPNOTVAL + USER: + if (u.u_eosys & EMULATEALIGN) { + infop = (process_info *)(SYSTEM - sizeof(process_info)); + locr0[PC] = saved_pc; + } i = SIGKILL; /* There is nothing to do but to kill the * process.. */ printf("KSP NOT VALID.\n"); @@ -187,7 +234,7 @@ int syscalltrace = 0; /* * Called from the trap handler when a system call occurs */ -syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) +syscall(Sp, type, hfs, accmst, acclst, dbl, code, pC, psL) unsigned code; { /* Next 2 dummy variables MUST BE the first local */ @@ -199,7 +246,7 @@ unsigned code; register dumm3; /* register 12 is the 1'st register variable */ /* in TAHOE (register 11 in VAX) */ - register int *locr0 = ((int *)&psl)-PS; + register int *locr0 = ((int *)&psL)-PS; register caddr_t params; /* known to be r10 below */ register int i; /* known to be r9 below */ register struct sysent *callp; @@ -219,7 +266,7 @@ unsigned code; u.u_error = 0; /*------ DIRTY CODE !!!!!!!!!---------*/ /* try to reconstruct pc, assuming code is an immediate constant */ - opc = pc - 2; /* short literal */ + opc = pC - 2; /* short literal */ if (code > 0x3f) { opc--; /* byte immediate */ if (code > 0x7f) { @@ -233,10 +280,16 @@ unsigned code; if (callp == sysent) { i = fuword(params); params += NBPW; - callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; + callp = ((unsigned)i >= nsysent) ? &sysent[63] : &sysent[i]; } if (i = callp->sy_narg * sizeof (int)) { - asm("prober $1,(r10),r9"); /* GROT */ + register int xxx; /* r6 */ + + asm("prober $1,(r10),$1"); /* GROT */ + asm("bnequ ok"); /* GROT */ + asm("addl3 r9,r10,r6"); /* get last byte */ + asm("decl r6"); + asm("prober $1,(r6),$1"); /* GROT */ asm("bnequ ok"); /* GROT */ u.u_error = EFAULT; /* GROT */ goto bad; /* GROT */ @@ -275,7 +328,7 @@ asm("ok:"); /* GROT */ (*(callp->sy_call))(); } if (u.u_eosys == RESTARTSYS) - pc = opc; + pC = opc; else if (u.u_error) { bad: locr0[R0] = u.u_error; @@ -336,7 +389,7 @@ nullsys() } -fpemulate(hfsreg,acc_most,acc_least,dbl,op_most,op_least,opcode,pc,psl) +fpemulate(hfsreg,acc_most,acc_least,dbl,op_most,op_least,opcode,pC,psL) { /* * Emulate the F.P. 'opcode'. Update psl flags as necessary. @@ -359,7 +412,7 @@ fpemulate(hfsreg,acc_most,acc_least,dbl, register dumm3; /* register 12 is the 1'st register variable */ /* in TAHOE (register 11 in VAX) */ - register int *locr0 = ((int *)&psl)-PS; /* R11 */ + register int *locr0 = ((int *)&psL)-PS; /* R11 */ int hfs = 0; /* returned data about exceptions */ float (*f_proc)(); /* fp procedure to be called. */ double (*d_proc)(); /* fp procedure to be called. */