[xtensa-cvscommit] linux/arch/xtensa/kernel handlers.S,1.14,1.15
Brought to you by:
zankel
|
From: <ma...@us...> - 2003-03-20 20:45:43
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel In directory sc8-pr-cvs1:/tmp/cvs-serv1534 Modified Files: handlers.S Log Message: Fix debug exception handler to at least reasonably handle the case where PS.EXCM was set when the debug exception occurred. For now, just try to ignore such exceptions; later, perhaps we can make kgdb handle them if it is active. Index: handlers.S =================================================================== RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/handlers.S,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** handlers.S 13 Feb 2003 18:19:20 -0000 1.14 --- handlers.S 20 Mar 2003 20:45:37 -0000 1.15 *************** *** 76,79 **** --- 76,80 ---- #include <asm/offset.h> #include <asm/pgtable.h> + #include <asm/processor.h> #define WSBITS (XCHAL_NUM_AREGS / 4) /* width of WINDOWSTART register in bits */ *************** *** 1024,1028 **** * saved in pt_regs, but we do anyway because it makes the algorithm * simpler. ! * The algoritm is to first save all panes lower than the active one, * and then save all the panes above the active one. We can only touch * a2 and a3. */ --- 1025,1029 ---- * saved in pt_regs, but we do anyway because it makes the algorithm * simpler. ! * The algorithm is to first save all panes lower than the active one, * and then save all the panes above the active one. We can only touch * a2 and a3. */ *************** *** 2819,2831 **** ! /* Debug Exception Handler * ! * On entry, a0 is preserved in EXCSAVE[DEBUGLEVEL]. * * This handler will set things up to look like either a kernel or user ! * exception occurred, depending if the debug trap happened in kernel or user ! * code, respectively, and then jump to the common exception handling code. ! * Thus, rfi is never called for debug interrupts. Instead, an the rfe in ! * the common exception path is called. * */ --- 2820,2842 ---- ! /* ! * Debug Exception Handler ! * ! * This handler assumes the following vector implementation: ! * ! * xsr a0, EXCSAVE + XCHAL_DEBUGLEVEL ! * jx a0 * ! * Thus on entry here, a0 has been saved in EXCSAVE_[DEBUGLEVEL]. * * This handler will set things up to look like either a kernel or user ! * exception occurred, depending on whether the debug exception happened ! * in kernel or user code, respectively, and then jump to the common ! * exception handling code. ! * Thus, rfi is usually never called for debug exceptions. Instead, ! * an rfe in the common exception path is called. ! * However, if PS.EXCM was set when the debug exception occurred, ! * it is handled differently; the exception is simply "ignored" ! * as much as possible (XTFIXME: pass such occurrences to kgdb if active). * */ *************** *** 2834,2842 **** handle_debug: - wsr a2, DEPC // preserve a2 so we can use it rsr a0, PS // Check if in user or kernel mode ! extui a0, a0, PS_UM_SHIFT, 1 ! bnez a0, 1f // jump if in user mode ! addi a0, a1, -(16+PT_SIZE) // use system stack s32i a1, a0, PT_AREG1 // save previous sp --- 2845,2854 ---- handle_debug: rsr a0, PS // Check if in user or kernel mode ! wsr a2, DEPC // preserve a2 so we can use it ! bbsi.l a0, PS_EXCM_SHIFT, 3f // jump if in exception mode ! bbsi.l a0, PS_UM_SHIFT, 1f // jump if in user mode ! ! // Kernel mode: addi a0, a1, -(16+PT_SIZE) // use system stack s32i a1, a0, PT_AREG1 // save previous sp *************** *** 2844,2873 **** movi a2, EXCTYPE_KERNEL // mark as a kernel exception j 2f - 1: - /* Switch to system stack. Variable kernelsp is a pointer to - * the system stack already decremented by 16+PT_SIZE. */ ! movi a0, kernelsp l32i a0, a0, 0 // load system stack value from variable s32i a1, a0, PT_AREG1 // save task's sp mov a1, a0 // set sp to system stack ! movi a2, EXCTYPE_USER // mark as a kernel exception ! 2: ! movi a0, 0 // Initialize ICOUNT and ICOUNTLEVEL wsr a0, ICOUNTLEVEL // so we don't get any ICOUNT wsr a0, ICOUNT // exceptions in the kernel. isync ! movi a0, 31 // set up "dummy" debug exception cause wsr a0, EXCCAUSE rsr a0, EPC + XCHAL_DEBUGLEVEL // Put PC into EPC1 for the wsr a0, EPC_1 // generic exception code. - rsr a0, EPS + XCHAL_DEBUGLEVEL // Put PS wth EXCM on into PS #if 1 ! s32i a0, a1, PT_RESERVED0 #endif - addi a0, a0, XCHAL_PS_EXCM_MASK // for the generic exception wsr a0, PS // code. --- 2856,2890 ---- movi a2, EXCTYPE_KERNEL // mark as a kernel exception j 2f ! // User mode: ! // Switch to system stack. Variable kernelsp is a pointer to ! // the system stack already decremented by 16+PT_SIZE. ! 1: movi a0, kernelsp ! //slot l32i a0, a0, 0 // load system stack value from variable + movi a2, EXCTYPE_USER // mark as a kernel exception s32i a1, a0, PT_AREG1 // save task's sp mov a1, a0 // set sp to system stack ! ! 2: movi a0, 0 // Initialize ICOUNT and ICOUNTLEVEL wsr a0, ICOUNTLEVEL // so we don't get any ICOUNT wsr a0, ICOUNT // exceptions in the kernel. isync ! movi a0, FAKE_EXCCAUSE_DEBUG // set up "dummy" debug exception cause wsr a0, EXCCAUSE + #if 1 + rsr a0, DEBUGCAUSE // save DEBUGCAUSE while it is live + s32i a0, a1, PT_RESERVED1 + #endif + rsr a0, EPC + XCHAL_DEBUGLEVEL // Put PC into EPC1 for the wsr a0, EPC_1 // generic exception code. + rsr a0, EPS + XCHAL_DEBUGLEVEL // Put PS wth EXCM on into PS #if 1 ! s32i a0, a1, PT_RESERVED0 // save EPS while it is live #endif addi a0, a0, XCHAL_PS_EXCM_MASK // for the generic exception wsr a0, PS // code. *************** *** 2882,2885 **** --- 2899,2984 ---- j _excCommonException // jump to common exception code + + // Exception mode: + // + // Here, a debug exception wasn't expected. + // (Simulating a general exception would mean simulating + // a double exception, and isn't what we want.) + // Possible reasons for getting here include unhandled + // exceptions (that cause execution of a BREAK instruction), + // and kernel bugs in critical exception assembly code. + // + // Assume there is no debugger present + // (XTFIXME: pass this exception to kgdb) + // and minimally handle the exception. + // In other words, skip over BREAK instructions, + // let ICOUNT continue counting, etc). + // The end result of executing this default handler + // is almost as if no debug exception had occurred, + // eg. as if PS.INTLEVEL >= DEBUGLEVEL (with some + // exceptions, such as disabling of IBREAK and + // DBREAK when encountered). + // + // If multiple debug causes are present, only handle one. + // (Any remaining ones will normally trigger after RFI.) + // + 3: + rsr a0, DEBUGCAUSE // get cause of debug exception + + bbci.l a0, DEBUGCAUSE_ICOUNT_SHIFT, 1f // ICOUNT trap? + movi a0, 0 + wsr a0, ICOUNT // clear ICOUNT + j 3f + + /* + * Ensure that we have IBREAKs, otherwise the IBREAKENABLE + * special register is not there: + */ + #if XCHAL_NUM_IBREAK > 0 + 1: bbci.l a0, DEBUGCAUSE_IBREAK_SHIFT, 1f // IBREAK match? + movi a0, 0 + wsr a0, IBREAKENABLE // disable IBREAK traps + j 3f + #endif + + /* Also check for DBREAK registers: */ + #if XCHAL_NUM_DBREAK > 0 + 1: bbci.l a0, DEBUGCAUSE_DBREAK_SHIFT, 1f // DBREAK match? + movi a0, 0 + wsr a0, DBREAKC_0 // disable DBREAK register 0 + # if XCHAL_NUM_DBREAK > 1 + wsr a0, DBREAKC_1 // disable DBREAK register 1 + # endif + j 3f + #endif + + 1: bbci.l a0, DEBUGCAUSE_BREAK_SHIFT, 1f // BREAK instruction? + //rsr a0, EPC+XCHAL_DEBUGLEVEL // get PC pointing to BREAK + //l8ui a0, a0, 1 // get first 4-bit operand of BREAK (in 2nd byte) + //extui a0, a0, (XCHAL_HAVE_BE*4), 4 // pos depends on endianness + //bnei a0, 1, 3f // is it a BREAK 1,x instruction? + rsr a0, EPC+XCHAL_DEBUGLEVEL // get PC pointing to BREAK + addi a0, a0, 3 // skip BREAK instruction + wsr a0, EPC+XCHAL_DEBUGLEVEL // update PC + j 3f + + 1: bbci.l a0, DEBUGCAUSE_BREAKN_SHIFT, 1f // BREAK.N instruction? + rsr a0, EPC+XCHAL_DEBUGLEVEL // get PC pointing to BREAK.N + addi a0, a0, 2 // skip BREAK.N instruction + wsr a0, EPC+XCHAL_DEBUGLEVEL // update PC + j 3f + + 1: bbci.l a0, DEBUGCAUSE_DEBUGINT_SHIFT, 1f // debug interrupt? + // Nothing to do... + j 3f + + 1: // Unknown debug case? ignore + + 3: movi a0, handle_debug // re-setup handler address + xsr a0, EXCSAVE+XCHAL_DEBUGLEVEL // restore a0 + rfi XCHAL_DEBUGLEVEL // return from debug exception + + + |