This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Kai, The current release of 3.0.2 and snapshot I used was recognizing the interrupt keyword and generating ISR code. I "assumed" it was correct. I'm using the atmel AT91FR40807 processor and with the debugger I was getting interrupts and returning correctly. I didn't anaylsis the interrupt handler as closely as I should have and missed the r12 register usage. I don't understand how you concluded that the GCC ISR works for the atmel AT91. It seems to me that r12 is overwritten. Richard Slaughter ----- Original Message ----- From: "Kai Ruottu" <kai.ruottu@luukku.com> To: "Richard Slaughter" <rslaughter@anatel.com> Cc: <crossgcc@sourceware.cygnus.com>; <ananda.motte@philips.com> Sent: Monday, November 12, 2001 4:33 AM Subject: ISR-support in ARM > Hi, > here were some discussion about this subject earlier, but some issues were > left unclear, at least to me.... > > Richard Slaughter wrote: > > > > Hi Amanda, > > I'm trying to do the same thing with the interrupt key words. Only I'm > > using the ARM7TDMI core. > > If I'm understanding things correctly version 3.0.X has provisions for this > > keyword for the ARM. > > I could not get any earlier version of the GCC to recognize the keyword but > > was able to get the 3.0.2 snapshot to work. I'm trying to use it with C++ > > and the compiler is recognizing the keyword and adding code for the interrupt. > > The code added is only using the default stack and not the dedicated interrupt > > stack. > > example: foo() __attribute__((interrupt("IRQ"))) > > Hmmmm... > > A quick check with the gcc-3.0.2-implementation gave an impression about at > least one 'bug' being there : > > -------------------------- clip ------------------------------------------- > @ Generated by gcc 3.0.2 for ARM/elf > .file "isr_demo.c" > .text > .align 2 > .global handle_intr > .type handle_intr,function > handle_intr: > @ Interrupt Service Routine. > @ args = 0, pretend = 0, frame = 0 > @ frame_needed = 0, current_function_anonymous_args = 0 > @ link register save eliminated. <--- 'lr' not used as 'scratch' ? > stmfd sp!, {r0, r1, r2, r3} > ldr r1, .L3 > ldr r3, [r1, #0] > add r3, r3, #1 > str r3, [r1, #0] > ldr r0, .L3+4 > cmp r3, #400 > ldreqb r3, [r0, #0] > moveq r2, #0 > eoreq r3, r3, #1 > streq r2, [r1, #0] > ldr ip, .L3+8 <------ Oops, the r12 ('ip') is allocated !!!! > streqb r3, [r0, #0] > ldrb r3, [ip, #0] > and r3, r3, #254 > strb r3, [ip, #0] > ldmfd sp!, {r0, r1, r2, r3} > subs pc, lr, #4 > .L4: > .align 2 > .L3: > .word count > .word 16777174 > .word 16777063 > .Lfe1: > .size handle_intr,.Lfe1-handle_intr > -------------------------- clip ------------------------------------------- > > When this was the 1st ISR-test I tried with gcc-3.0.2, and there was this > error in the basic principle: "All the registers used inside the ISR must > be saved in the prologue and restored in the epilogue", this wasn't very > promising... > > However fixing this 'bug' in gcc-3.0.2 isn't hard, after my own implementation > for the earlier GCCs, and then doing some work to handle the r11 - r15 (the 'fp', > 'ip', 'lr' and 'pc' - the r13 is the 'sp') inside a ISR, some kind of 'fix' was > done in 15 minutes... > > But should this 'bug' be fixed? Perhaps not because the 'ip' case, but also > the 'lr' handling fails in gcc-3.0.2. The 'lr'/'r14' is one of those 'scratch' > registers and may be allocated too... Another test with more processing in the > ISR revealed that this really happens and the return address in 'lr' is written > over... > > Ok, the words "was able to get the 3.0.2 snapshot to work" clash with my > experiences presented here... What I cannot find is what kind of prologue and > epilogue wrappers done in assembly should be done for this. I understand that > the ARM-architecture is not so well defined in this respect. For instance the > Atmel AT91 has a special interrupt controller, 'AIC', which helps the following > to happen: > > ---------------------- clip --------------------------------------------------- > ;- An interrupt occurs : > ;- The core set the I bit and switch in IRQ Mode. The Program counter is stored > ;- in the Link Register before being loaded with the IRQ vector 0x00000018. > ;- The Current Program Status Register is stored in the SPSR_irq register. > ;- The core execute the instruction stored in the vector ( ldr pc, [pc,#-&F20] ) > ;- and load the PC with the value read in the Interrupt Vector Register of the > ;- Advanced Interrupt Controller. > ;- Read of the Interrupt Vector Register automatically clears the interrupt > ;- if this one is programmed edge triggered, and push in hardware stack the > ;- level of priority of the interrupt. > ;- The value read in IVR is stored in the PC. This branch here. > ---------------------- clip --------------------------------------------------- > > So 'stand-alone' ISR-functions can be generated by GCC at least for this ARM- > CPU variation, if wanted, but what about all the others? > > If there is a support for ISRs now in GCC, there should somewhere an explanation > how one uses the support, what kind of 'wrappers' one needs around the gcc-3.x- > generated code and so on... Has anyone found anything about this? > > Meanwhile my opinion is that the 'ip', 'lr' and 'fp' should be saved in the > GCC-generated prologue, if the ISR uses them or if the ISR calls a 'normal' > function which perhaps uses them but doesn't save them... A clip from the > 'gcc/config/arm/arm.h' tells about the current register usage: > > -------------------------- clip ------------------------------------------- > /* Standard register usage. */ > > /* Register allocation in ARM Procedure Call Standard (as used on RISCiX): > (S - saved over call). > > r0 * argument word/integer result > r1-r3 argument word > > r4-r8 S register variable > r9 S (rfp) register variable (real frame pointer) > > r10 F S (sl) stack limit (used by -mapcs-stack-check) > r11 F S (fp) argument pointer > r12 (ip) temp workspace > r13 F S (sp) lower end of current stack frame > r14 (lr) link address/workspace > r15 F (pc) program counter > > f0 floating point result > f1-f3 floating point scratch > > f4-f7 S floating point variable > -------------------------- clip ------------------------------------------- > > Not leaving the 'ip' and 'fp'-saving to some unspecified wrappers, but > doing this in the ISR-prologue, and the restoring in the ISR-epilogue, > would be more 'normal', I don't understand what is the idea behind the > current implementation... > > Cheers, Kai ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |