This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: SVC SPSR overwritten in Arm HAL


>>>>> Pierre Habraken writes:

> The origin of this misbehavior resides in the HAL exception handler
> (vector.S): If an exception or IRQ occurs while the processor is running
> in SVC mode, then the saved psr of the SVC mode (spsr_svc) is
> overwritten by the exception handler at the time the latter prepares
> itself to return:
> =============================================================
> return_from_exception:

>         ldr     r0,[sp,#armreg_cpsr]
>         msr     spsr,r0
>         ^^^     ^^^^^^^
>         // return to supervisor mode is simple
>         and     r1,r0,#CPSR_MODE_BITS
>         cmp     r1,#CPSR_SUPERVISOR_MODE
>         ldmeqfd sp,{r0-r14,pc}^
>         ...
> =============================================================

> The reported misbehavior is fixed by applying the change below to the
> exception handler:
> =============================================================
> return_from_exception:

>         ldr     r0,[sp,#armreg_cpsr]

>         // return to supervisor mode is simple
>         and     r1,r0,#CPSR_MODE_BITS
>         cmp     r1,#CPSR_SUPERVISOR_MODE
>         bne     1f
>         msr     cpsr, r0
>         ldmfd   sp, {r0-r14, pc}
> 1:
>         msr     spsr, r0
>         ...
> =============================================================

> Depending on the type of program or application, one can consider that
> the original behavior is either a bug or a feature. So, taking in
> account the fact that the fix I propose above adds one instruction (bne)
> only to the execution flow, is it worth to create a cdl option for it ?

The bne has more of an impact (due to the pipeline) than a simple
instruction. I think the code should look like this:

         // return to supervisor mode is simple
         and     r1,r0,#CPSR_MODE_BITS
         cmp     r1,#CPSR_SUPERVISOR_MODE
         msreq   cpsr, r0
         ldmeqfd sp, {r0-r14, pc}
         msr     spsr, r0
         ...

Cancelling two insns because of condition codes is generally cheaper than
branching around them. This adds extra overhead to the return to SVC mode
case and only one insn in the other (much less likely) case.

--Mark


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]