From b9d14b8fa29af2ad3216614592a177e7e1346f26 Mon Sep 17 00:00:00 2001 From: La1itchauhan Date: Wed, 21 Oct 2026 01:21:16 +0530 Subject: [PATCH] fix(gic): use correct distributor registers for ESPI enable and routing 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 #605 Signed-off-by: La1itchauhan --- val/driver/gic/v3/gic_v3_extended.c | 6 ++++-- val/include/acs_gic.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/val/driver/gic/v3/gic_v3_extended.c b/val/driver/gic/v3/gic_v3_extended.c index a2218c31..285800de 100644 --- a/val/driver/gic/v3/gic_v3_extended.c +++ b/val/driver/gic/v3/gic_v3_extended.c @@ -200,7 +200,7 @@ v3_enable_extended_interrupt_source(uint32_t int_id) /* Calculate register offset and bit position */ regOffset = (int_id - EXTENDED_SPI_START_INTID) / 32; regShift = (int_id - EXTENDED_SPI_START_INTID) % 32; - val_mmio_write(val_get_gicd_base() + GICD_ICENABLERE + (4 * regOffset), 1 << regShift); + val_mmio_write(val_get_gicd_base() + GICD_ISENABLERE + (4 * regOffset), 1 << regShift); } else { /* Calculate register offset and bit position */ regOffset = (int_id - EXTENDED_PPI_REG_OFFSET) / 32; @@ -268,7 +268,9 @@ v3_route_extended_interrupt(uint32_t int_id) Mpidr = read_mpidr_el1(); cpuTarget = Mpidr & (PE_AFF0 | PE_AFF1 | PE_AFF2 | PE_AFF3); - val_mmio_write64(gicd_base + GICD_IROUTERn + (int_id * 8), cpuTarget); + /* ESPI routing registers start at GICD_IROUTERnE; INTID 4096 maps to register 0 */ + val_mmio_write64(gicd_base + GICD_IROUTERnE + + ((int_id - EXTENDED_SPI_START_INTID) * 8U), cpuTarget); } /** diff --git a/val/include/acs_gic.h b/val/include/acs_gic.h index 4a12104d..59ca1b57 100644 --- a/val/include/acs_gic.h +++ b/val/include/acs_gic.h @@ -30,6 +30,7 @@ #define GICD_IROUTER 0x6000 #define GICD_PIDR2 0xFFE8 +#define GICD_ISENABLERE 0x1200 #define GICD_ICENABLERE 0x1400 #define GICD_ICPENDRE0 0x1800 #define GICD_ICACTIVERE0 0x1C00