Annotation of 43BSDReno/sys/tahoealign/exception.c, revision 1.1

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: }

unix.superglobalmegacorp.com

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