|
|
1.1 ! root 1: /* exception.c 1.1 86/07/20 */ ! 2: ! 3: #include "../tahoealign/align.h" ! 4: ! 5: /* ! 6: * Signal an exception. It will be handled by 'locore.s'. Here, I: ! 7: * 1) Put the exception code where it belongs on the stack. ! 8: * 2) Restore pc and sp to show that the current opcode ! 9: * 'was not executed'. ! 10: * 3) Execute one big non-local-goto. In the process we take care ! 11: * to reset the current HW fp such that 'alignment' will ! 12: * indeed return to 'locore.s'. ! 13: * IMPORTANT NOTE : the process I use will NOT restore ! 14: * all registers (like normal returns) so the call to the ! 15: * handling routine HAS TO BE the last thing in 'alignment'. ! 16: * Otherwise, all its own register variables will be a mess !! ! 17: * I also know that 'alignment' itself WILL restore all ! 18: * registers for 'locore.s' since its entry mask is all-1. ! 19: */ ! 20: exception(infop, type, param1, param2) ! 21: process_info *infop; ! 22: int type, param1, param2; ! 23: { ! 24: register long *my_fp; ! 25: register long *current_fp, *prev_fp; ! 26: ! 27: my_fp = (long *)&infop-1 ; ! 28: infop->ret_exception = type; ! 29: switch (type) { ! 30: case ARITHMETIC: ! 31: infop->ret_code = param1; ! 32: break; ! 33: case ILL_ACCESS: ! 34: infop->ret_addr = param1; ! 35: infop->ret_code = param2; ! 36: break; ! 37: case ALIGNMENT: ! 38: case ILL_ADDRMOD: ! 39: case ILL_OPRND: ! 40: break; ! 41: default : ! 42: printf ("Bad exception type %d (alignment code)\n", type); ! 43: break; ! 44: } ! 45: /* ! 46: * Now the big trick. Look up the stack until the frame of ! 47: * 'alignment' is found. prev_fp will point to it and current_fp ! 48: * will then point to the frame of whoever 'alignment' called. ! 49: * This should better work ... ! 50: */ ! 51: prev_fp = my_fp; ! 52: while (prev_fp != &fp) { ! 53: current_fp = prev_fp; ! 54: prev_fp = (long *) *prev_fp; ! 55: } ! 56: /* ! 57: * Found it. Now fool the HW into thinking that 'alignment' called ! 58: * us directly here, so this routine's 'return' will go back ! 59: * all the way to 'alignment', stopping any further emulation ! 60: * for the current offending opcode. ! 61: * "fool the HW..." ha ha, am I realy fooling myself ? ! 62: */ ! 63: *my_fp = *current_fp; ! 64: *(my_fp - 2) = *(current_fp -2); /* Alter program counter */ ! 65: /* ! 66: * Without further ado, just go back now !!!! ! 67: */ ! 68: } ! 69: ! 70: not_needed (infop) ! 71: process_info *infop; ! 72: { ! 73: /* ! 74: * Shouldn't ever come to this routine. ! 75: */ ! 76: ! 77: printf ("Opcode 0x%x should not trap to alignment code.", ! 78: opCODE); ! 79: printf (" OS or machine problem!! \n"); ! 80: } ! 81: ! 82: ! 83: cannot_do (infop) ! 84: process_info *infop; ! 85: { ! 86: /* ! 87: * Some opcode-caused alignments cannot be emulated. See table.c for ! 88: * specific reasons. Reflect this back to the process as alignment ! 89: * exception. ! 90: */ ! 91: exception (infop, ALIGNMENT); ! 92: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.