Thanks, Dave. This answers my question. I wasn't aware of the APCS,
but I deeply suspected there was one.
Best regards,
Guille
--- In lpc2000@yahoogroups.com, "David Hawkins" <dwh@o...> wrote:
>
>
>
> > Hi, all!
> >
> > First of all I want to thank everybody in this group. The amount
and
> > quality of help I'm receiving from you guys is extraordinary. I
> > sincerely hope I can contribute helping others in due time.
> >
> > I am doing some IRQ compilation tests with GCC and the
__attribute__
> > ((interrupt("IRQ")) syntax. Apparently the code doesn't seem to
> > save/restore all the registers I expected. In particular, it
doesn't
> > seem to save spsr. Also, only general registers r1-r4 are saved
> > before calling an external function. I have the following
questions:
> >
> > * Saving spsr is only needed for reentrant IRQs?
> > * Perhaps saving only r1-r4 is a convention, and functions should
> > always save by themselves any other general registers they may
use?
> > * Should I worry or this is perfectly normal and *safe*?
> >
> > Thanks in advance.
> >
>
> Hi Guille,
>
> Let me help explain with the following (but incomplete) startup
code:
>
> .global main
> .global _start
>
> /* Symbols defined by the linker script */
> .global _etext
> .global _data
> .global _edata
> .global _bss
> .global _ebss
>
> /* External functions */
> .global fiq_handler
> .global irq_handler
>
> .text
> .arm
>
> /* ----------------------------------------------------------------
> * Exception vectors
> * ----------------------------------------------------------------
> */
> _start:
> b reset /* reset */
> b loop /* undefined instruction */
> b loop /* software interrupt */
> b loop /* prefetch abort */
> b loop /* data abort */
> nop /* reserved for the bootloader checksum */
> ldr pc, irq_addr
>
> /* FIQ ISR */
> fiq_isr:
> sub lr, lr, #4
> stmfd sp!, {r0-r3, ip, lr}
> bl fiq_handler
> ldmfd sp!, {r0-r3, ip, pc}^
>
> irq_addr: .word irq_isr
> irq_isr:
> sub lr, lr, #4
> stmfd sp!, {r0-r3, ip, lr}
> bl irq_handler
> ldmfd sp!, {r0-r3, ip, pc}^
>
>
> Ok, above I define two external interrupt handlers written as
> C-functions *** without the __interrupt__ attribute ***
>
> The FIQ handler lives at the FIQ vector address, while the IRQ
> handler is loaded into the PC, jumping it to irq_isr, which\
> in turn saves context and jumps to the irq_handler function.
>
> The ONLY registers you need to save there are the APCS
> (ARM Procedure Calling Standard) 'scratch' registers.
> Those registers are; r0-r3, and ip. The lr you save cause
> you're calling a function.
>
> All that the GNU compiler does is exactly that, and then
> it optimizes, i.e., if it doesn't use r0-r3, it'll remove
> them from the generated code.
>
> The SPSR register only needs saving when nesting IRQ interrupts.
> If an FIQ interrupt occurs while processing an IRQ interrupt,
> its ok, as the FIQ mode has its own SPSR.
>
> Cheers
> Dave
>Message
Re: Save/restore IRQ registers in GNU C
2005-10-25 by Guillermo Prandi
Attachments
- No local attachments were found for this message.