diff options
| author | Frédéric Desbiens <[email protected]> | 2026-08-14 11:42:59 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-08-14 11:42:59 -0400 |
| commit | 19d90a49c495d8d51f058b50e282524cf5ed9f96 (patch) | |
| tree | 7d7e9f4f11cdffcce206186ec8a9fc312238312f /common_modules/module_manager/src | |
| parent | 5a7f4f8f7c9a5d8f193bd2c67d883b0b56930957 (diff) | |
Exercised the nested FIQ path, the last pair nothing had ever called (#613)
_tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end complete the set:
after #611 and #612 covered IRQ nesting on the model and on silicon, these two
were the remaining routines compiled into every build and entered by nothing.
demo_fiq.elf enters them.
FIQ needs more of the GIC than IRQ does. With a single security state the
controller delivers Group 0 as FIQ and Group 1 as IRQ, so an interrupt only
arrives as an FIQ if it has been moved into Group 0, the distributor and the CPU
interface both have Group 0 enabled, and it is acknowledged through the Group 0
registers. Group 1's acknowledge returns the spurious INTID for a Group 0
interrupt and leaves it pending, which would present as a storm rather than as an
error. gicv3.c gains IGRPEN0, BPR0, gicv3_enable_sgi_group0,
gicv3_send_sgi_group0 and the Group 0 acknowledge and EOI pair. ICC_SGI0R differs
from ICC_SGI1R only in opc1, 2 against 0, and each raises into its own group.
entry.S routes the EL1 FIQ vector into _tx_thread_fiq_context_save with the same
ordering the IRQ path needed: acknowledge in FIQ mode before nesting starts, then
nesting_start, service, nesting_end, and end-of-interrupt last. It also leaves
FIQ unmasked on the drop to EL1 when FIQ support is compiled in, because
tx_thread_stack_build only clears a thread's F bit in that configuration and
nothing else ever clears it, so an FIQ raised before the first thread ran would
otherwise be silently ignored.
Nesting an FIQ means taking an FIQ while an FIQ handler runs, which one source
cannot show, so two Group 0 SGIs are used with the second at a numerically lower
priority. The low one's handler raises the high one.
One mistake worth recording, because the guard it needed is not obvious.
TX_ENABLE_FIQ_SUPPORT is PUBLIC on the threadx target, so it reaches every image
as soon as the library is built with FIQ -- including images that link no
interrupt controller at all. demo_m2 is one of those: no gicv3.c, no
irq_dispatch.c. Referencing gicv3_acknowledge_group0 and board_fiq_service from
the FIQ vector broke its link outright. The vector is now gated on
TX_R52_USE_THREADX_IRQ as well, which is how the IRQ vector has always been
gated, and images without the infrastructure keep the fault reporter.
Verified on FVP_BaseR_AEMv8R. F1 covers the whole Group 0 chain on its own --
IGRPEN0, the ICC_SGI0R encoding, IAR0 and EOIR0, the EL1 vector and F being
unmasked -- so a failure there points somewhere other than the nesting routines.
The demo reports 21 low-priority FIQs, 20 high-priority, 20 of them nested, max
depth 2, depth unwound to zero, the IRQ tick undisturbed, threads still
scheduled and no unexpected Group 0 INTID.
All six images pass in the FIQ configuration, and the default build links no FIQ
or Group 0 symbol at all, so the work is absent rather than dormant where it is
not wanted. Both toolchains build every file, GNU with no warnings and Arm
Toolchain for Embedded 22.1.0 as well.
Not done here: the S32Z280 example is untouched, so FIQ on silicon is a separate
change, as IRQ nesting was.
Assisted-by: Claude Code (Opus 5) <[email protected]>
Diffstat (limited to 'common_modules/module_manager/src')
0 files changed, 0 insertions, 0 deletions
