This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Nested interrupts

Hi,

I'm trying to get an idea of the best (only?) way to implement interrupt nesting (i.e. a lower priority ISR being interrupted by a higher priority one). I'm using only the VIC IRQ of an STR91 device (i.e no FIQ). Using UV3 & RealView. Having reviewed what I've read here, it seems that I need to:

1) Upon ISR entry, save the current context
2) Enter supervisor mode in order to...
3) ...re-enable interrupts (allowing pre-emption)
4) Process ISR
5) Revert to user mode
6) Restore context
7) Leave ISR

Q1. Is the only way to enter supervisor mode via an SWI?
Q2.Would all my ISR's requiring pre-emption (not all would) have to be encased in an asm wrapper?
Q3. Are there some 'intrinsics' that can be used for this purpose? (I'm having difficulty finding a definitive list of them)
Q4. Is my understanding correct?

Any clarification/recommendations on this would be appreciated.

Thanks

Dave

  • Hi,

    I've had a look, and am trying to adapt the example given:

    
    Add the following assembler wrapper (in a separate assembly module) to the interrupt function:
    
           PRESERVE8
           AREA    NEST_IRQ, CODE, READONLY
           ARM
           IMPORT  eint1_srv
           EXPORT  eint1_irq
    
    eint1_irq
    
           PUSH    {R0-R3,R12,LR}          ; save register context
           MRS     LR, SPSR                ; Copy SPSR_irq to LR
           PUSH    {LR}                    ; Save SPSR_irq
           MSR     CPSR_c, #0x1F           ; Enable IRQ (Sys Mode)
           PUSH    {LR}                    ; Save LR
    
           BL      eint1_srv
    
           POP     {LR}                    ; Restore LR
           MSR     CPSR_c, #0x92           ; Disable IRQ (IRQ Mode)
           POP     {LR}                    ; Restore SPSR_irq to LR
           MSR     SPSR_cxsf, LR           ; Copy LR to SPSR_irq
    
    ;      VICVectAddr = 0;                ; Acknowledge Interrupt
           MOV     R0,#0
           STR     R0,[R0,#-0xFD0]
    
           POP     {R0-R3,R12,LR}          ; restore register context
           SUBS    R15,R14,#0x0004         ; return from interrupt
    
    
           END
    
    

    I'm struggling to adapt the asm relating to reading the relevant VIC current vector address (which I guess is here)

    VICVectAddr = 0;                ; Acknowledge Interrupt
           MOV     R0,#0
           STR     R0,[R0,#-0xFD0]
    


    I'm not to clear what's actually happening here- what I need to do amounts to the VIC1->VAR = 0 statement in 'C', which amounts to a write to 0xFC00.0030 on the STR91x device.

    How do I adapt what's in this example to do this?

  • David,
    please refer to documentation related to ARM9 interrupt handling. note that upon an IRQ, the ARM9 always jumps to 0x18, where an instruction to jump to a address specified at 0xFFFFFF030 (filled by the VIC) is located. that is what you see happening in that snippet of code. handling a FIQ happens by jumping to 0x1C where your ISR is located.