|
|
1.1 ! root 1: /* Copyright 1989 by AT&T Bell Laboratories */ ! 2: /* SPARC.dep.c ! 3: * ! 4: * J.H. Reppy ! 5: * Cornell University ! 6: * Ithaca, NY 14853 ! 7: * [email protected] ! 8: * ! 9: * HISTORY: ! 10: * 11/20/89 created (extracted from callgc.c and run.c) ! 11: * ! 12: * SPARC dependent code for SML/NJ runtime kernel. ! 13: */ ! 14: ! 15: #include <signal.h> ! 16: #include <floatingpoint.h> ! 17: #include "tags.h" ! 18: ! 19: /* When handling signals we need to know the context of the signal. We view ! 20: * execution as being at one of two levels, and use the flag inML to distinguish ! 21: * the levels: ! 22: * 0 -- in C code above ML ! 23: * 1 -- in ML code or in C/asm code called from ML. ! 24: * This is adjusted by the assembler code that implements the C/ML interface. ! 25: */ ! 26: int inML = 0; /* == 1 when execution is in ML code */ ! 27: int fault_pending = 0; /* == 1 when a fault is pending in level 0 */ ! 28: ! 29: ! 30: extern int cause, fault_code; ! 31: extern int saved_pc; ! 32: extern int saveregs[]; ! 33: ! 34: ! 35: /* ghandle: ! 36: * Handler for GC signals. This is based on what level execution is in. ! 37: * If a fault occurs in level 0 we note it and invoke the exn handler the next ! 38: * time ML code is run. If a fault occurs in level 1 we need to determine if ! 39: * it is in ML code or in C/asm code called from ML. If it is in ML code then ! 40: * we transfer control directly to the exn handler. If it is in C/asm code, ! 41: * then we call ml_longjmp() (in SPARC.prim.s) to restore the ML register window. ! 42: */ ! 43: ghandle(sig, code, scp, addr) ! 44: int sig, code, addr; ! 45: struct sigcontext *scp; ! 46: { ! 47: extern datalist, startprim, endprim, endmo, etext, ml_longjmp; ! 48: ! 49: saved_pc = scp->sc_pc; ! 50: ! 51: if ((sig == SIGEMT) && (code == EMT_TAG)) { ! 52: /* GC related fault. There are three possible code sequences that may ! 53: * trigger GC (where n is an integer and %r is a temp register). ! 54: * ! 55: * taddcctv %g6,%g4,%g0 1000 0001 0001 0001 1000 0000 0000 0100 ! 56: * ! 57: * add %g4,n,%r 10rr rrr0 0000 0001 001n nnnn nnnn nnnn ! 58: * taddcctv %g6,%r,%g0 1000 0001 0001 0001 1000 0000 000r rrrr ! 59: * ! 60: * sethi %hi(n),%r 00rr rrr1 00nn nnnn nnnn nnnn nnnn nnnn ! 61: * or %r,%lo(n),%r 10rr rrr0 0001 0rrr rr1n nnnn nnnn nnnn ! 62: * add %g4,%r,%r 10rr rrr0 0000 0001 0000 0000 000r rrrr ! 63: * taddcctv %g6,%r,%g0 1000 0001 0001 0001 1000 0000 000r rrrr ! 64: */ ! 65: register unsigned int *pc = (unsigned int *)saved_pc; ! 66: register int pc_adjust; ! 67: ! 68: if (pc[0] == 0x81118004 /* taddcctv %g6,%r,%g0 */) ! 69: pc_adjust = 0; ! 70: else if ((pc[0] & 0xffffffe0) == 0x81118000 /* taddcctv %g6,%r,%g0 */) ! 71: pc_adjust = (pc[-1] & 0x00002000 /* immed flag */) ? 4 : 12; ! 72: else ! 73: die ("SIGEMT not related to gc\n"); ! 74: if (((int)pc)+4 != scp->sc_npc) ! 75: die ("SIGEMT not related to garbage collection (bogus npc)\n"); ! 76: saved_pc = ((int)pc) - pc_adjust; ! 77: scp->sc_pc = (int)saveregs; ! 78: scp->sc_npc = ((int)saveregs)+4; ! 79: cause = CAUSE_GC; ! 80: } ! 81: else if (! inML) { ! 82: /* execution above ML */ ! 83: if (sig != SIGINT) ! 84: die ("Unknown signal %d (%#x)\n", sig, code); ! 85: fault_pending = 1; ! 86: fault_code = exnCode(sig, code); ! 87: } ! 88: else { ! 89: fault_code = exnCode(sig, code); ! 90: cause = CAUSE_FAULT; ! 91: ! 92: /* Check to see if we are in ML code or in C/asm called from ML */ ! 93: if (((int)&etext <= saved_pc) ! 94: || (((int)&startprim <= saved_pc) && (saved_pc < (int)&endprim)) ! 95: || (((int)&datalist != ML_NIL) && ((int)&datalist <= saved_pc) ! 96: && (saved_pc <= (int)&endmo))) ! 97: { ! 98: /* Execution is in ML code */ ! 99: scp->sc_pc = (int)saveregs; ! 100: scp->sc_npc = ((int)saveregs)+4; ! 101: } ! 102: else { ! 103: /* Execution is in C/asm code called from ML. */ ! 104: if (sig != SIGINT) ! 105: die ("Unknown signal %d (%#x)\n", sig, code); ! 106: scp->sc_pc = (int)&ml_longjmp; ! 107: scp->sc_npc = ((int)&ml_longjmp)+4; ! 108: } ! 109: } ! 110: } ! 111: ! 112: extern int handleprof(); ! 113: extern void set_fsr(); ! 114: ! 115: /* setupsignals: ! 116: * Install the signal handlers. ! 117: */ ! 118: setupsignals() ! 119: { ! 120: struct sigvec a; ! 121: ! 122: a.sv_handler = (void (*)()) ghandle; ! 123: a.sv_mask = sigmask(SIGINT); ! 124: a.sv_onstack = 0; ! 125: sigvec(SIGEMT,&a,0); ! 126: a.sv_mask = 0; ! 127: sigvec(SIGINT,&a,0); ! 128: set_fsr (0x0f000000); /* enable FP exceptions NV, OF, UF & DZ */ ! 129: sigvec(SIGFPE,&a,0); ! 130: a.sv_handler = SIG_IGN; ! 131: sigvec(SIGPIPE,&a,0); ! 132: a.sv_handler = (void (*)()) handleprof; ! 133: sigvec(SIGVTALRM,&a,0); ! 134: } ! 135: ! 136: /**** TEMP ****/ ! 137: char *malloc(){die("malloc"); return 0;} ! 138: char *realloc(){die("realloc"); return 0;} ! 139: char *calloc(){die("calloc"); return 0;} ! 140: int free(){die("free");} ! 141: int cfree(){die("cfree");}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.