00001 /* 00002 * Copyright (C) 2008 by Duane Ellis 00003 * 00004 * All rights reserved. 00005 * 00006 * The original code had been released as part of the LoastARM Project 00007 * under GPL Version 2 and is published here under the following license 00008 * with kind permission from the author: 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright 00017 * notice, this list of conditions and the following disclaimer in the 00018 * documentation and/or other materials provided with the distribution. 00019 * 3. Neither the name of the copyright holders nor the names of 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00030 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00031 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00033 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00034 * SUCH DAMAGE. 00035 * 00036 * For additional information see http://lostarm.sourceforge.net/ 00037 */ 00038 00047 /* -*- mode: asm -*- */ 00048 #if __ASSEMBLER__ 00049 00050 .macro ARM7TDMI_IRQ_BUG 00052 /* See: ATMEL doc DOC1156 */ 00053 /* fix/adjust lr */ 00054 sub lr,lr,#4 00055 stmfd sp!,{lr} 00056 mrs lr,spsr 00057 00058 /* BUG IS - due to pipeline the IRQ bit may be */ 00059 /* set right (disableing irqs) but it gets lost */ 00060 /* inside the pipeline, software must fix this */ 00061 ands lr,lr,#ARM_CPSR_I_BIT 00062 ldmnefd sp!,{pc}^ 00063 ldmfd sp!,{lr} 00064 /* undo the add above cause below we will do 00065 * the sub again below it would be nicer to 00066 * 'clean this up' 00067 */ 00068 add lr,lr,#4 00069 .endm 00070 00071 00072 .macro exception_enter, whatmode, frametype 00073 00074 .if ((\whatmode) != ARM_SVC_MODE) 00075 sub lr,lr,#4 00076 .endif 00077 /* switch to system mode */ 00078 msr cpsr_c,#(ARM_SYS_MODE | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00079 /* we are now in system mode */ 00080 00081 /* one fallacy - we always assume 00082 * sysmode SP is not messed up 00083 */ 00084 00085 /* make room for PTRACE frame */ 00086 sub sp,sp,#(PTRACE_FRAME_size*4) 00087 00088 /* save the world */ 00089 stmia sp,{r0-r14} 00090 00091 /* save the return value here */ 00092 str r0,[sp,#(PTRACE_R0_retval_idx*4)] 00093 00094 /* Need to go back to old mode and pickup things 00095 * When we get there, we will need the sys stack 00096 */ 00097 mov r0,sp 00098 00099 /* step over to the dark side */ 00100 msr cpsr_c,#((\whatmode) | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00101 /* back in offending mode */ 00102 00103 /* save the exception address */ 00104 str lr,[r0,#(4*PTRACE_R15_idx)] 00105 00106 /* And the saved PSR */ 00107 mrs r1,spsr 00108 str r1,[r0,#(4*PTRACE_CPSR_idx)] 00109 /* and back to supervisor mode */ 00110 msr cpsr_c,#(ARM_SYS_MODE | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00111 /* done, w/ IRQ & FIQ disabled */ 00112 /* APP can decide to re-enable if *IT* wants to */ 00113 .if ((\frametype) != 0) 00114 mov r1,#(\frametype) 00115 str r1,[r0,#(4*PTRACE_FRAMETYPE_idx)] 00116 .endif 00117 .endm 00118 00119 .macro exception_exit, whatmode 00120 /* 00121 * SP = the saved state 00122 * we always restore via SYSMODE 00123 */ 00124 00125 /* pre-position some values */ 00126 ldr r0,[sp,#(PTRACE_R15_idx*4)] 00127 ldr r1,[sp,#(PTRACE_CPSR_idx*4)] 00128 00129 /* go to the offending mode */ 00130 msr cpsr_c,#((\whatmode) | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00131 00132 mov lr,r0 00133 msr spsr,r1 00134 00135 /* back to the main mode */ 00136 msr cpsr_c,#(ARM_SYS_MODE | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00137 /* restore the world */ 00138 ldmia sp,{r0-r14} 00139 .if ((\whatmode) == ARM_SVC_MODE) 00140 ldr r0,[sp,#(PTRACE_R0_retval_idx*4)] 00141 .endif 00142 add sp,sp,#(PTRACE_FRAME_size*4) 00143 00144 /* back to the offending mode */ 00145 msr cpsr_c,#((\whatmode) | ARM_CPSR_F_BIT | ARM_CPSR_I_BIT) 00146 /* and effect the return */ 00147 movs pc,lr 00148 00149 .endm 00150 00151 #endif