To generate a FIQ from ARM GIC apart from setting GICC_CTLR.FIQEn what else needs to be configured?

I'm just trying to generate an FIQ from GIC .All the interrupts are by default grouped to Group0 and apart from setting FIQEn trying to understand what else needs to be configured..

Parents
  • Hi,

    Note that I'm assuming here that you're in the Secure world, seeing as you're setting GICC_CTLR.FIQEn.

    Let's use interrupt ID #0 (an SGI) as the interrupt that you want to receive.

    1. Enable forwarding of Group 0 interrupts from the Distributor to the CPU interfaces by setting GICD_CTLR.EnableGrp0
    2. Set the priority value of interrupt ID #0 (for example to 0x0) by writing to GICD_IPRIORITYR0
    3. Enable interrupt ID #0 by setting bit [0] of GICD_ISENABLER0
    4. Set the priority mask value to a lower priority than that of the chosen interrupt (for example to 0xFF) by writing to GICC_PMR
    5. Set the binary point value (for example to 0x7 to disable preemption) by writing to GICC_BPR
    6. Enable signalling of Group 0 interrupts from the CPU interface to the CPU, as well as signalling Group 0 interrupts as FIQs, by setting GICC_CTLR.FIQEn and GICC_CTLR.EnableGrp0
    7. Unmask FIQs (for example in AArch64: MSR DAIFClr, #0b0001)
    8. Send yourself the SGI by writing value 0x2000000 to GICD_SGIR. This targets SGI #0 only at the writing CPU's CPU interface

    The process is very similar for PPIs and SPIs, with some additional steps:

    • Both PPIs and SPIs may need to be manually configured as either level-sensitive or edge-triggered by writing to the corresponding GICD_ICFGRn register
    • SPIs need a mask of target CPU interfaces setting by writing to the corresponding GICD_ITARGETSRn register

    Note that you can follow the above steps and then write to the corresponding bit in the corresponding GICD_ISPENDRn register to forcefully set the interrupt as pending.

    Hope that helps,

    Ash

Reply
  • Hi,

    Note that I'm assuming here that you're in the Secure world, seeing as you're setting GICC_CTLR.FIQEn.

    Let's use interrupt ID #0 (an SGI) as the interrupt that you want to receive.

    1. Enable forwarding of Group 0 interrupts from the Distributor to the CPU interfaces by setting GICD_CTLR.EnableGrp0
    2. Set the priority value of interrupt ID #0 (for example to 0x0) by writing to GICD_IPRIORITYR0
    3. Enable interrupt ID #0 by setting bit [0] of GICD_ISENABLER0
    4. Set the priority mask value to a lower priority than that of the chosen interrupt (for example to 0xFF) by writing to GICC_PMR
    5. Set the binary point value (for example to 0x7 to disable preemption) by writing to GICC_BPR
    6. Enable signalling of Group 0 interrupts from the CPU interface to the CPU, as well as signalling Group 0 interrupts as FIQs, by setting GICC_CTLR.FIQEn and GICC_CTLR.EnableGrp0
    7. Unmask FIQs (for example in AArch64: MSR DAIFClr, #0b0001)
    8. Send yourself the SGI by writing value 0x2000000 to GICD_SGIR. This targets SGI #0 only at the writing CPU's CPU interface

    The process is very similar for PPIs and SPIs, with some additional steps:

    • Both PPIs and SPIs may need to be manually configured as either level-sensitive or edge-triggered by writing to the corresponding GICD_ICFGRn register
    • SPIs need a mask of target CPU interfaces setting by writing to the corresponding GICD_ITARGETSRn register

    Note that you can follow the above steps and then write to the corresponding bit in the corresponding GICD_ISPENDRn register to forcefully set the interrupt as pending.

    Hope that helps,

    Ash

Children