I have identified what seem to be the relevant elements of this example, and reviewed them against the relevant ARM GIC documentation.
I observe that, by default, Linux runs with security options inactive.
I observe that, by default, all interrupts are group 0, and that LINUX uses the IRQ signal for group 0 interrupts.
The first issue, then, is that only group 0 interrupts can signal the FIQ handler.
From the code example, patch 1 does most of the key modifications in the GIC driver code.
As a first step and sanity check, I have chosen to do the following:
Reassign all interrupts as group 1 and only enable group 1 interrupts.
I am not yet using any FIQ, nor enabling group 0 as either IRQ or FIQ.
This change is implemented entirely within the GIC module in arch/arm/common/gic.c (details below)
There is a register array base also for which the offset is added as a define macro in arch/arm/include/asm/hardware/gic.h
My expectation would be that this change is transparent, and everything in the Kernel world should be oblivious to this change.
Unfortunately, this is not the case... Relatively early in the boot process, just after the GPT interrupt is enabled, everything stops...
code fragments thus far:
in gic.h I added:
#define GIC_DIST_GROUP_SET 0x080
-- Note that the code example used GIC_DIST_SECURE_SET, but I found that to be a misnomer.
Since these bits change what the ARM documentation refers to as the 'interrupt group' GIC_DIST_GROUP_SET made more sense.
in gic_dist_init() the following is added:
/* SDA-SQS - Set all irq to Group 1 mode
** By default, since no FIQ is used, all can be group 0 since all are the same anyway...
** Wanting to use an FIQ we will make all group 0 interrupts use FIQ as part of this test...
** To do that we first need to make all the 'normal' interrupts use group 1...
*/
for (i = 0; i < gic_irqs; i += 32)
writel_relaxed(0xffffffff, base + GIC_DIST_GROUP_SET + i * 4 / 32);
-- Note that this is added just after initialization of the GIC_DIST_ENABLE_CLEAR registers
and at the end of that procedure:
writel_relaxed(2, base + GIC_DIST_CTRL);
-- Note that the original code wrote '1' which is enable for group 0, while '2' is enable for group 1 interrupts.
in gic_cup_init() the following is changed:
writel_relaxed(2, base + GIC_CPU_CTRL);
-- Note that the original code wrote '1' which is enable for group 0, while '2' is enable for group 1 interrupts.
-- Also since I am not yet using FIQ I have not set any of the other bits in this control register.
All other things being equal, it seems this should be a transparent set of changes.
Have I missed something obvious?