Skip to content

fix(gic): use correct distributor registers for ESPI enable and routing - #653

Merged
chetan-rathore merged 1 commit into
ARM-software:mainfrom
La1itchauhan:fix/605-espi-enable-routing
Oct 23, 2026
Merged

chetan-rathore merged 1 commit into
ARM-software:mainfrom
La1itchauhan:fix/605-espi-enable-routing

Conversation

@La1itchauhan

@La1itchauhan La1itchauhan commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR fixes two distributor register addressing bugs in the GICv3 driver when handling Extended SPIs (ESPIs, INTIDs 4096..5119):

  1. Enable register: v3_enable_extended_interrupt_source() previously wrote to GICD_ICENABLERE (Clear-Enable, offset 0x1400) instead of GICD_ISENABLERE (Set-Enable, offset 0x1200), unintentionally clearing/disabling the interrupt. Added #define GICD_ISENABLERE 0x1200 to val/include/acs_gic.h and updated the driver to write to GICD_ISENABLERE.
  2. Routing register & offset: v3_route_extended_interrupt() previously used GICD_IROUTERn (0x6000, intended only for standard SPIs up to INTID 1019) and multiplied int_id * 8 directly without subtracting EXTENDED_SPI_START_INTID (4096), writing to an invalid out-of-bounds offset (0xE000). Corrected to use GICD_IROUTERnE (0x8000) indexed by (int_id - EXTENDED_SPI_START_INTID) * 8U.

Fixes #605


Test Plan

  • Specification Check: Verified register base offsets and bit indexing against the Arm Generic Interrupt Controller Architecture Specification (Arm IHI 0069):
    • GICD_ISENABLERE<n>: 0x1200 + (4 * n)
    • GICD_ICENABLERE<n>: 0x1400 + (4 * n)
    • GICD_IROUTER<n>E: 0x8000 + (8 * n)
  • Unit Test Execution: Executed an MMIO trace harness compiling val/driver/gic/v3/gic_v3_extended.c under qemu-aarch64:
    • enable ESPI 4133 (ISENABLERE) -> wrote offset 0x1204 (want 0x1204) [PASS]
    • disable ESPI 4133 (ICENABLERE) -> wrote offset 0x1404 (want 0x1404) [PASS]
    • route first ESPI 4096 -> wrote offset 0x8000 (want 0x8000) [PASS]
    • route ESPI 4101 -> wrote offset 0x8028 (want 0x8028) [PASS]
    • route last ESPI 5119 -> wrote offset 0x9ff8 (want 0x9ff8) [PASS]
    • Result: all checks passed

I am a human contributor and I fully understand, reviewed, and verified the code and architectural offsets being submitted.
An AI coding assistant was used to help cross-reference the Arm IHI 0069 register map and format the unit test harness under my direction.

Extended SPI (ESPI) support in the GICv3 driver had two register addressing bugs:

1. v3_enable_extended_interrupt_source() wrote to GICD_ICENABLERE
   (Clear-Enable) instead of GICD_ISENABLERE (Set-Enable). As a result,
   attempting to enable an ESPI source would clear/disable it.
   Define GICD_ISENABLERE (0x1200) in acs_gic.h and write to it when enabling ESPI.

2. v3_route_extended_interrupt() programmed GICD_IROUTERn (0x6000, legacy SPI
   range) and did not subtract EXTENDED_SPI_START_INTID (4096) from int_id,
   writing to an incorrect offset well past the distributor routing space.
   Route ESPIs through GICD_IROUTERnE (0x8000) using the 0-based ESPI index
   (int_id - EXTENDED_SPI_START_INTID).

Fixes ARM-software#605

Signed-off-by: La1itchauhan <chauhanlalitofficial@gmail.com>
@chetan-rathore
chetan-rathore merged commit 7984f28 into ARM-software:main Oct 23, 2026
29 checks passed
@chetan-rathore

Copy link
Copy Markdown
Contributor

Thanks @La1itchauhan for the contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GICv3 ESPI enable and routing use incorrect distributor registers

2 participants