1// 2// debug_hndlr.S -- default Xtensa debug exception handler 3// 4// $Id: //depot/rel/Foxhill/dot.8/Xtensa/OS/hal/debug_hndlr.S#1 $ 5 6// Copyright (c) 2003-2010 Tensilica Inc. 7// 8// Permission is hereby granted, free of charge, to any person obtaining 9// a copy of this software and associated documentation files (the 10// "Software"), to deal in the Software without restriction, including 11// without limitation the rights to use, copy, modify, merge, publish, 12// distribute, sublicense, and/or sell copies of the Software, and to 13// permit persons to whom the Software is furnished to do so, subject to 14// the following conditions: 15// 16// The above copyright notice and this permission notice shall be included 17// in all copies or substantial portions of the Software. 18// 19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27#include <xtensa/coreasm.h> 28#include <xtensa/config/system.h> 29 30#if XCHAL_HAVE_DEBUG && XCHAL_HAVE_EXCEPTIONS 31 32 /* 33 * Default debug exception handler. 34 * 35 * Note that the debug exception vector must save a3 36 * in EXCSAVE+XCHAL_DEBUGLEVEL before jumping here. 37 * 38 * This handler is used when no debugger is present. 39 * The end result of executing this default handler 40 * is as if no debug exception had occurred, eg. as if 41 * the core was running at PS.INTLEVEL >= DEBUGLEVEL. 42 * 43 * Because the debug exception vector might get 44 * placed in ROM, and be expected to work regardless 45 * of what executable image or OS is running in RAM, 46 * we're very careful not to use any RAM here. 47 * We don't know what RAM we can safely use. 48 * This tricky part to accomplishing this feat 49 * is to use only *one* register (a3, which was 50 * saved in EXCSAVE+XCHAL_DEBUGLEVEL), because we don't 51 * have RAM in which to safely store other regs. 52 * 53 * A real debugger application would normally 54 * have some kind of conventions, or special 55 * hardware support, to have its own RAM workspace 56 * in which to save context and do real work 57 * in this handler. 58 */ 59 60 61#if XSHAL_DEBUG_VECTOR_ISROM 62 // Debug exception vector is in ROM, so place the handler 63 // in ROM also. Otherwise running different executables 64 // with that ROM will not work because the handler would 65 // likely not be there or be at the wrong address. 66 // 67 .section .srom.text, "ax" 68#else 69 // Debug exception vector is in RAM, so we can safely 70 // place the handler in RAM as well. 71 // 72 .text 73#endif 74 75 .global xthal_debugexc_defhndlr_nw 76 .align 4 77xthal_debugexc_defhndlr_nw: 78 rsr.debugcause a3 // get cause of debug exception 79 80 // Check for possible debug causes, in priority order. 81 // We only handle the highest priority condition present. 82 // (If there are multiple conditions, the lower priority 83 // condition(s) will normally trigger upon return from 84 // this exception handler.) 85 86 bbci.l a3, DEBUGCAUSE_ICOUNT_SHIFT, 1f // ICOUNT trap? 87 movi a3, 0 88 wsr.icount a3 // clear ICOUNT 89 j 3f 90 91/* 92 * Ensure that we have IBREAKs, otherwise the IBREAKENABLE 93 * special register is not there: 94 */ 95#if XCHAL_NUM_IBREAK > 0 961: bbci.l a3, DEBUGCAUSE_IBREAK_SHIFT, 1f // IBREAK match? 97 movi a3, 0 98 wsr.ibreakenable a3 // disable IBREAK traps 99 j 3f 100#endif 101 102/* Also check for DBREAK registers: */ 103#if XCHAL_NUM_DBREAK > 0 1041: bbci.l a3, DEBUGCAUSE_DBREAK_SHIFT, 1f // DBREAK match? 105 movi a3, 0 106 wsr.dbreakc0 a3 // disable DBREAK register 0 107# if XCHAL_NUM_DBREAK > 1 108 wsr.dbreakc1 a3 // disable DBREAK register 1 109# endif 110 j 3f 111#endif 112 1131: bbci.l a3, DEBUGCAUSE_BREAK_SHIFT, 1f // BREAK instruction? 114 //readsr epc XCHAL_DEBUGLEVEL a3 // get PC pointing to BREAK 115 //l8ui a3, a3, 1 // get first 4-bit operand of BREAK (in 2nd byte) 116 //extui a3, a3, (XCHAL_HAVE_BE*4), 4 // pos depends on endianness 117 //bnei a3, 1, 3f // is it a BREAK 1,x instruction? 118 readsr epc XCHAL_DEBUGLEVEL a3 // get PC pointing to BREAK 119 addi a3, a3, 3 // skip BREAK instruction 120 writesr epc XCHAL_DEBUGLEVEL a3 // update PC 121 j 3f 122 1231: bbci.l a3, DEBUGCAUSE_BREAKN_SHIFT, 1f // BREAK.N instruction? 124 readsr epc XCHAL_DEBUGLEVEL a3 // get PC pointing to BREAK 125 addi a3, a3, 2 // skip BREAK.N instruction 126 writesr epc XCHAL_DEBUGLEVEL a3 // update PC 127 j 3f 128 1291: bbci.l a3, DEBUGCAUSE_DEBUGINT_SHIFT, 1f // debug interrupt? 130 // Nothing to do... 131 j 3f 132 1331: // Unknown debug case? ignore 134 1353: readsr excsave XCHAL_DEBUGLEVEL a3 // restore a3 136 rfi XCHAL_DEBUGLEVEL // return from debug exception 137 138 .size xthal_debugexc_defhndlr_nw, . - xthal_debugexc_defhndlr_nw 139 140 141#if XSHAL_DEBUG_VECTOR_ISROM 142 .text // in case this gets included by something else 143#endif 144 145#endif /* XCHAL_HAVE_DEBUG */ 146 147