diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-09-22 08:32:09 +0100 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-10-16 16:50:02 +0100 |
commit | fc529fee720de5fef8388c52bfefcb807ac764b0 (patch) | |
tree | 01378c294cf169c5fdf84e3bcab1295ce0bb4068 /drivers/arm/gic/v3/gicv3_main.c | |
parent | 8db978b5a8606a658c65b16fab7edd7a17c7c940 (diff) |
GIC: Add API to set interrupt routing
SPIs can be routed to either a specific PE, or to any one of all
available PEs.
API documentation updated.
Change-Id: I28675f634568aaf4ea1aa8aa7ebf25b419a963ed
Co-authored-by: Yousuf A <yousuf.sait@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'drivers/arm/gic/v3/gicv3_main.c')
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index a5067322..c81ba950 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -999,3 +999,41 @@ void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target) write_icc_sgi0r_el1(sgi_val); isb(); } + +/******************************************************************************* + * This function sets the interrupt routing for the given SPI interrupt id. + * The interrupt routing is specified in routing mode and mpidr. + * + * The routing mode can be either of: + * - GICV3_IRM_ANY + * - GICV3_IRM_PE + * + * The mpidr is the affinity of the PE to which the interrupt will be routed, + * and is ignored for routing mode GICV3_IRM_ANY. + ******************************************************************************/ +void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr) +{ + unsigned long long aff; + uint64_t router; + + assert(gicv3_driver_data); + assert(gicv3_driver_data->gicd_base); + + assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE)); + assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID); + + aff = gicd_irouter_val_from_mpidr(mpidr, irm); + gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff); + + /* + * In implementations that do not require 1 of N distribution of SPIs, + * IRM might be RAZ/WI. Read back and verify IRM bit. + */ + if (irm == GICV3_IRM_ANY) { + router = gicd_read_irouter(gicv3_driver_data->gicd_base, id); + if (!((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK)) { + ERROR("GICv3 implementation doesn't support routing ANY\n"); + panic(); + } + } +} |