This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

omapl138 ARM exception exit

Other Parts Discussed in Thread: OMAPL138

Hi

I am testing the exception handling in omapl138 ARM.  here is the interrupt vector table:

.sect ".intvecs"
_intvecs:                                  ;Exception                                 Address
LDR PC,init                            ;Reset                                        0xffff0000
.word 0                                    ;undefined instruction             0xffff0004
MOV PC,R14                          ;soft ware interrupt                  0xffff0008
.word 0                                    ;pre-fetch abort                         0xffff000c
.word 0                                    ;data abort                                 0xffff0010
.word 0                                     ;reserved                                  0xffff0014
LDR PC,irq_handler             ;irq                                             0xffff0018
LDR PC,fiq_handler             ;fiq                                              0xffff001c

And in my main function, which is in USR mode,  I generated a software interrupt using swi #12. Theoretically, ARM will go to this intvec and go back to main function without change any registers' value.

When I debug it step by step, I found that after swi #12, ARM goes to this intvec. At this moment, R13 is updated by R13_SVC, R14 stores the return address in main function, CPSR goes to SVC mode. All these are reasonable. SPSR_SVC is supposed to save the value of CPSR right before swi #12 instruction but its higher bits remained unchanged while only mode field is updated.

What's more, after execution of MOV PC,R14, ARM does go back to the main function as expected. However, CPSR was recovered by SPSR_SVC. i.e. CPSR is still in SVC mode without being changed back to USR mode. 

So I was wondering whether CPSR is updated by core automatically when exit from exception? or We have to recover CPSR explicitly in our interrupt handler? I we do have to recover CPSR explicitly in our interrupt handler, how can we do it? because in our interrupt handler, it usually looks like this:

STMFD SP!,{R0-R12,R14}

...

LDMFD SP!,{R0-R12,R14}

MOV PC,R14

To recover CPSR explicitly, we have move value from SPSR to CPSR. Since there is no instruction that can move data between these two registers, we have to use a general purpose register as a temporary register (for example R0). We can not use R0 after instruction LDMFD SP!,{R0-R12,R14} because R0 maybe used in the functions that was interrupted. And we can't use R0 to recover CPSR before LDMFD SP!{R0-R14} neither, because if CPSR was updated and mode was changed, R13 would be changed to USR stack, thus making LDMFD SP!,{R0-R14} can't recover R0-R12,R14 from SVC stack.

Does anybody know how to deal with this case?

Thanks,

Fu