Mercurial > ecos
diff packages/hal/arm/arch/current/src/vectors.S @ 1002:609c8b1447ee
HAL enhancements from Pierre Habraken
| author | msalter |
|---|---|
| date | Tue, 06 May 2003 21:00:18 +0000 |
| parents | 282a39769954 |
| children | 04b94baa3683 |
line wrap: on
line diff
--- a/packages/hal/arm/arch/current/src/vectors.S +++ b/packages/hal/arm/arch/current/src/vectors.S @@ -8,7 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free @@ -490,6 +490,8 @@ init_done: // // Exception handlers // Assumption: get here from a non-user context [mode] +// except in case of standalone app. running in user mode +// (CYGOPT_HAL_ARM_WITH_USER_MODE should have been defined) // .code 32 undefined_instruction: @@ -582,6 +584,17 @@ 10: stmfd sp!,{r0-r2,r4,r5} // push svc_sp, svc_lr, vector, psr, pc +#ifdef CYGOPT_HAL_ARM_WITH_USER_MODE + // did exception occur in user mode ? + and r2, r1, #CPSR_MODE_BITS + cmp r2, #CPSR_USER_MODE + bne 1f + stmfd sp, {r8-r12, sp, lr}^ // get user mode regs + nop + sub sp, sp, #4*7 + bal 2f +1: +#endif // switch to pre-exception mode to get banked regs mov r0,sp // r0 survives mode switch mrs r2,cpsr // Save current psr for return @@ -591,7 +604,7 @@ 10: stmfd r0!,{r8-r12,sp,lr} msr cpsr,r2 // back to svc mode mov sp,r0 // update stack pointer - +2: // now save pre-exception r0-r7 on current stack ldmfd r3,{r0-r5} stmfd sp!,{r0-r7} @@ -636,14 +649,42 @@ return_from_exception: // return to supervisor mode is simple and r1,r0,#CPSR_MODE_BITS cmp r1,#CPSR_SUPERVISOR_MODE + +#ifndef CYGOPT_HAL_ARM_PRESERVE_SVC_SPSR + msr spsr,r0 ldmeqfd sp,{r0-r14,pc}^ +#else + // we must take care of not corrupting the current (svc) + // spsr which happens to be also the pre-exception spsr + bne 1f + // we are returning to svc mode thus we must restore the + // pre-exception cpsr before returning to interrupted code + msr cpsr, r0 + ldmfd sp, {r0-r14, pc} +1: + // we are not returning to svc mode thus we can safely restore + // svc spsr + msr spsr, r0 +#endif +#ifdef CYGOPT_HAL_ARM_WITH_USER_MODE + // are we returning to user mode ? + and r2, r1, #CPSR_MODE_BITS + cmp r2, #CPSR_USER_MODE + add r2, sp, #armreg_r8 + bne 1f + ldmfd r2, {r8-r14}^ // restore user mode regs + nop + bal 2f +1: +#else + add r2, sp, #armreg_r8 +#endif // // return to other non-user modes is a little trickier // // switch to pre-exception mode and restore r8-r14 - add r2,sp,#armreg_r8 mrs r1,cpsr orr r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE bic r0,r0,#CPSR_THUMB_ENABLE @@ -651,6 +692,7 @@ return_from_exception: ldmfd r2,{r8-r14} msr cpsr, r1 // back to svc mode +2: // move sp,lr and pc for final load ldr r0,[sp,#armreg_svcsp] str r0,[sp,#armreg_r8] @@ -676,6 +718,8 @@ return_from_exception: // Handle device interrupts // This is slightly more complicated than the other exception handlers because // it needs to interface with the kernel (if present). +// Assumption: can get here from any mode, including user mode +// (spurious interrupt while standalone app. is running in user mode) .code 32 FIQ: @@ -723,6 +767,17 @@ handle_IRQ_or_FIQ: mov r4,lr // save original svc lr stmfd sp!,{r0-r2,r4,r5} // push svc_sp, svc_lr, vector, psr, pc +#ifdef CYGOPT_HAL_ARM_WITH_USER_MODE + // did exception occur in user mode ? + and r2, r1, #CPSR_MODE_BITS + cmp r2, #CPSR_USER_MODE + bne 1f + stmfd sp, {r8-r12, sp, lr}^ // get user mode regs + nop + sub sp, sp, #4*7 + bal 2f +1: +#endif // switch to pre-exception mode to get banked regs mov r0,sp // r0 survives mode switch mrs r2,cpsr // Save current psr for return @@ -733,6 +788,7 @@ handle_IRQ_or_FIQ: msr cpsr,r2 // back to svc mode mov sp,r0 // update stack pointer +2: // now save pre-exception r0-r7 on current stack ldmfd r3,{r0-r5} stmfd sp!,{r0-r7}
