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

Assertion of IRQS is not causing calling of ISR

Note: This was originally posted on 4th September 2012 at http://forums.arm.com

Hi,

With my current flow, when I am asserting legacy nIRQ I am able to jump to ISR, but not when asserting IRQS[0].
I have enabled interrupts as below
[size=2]CPSIE   ifa, #18

and configured [size=2]Interrupt Security ([/size][/size][size=2][size=2]ICDISR), [size=2][/size][/size][/size][size=2][size=2][size=2][size=2]Interrupt Edge Trigger Config ([/size]ICDIF),[size=2]Interrupt Priority (ICDIPR)[/size][/size][/size][/size],[size=2]Interrupt Target Processor (ICDIPTR),[size=2]Interrupt Enable (ICDISER),[size=2]Interrupt Priority Mask (ICCPMR),[size=2]Interrupt Binary Point (ICCBPR),[size=2]Interface Control Register (ICCICR),[size=2]Distributor Control Register (ICDDCR)

Am I missing something?
Is something separate need to be done, when using IRQS interrupts?

Thanks
Lokesh
[/size][/size][/size][/size][/size][/size]
  • Note: This was originally posted on 4th September 2012 at http://forums.arm.com

    ttfn,

    I don't these registers in latest spec, they are removed
    DDI0407H_cortex_a9_mpcore_r4p0_trm.pdf

    As per programming part there should be same set of programming of registers mentioned above for both nIRQ and IRQS.
    Since for nIRQ ISR is getting called, but not in the case of IRQS?

    Is there any difference in the way of programming in nIRQ and IRQS?

    If you need I can share these registers programming code.

    Thanks
    Lokesh
  • Note: This was originally posted on 4th September 2012 at http://forums.arm.com

    ttfn,

    Is that vector address will be different for IRQS[0] compared to nIRQ?

    If so what is logic to derive vector address for IRQS[0].. IRQS[n]?

    For nIRQ as suggested I am using base address + 0x18

    VecTable
                 LDR  pc, [pc,#0x18]


    Is this same same for all IRQ or different for different IRQS?
  • Note: This was originally posted on 5th September 2012 at http://forums.arm.com

    Hi ttfn,

    Yes you are right I am using cortex A9 MP core
    Here is what I am configuring
      ;;; --------------------------------
    ;;; -Interrupt Security (ICDISR) (ICDISR0 is banked per processor)
    ;;; --------------------------------
        ; Define the security for this SPI interrupt
    [ :DEF:VERBOSE
        MESSAGE "Setting Interrupt Security\n"
    ]
        LDR  r2, =0x00000000 ; 1 = non-secure, 0 = secure
        ADD  r3, r11, #0x80
        MOV  r0, #0
    int_secure_loop
        STR  r2, [r3]
        ADD  r0, r0, #0x1
        ADD  r3, r3, #0x4
    ;    CMP  r0, #0x08 ;#NUM_INT_LOOPS  ;only need 8 times
        CMP  r0, #NUM_INT_LOOPS 
        BNE   int_secure_loop
    ;;; --------------------------------
    ;;; -Interrupt Edge Trigger Config (ICDIFR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
        MESSAGE "Setting Interrupt Trigger Cfg\n"
    ]
        LDR  r2, =0xffffffff ; 1 = edge, 0 = level
        ADD  r3, r11, #0xc00
        MOV  r0, #0
    int_edge_cfg_loop
        STR  r2, [r3]
        ADD  r0, r0, #0x1
        ADD  r3, r3, #0x4
    ;    CMP  r0, #0x10 ;#NUM_INT_LOOPS
        CMP  r0, #NUM_INT_LOOPS
        BNE   int_edge_cfg_loop

    ;;; --------------------------------
    ;;; -Interrupt Priority (ICDIPR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
        MESSAGE "Set Priority (greater than 0 to avoid masking)\n"
    ]
        ADD  r3, r11, #0x400
        LDR  r1, =0x08080808 ;; just make all priorities the same for this test
        MOV  r0, #0
    set_pri_loop   
    ;    STR  r1, [r3, #0x4]
        STR  r1, [r3]
        ADD  r0, r0, #0x1
        ADD  r3, r3, #0x4
        CMP  r0, #NUM_INT_LOOPS
        BNE   set_pri_loop
       
    ;;; --------------------------------
    ;;; -Interrupt Target Processor (ICDIPTR)
    ;;; --------------------------------
        ; Define the target for this SPI interrupt
    [ :DEF:VERBOSE
        MESSAGE "Setting Interrupt Targets\n"
    ]
    ; --- For example purposes, we'll have one processor as an individual target per interrupt
        LDR  r2, =0x01010101 ; See GIC Arch spec : one byte per interrupt : 1 = CPU0, 2 = CPU1, 4=CPU2, 8=CPU3
        ADD  r3, r11, #0x800
        MOV  r0, #0
    int_target_loop
        STR  r2, [r3, #32] ;; Int ID's 0-31 are banked per CPU and not programmed for target processors
        ADD  r0, r0, #0x1
        ADD  r3, r3, #0x4
        CMP  r0, #NUM_INT_LOOPS
        BNE   int_target_loop

    ;;; --------------i------------------
    ;;; -Interrupt Enable (ICDISER)
    ;;; --------------------------------
        ; Now we need to enable the intterupts
    [ :DEF:VERBOSE
        MESSAGE "Enable Interrupts\n"
    ]
        LDR  r2, =0xffffffff
        ADD  r3, r11, #0x100
        MOV  r0, #0
    set_enable_loop
    ;    STR  r2, [r3, #0x4]
        STR  r2, [r3]
        ADD  r0, r0, #0x1
        ADD  r3, r3, #0x4
    ;    CMP  r0, #0x4 ;#NUM_INT_LOOPS
        CMP  r0, #NUM_INT_LOOPS
        BNE   set_enable_loop
       
    ; Per CPU Config
    ; r10 = IC_INT_BASE
    ;;; --------------------------------
    ;;; -Interrupt Priority Mask (ICCPMR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
       MESSAGE "Interrupt Priority Mask register\n"
    ]
       LDR  r1,[r10, #0x04]
       CMP   r1, #0
       BNE   fail
       MOV   r1, #0xf8 ; set priority reg to allow all priority levels to reach CPU
       STR   r1, [r10, #0x04]

       ; MESSAGE "Check2\n"
       
    ;;; --------------------------------
    ;;; -Interrupt Binary Point (ICCBPR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
        MESSAGE "Binary Point register\n"
    ]
        MOV  r1, #3
        STR  r1, [r10, #0x08]

        ;MESSAGE "Check3\n"
       
    ;;; --------------------------------
    ;;; -Interface Control Register (ICCICR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
        MESSAGE "CPU Interface Control Register\n"
    ]
        MOV  r1, #0x1f  ;enable the interface
        STR  r1, [r10]
        ;Enable the Interrupt Interface disables legacy nFIQ/nIRQ support.
        ;The nFIQ/nIRQ pins then become part of the IRQS bus input pins to the controller.


    ;;; --------------------------------
    ;;; -Distributor Control Register (ICDDCR)
    ;;; --------------------------------
    [ :DEF:VERBOSE
            MESSAGE "Distributor Control register\n"
    ]
        ; Now we need to enable the intterupts
        ; The IRQS[] pins won't do anything without being enabled in the distributor
        MOV  r1, #0x1  ; enable SPI/PPI for Secure and Non-Secure modes
        STR  r1, [r11]

     
    Please let me know if I am missing something.

    Thanks
    Lokesh
  • Note: This was originally posted on 6th September 2012 at http://forums.arm.com

    Yes I have cleared it by following instruction

    CPSIE   ifa, #18

    Which GIC spec you are referring.
    I was going through IHI0048A_gic_architecture_spec_v1_0.pdf, but when I searched it on arm infocenter looks like second version of spec is available.
    As per version 2
    [0] EnableGrp1
    [4:1] - Reserved
    [5] FIQBypDisGrp1
    [6] IRQBypDisGrp1
    [8:7] - Reserved.
    [9] EOImodeNS

    So writing 0x1f also may not affect FIQ.
    Anyway which document will be used for cortex A9 mp core.


  • Note: This was originally posted on 6th September 2012 at http://forums.arm.com

    Hi,

    If it's GCC v1 version than my configuration should be correct?

    Please let me know if something is missing.

    Thanks
  • Note: This was originally posted on 4th September 2012 at http://forums.arm.com

    You look like you have the full list of regs - so the question is what are you programming into those registers?

    One thing you might want to check is the Pending Set/Clear registers.  This will let you check whether the IC thinks the interrupt is pending (i.e. whether it sees the signal asserted).
  • Note: This was originally posted on 5th September 2012 at http://forums.arm.com

    You haven't said, but I'm guessing you are using Cortex-A9 MPCore - correct me if I guessed incorrectly.

    So the nIRQ signals are the legacy interrupt signals.  When the CPU interface is disabled (ICCICR.Enable=0) the nIRQ is connected directly to the core.  All you need to generate an IRQ exception is clear CPSR.I and then assert the nIRQ signal (*).

    When you enable the IC (ICCICR.Enable=1 & ICDDCR.Enable=1), the cores interrupts are driven by the IC.  The nIRQ line no longer gets connected to the core directly, but becomes just another interrupt source for the IC (a PPI to be precise, with ID 31).

    To take an interrupt connected via the IRQS signal you must enable and configure the IC.  From your earlier post, you seem to programming all the right registers.  Question is what are you programming them to?  You could, for example, be enabling ID31 (the nIRQ ID) but not ID32 (the IRQS[0] ID).

    On your question about vectors.... No, a Cortex-A9 core has only one IRQ vector. 

    * Remembering that nIRQ is active low.  So to "assert" you actually take the signal low.
  • Note: This was originally posted on 6th September 2012 at http://forums.arm.com

    I've only skimmed through the code, but I spotted one thing you might want to look into.

    You are writing 0x1F into the CPU Interface Control Register (ICCICR), looking at the GIC spec...

      [3] = FIQEn

    Setting this bit means that "secure" interrupts are delivered as FIQ exceptions - not IRQs.  Earlier in the code you zeroed the Interrupt Security (ICDISR), making all your interrupts secure.  So they're all going to be delivered as FIQs.

    Have you cleared the CPSR.F bit?
  • Note: This was originally posted on 6th September 2012 at http://forums.arm.com

    The IC in the Cortex-A9 MPCore is GICv1. 

    Although the GICv2 specification document notes the differences between v1 and v2.