1df373737SAchin Gupta /* 217e84eedSJeenu Viswambharan * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3df373737SAchin Gupta * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5df373737SAchin Gupta */ 6df373737SAchin Gupta 7df373737SAchin Gupta #include <assert.h> 8*09d40e0eSAntonio Nino Diaz 9*09d40e0eSAntonio Nino Diaz #include <drivers/arm/gic_common.h> 10*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 11*09d40e0eSAntonio Nino Diaz 12e9ec3cecSSoby Mathew #include "gic_common_private.h" 13df373737SAchin Gupta 14df373737SAchin Gupta /******************************************************************************* 15df373737SAchin Gupta * GIC Distributor interface accessors for reading entire registers 16df373737SAchin Gupta ******************************************************************************/ 17df373737SAchin Gupta /* 18df373737SAchin Gupta * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt 19df373737SAchin Gupta * `id`, 32 interrupt ids at a time. 20df373737SAchin Gupta */ 21df373737SAchin Gupta unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) 22df373737SAchin Gupta { 233fea9c8bSAntonio Nino Diaz unsigned int n = id >> IGROUPR_SHIFT; 243fea9c8bSAntonio Nino Diaz 25df373737SAchin Gupta return mmio_read_32(base + GICD_IGROUPR + (n << 2)); 26df373737SAchin Gupta } 27df373737SAchin Gupta 28df373737SAchin Gupta /* 29df373737SAchin Gupta * Accessor to read the GIC Distributor ISENABLER corresponding to the 30df373737SAchin Gupta * interrupt `id`, 32 interrupt ids at a time. 31df373737SAchin Gupta */ 32df373737SAchin Gupta unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) 33df373737SAchin Gupta { 343fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISENABLER_SHIFT; 353fea9c8bSAntonio Nino Diaz 36df373737SAchin Gupta return mmio_read_32(base + GICD_ISENABLER + (n << 2)); 37df373737SAchin Gupta } 38df373737SAchin Gupta 39df373737SAchin Gupta /* 40df373737SAchin Gupta * Accessor to read the GIC Distributor ICENABLER corresponding to the 41df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 42df373737SAchin Gupta */ 43df373737SAchin Gupta unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) 44df373737SAchin Gupta { 453fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICENABLER_SHIFT; 463fea9c8bSAntonio Nino Diaz 47df373737SAchin Gupta return mmio_read_32(base + GICD_ICENABLER + (n << 2)); 48df373737SAchin Gupta } 49df373737SAchin Gupta 50df373737SAchin Gupta /* 51df373737SAchin Gupta * Accessor to read the GIC Distributor ISPENDR corresponding to the 52df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 53df373737SAchin Gupta */ 54df373737SAchin Gupta unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) 55df373737SAchin Gupta { 563fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISPENDR_SHIFT; 573fea9c8bSAntonio Nino Diaz 58df373737SAchin Gupta return mmio_read_32(base + GICD_ISPENDR + (n << 2)); 59df373737SAchin Gupta } 60df373737SAchin Gupta 61df373737SAchin Gupta /* 62df373737SAchin Gupta * Accessor to read the GIC Distributor ICPENDR corresponding to the 63df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 64df373737SAchin Gupta */ 65df373737SAchin Gupta unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) 66df373737SAchin Gupta { 673fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICPENDR_SHIFT; 683fea9c8bSAntonio Nino Diaz 69df373737SAchin Gupta return mmio_read_32(base + GICD_ICPENDR + (n << 2)); 70df373737SAchin Gupta } 71df373737SAchin Gupta 72df373737SAchin Gupta /* 73df373737SAchin Gupta * Accessor to read the GIC Distributor ISACTIVER corresponding to the 74df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 75df373737SAchin Gupta */ 76df373737SAchin Gupta unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) 77df373737SAchin Gupta { 783fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISACTIVER_SHIFT; 793fea9c8bSAntonio Nino Diaz 80df373737SAchin Gupta return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); 81df373737SAchin Gupta } 82df373737SAchin Gupta 83df373737SAchin Gupta /* 84df373737SAchin Gupta * Accessor to read the GIC Distributor ICACTIVER corresponding to the 85df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 86df373737SAchin Gupta */ 87df373737SAchin Gupta unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) 88df373737SAchin Gupta { 893fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICACTIVER_SHIFT; 903fea9c8bSAntonio Nino Diaz 91df373737SAchin Gupta return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); 92df373737SAchin Gupta } 93df373737SAchin Gupta 94df373737SAchin Gupta /* 95df373737SAchin Gupta * Accessor to read the GIC Distributor IPRIORITYR corresponding to the 96df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 97df373737SAchin Gupta */ 98df373737SAchin Gupta unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) 99df373737SAchin Gupta { 1003fea9c8bSAntonio Nino Diaz unsigned int n = id >> IPRIORITYR_SHIFT; 1013fea9c8bSAntonio Nino Diaz 102df373737SAchin Gupta return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); 103df373737SAchin Gupta } 104df373737SAchin Gupta 105df373737SAchin Gupta /* 106df373737SAchin Gupta * Accessor to read the GIC Distributor ICGFR corresponding to the 107df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 108df373737SAchin Gupta */ 109df373737SAchin Gupta unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) 110df373737SAchin Gupta { 1113fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICFGR_SHIFT; 1123fea9c8bSAntonio Nino Diaz 113df373737SAchin Gupta return mmio_read_32(base + GICD_ICFGR + (n << 2)); 114df373737SAchin Gupta } 115df373737SAchin Gupta 116df373737SAchin Gupta /* 117df373737SAchin Gupta * Accessor to read the GIC Distributor NSACR corresponding to the 118df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 119df373737SAchin Gupta */ 120df373737SAchin Gupta unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) 121df373737SAchin Gupta { 1223fea9c8bSAntonio Nino Diaz unsigned int n = id >> NSACR_SHIFT; 1233fea9c8bSAntonio Nino Diaz 124df373737SAchin Gupta return mmio_read_32(base + GICD_NSACR + (n << 2)); 125df373737SAchin Gupta } 126df373737SAchin Gupta 127df373737SAchin Gupta /******************************************************************************* 128df373737SAchin Gupta * GIC Distributor interface accessors for writing entire registers 129df373737SAchin Gupta ******************************************************************************/ 130df373737SAchin Gupta /* 131df373737SAchin Gupta * Accessor to write the GIC Distributor IGROUPR corresponding to the 132df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 133df373737SAchin Gupta */ 134df373737SAchin Gupta void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) 135df373737SAchin Gupta { 1363fea9c8bSAntonio Nino Diaz unsigned int n = id >> IGROUPR_SHIFT; 1373fea9c8bSAntonio Nino Diaz 138df373737SAchin Gupta mmio_write_32(base + GICD_IGROUPR + (n << 2), val); 139df373737SAchin Gupta } 140df373737SAchin Gupta 141df373737SAchin Gupta /* 142df373737SAchin Gupta * Accessor to write the GIC Distributor ISENABLER corresponding to the 143df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 144df373737SAchin Gupta */ 145df373737SAchin Gupta void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) 146df373737SAchin Gupta { 1473fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISENABLER_SHIFT; 1483fea9c8bSAntonio Nino Diaz 149df373737SAchin Gupta mmio_write_32(base + GICD_ISENABLER + (n << 2), val); 150df373737SAchin Gupta } 151df373737SAchin Gupta 152df373737SAchin Gupta /* 153df373737SAchin Gupta * Accessor to write the GIC Distributor ICENABLER corresponding to the 154df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 155df373737SAchin Gupta */ 156df373737SAchin Gupta void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) 157df373737SAchin Gupta { 1583fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICENABLER_SHIFT; 1593fea9c8bSAntonio Nino Diaz 160df373737SAchin Gupta mmio_write_32(base + GICD_ICENABLER + (n << 2), val); 161df373737SAchin Gupta } 162df373737SAchin Gupta 163df373737SAchin Gupta /* 164df373737SAchin Gupta * Accessor to write the GIC Distributor ISPENDR corresponding to the 165df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 166df373737SAchin Gupta */ 167df373737SAchin Gupta void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) 168df373737SAchin Gupta { 1693fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISPENDR_SHIFT; 1703fea9c8bSAntonio Nino Diaz 171df373737SAchin Gupta mmio_write_32(base + GICD_ISPENDR + (n << 2), val); 172df373737SAchin Gupta } 173df373737SAchin Gupta 174df373737SAchin Gupta /* 175df373737SAchin Gupta * Accessor to write the GIC Distributor ICPENDR corresponding to the 176df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 177df373737SAchin Gupta */ 178df373737SAchin Gupta void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) 179df373737SAchin Gupta { 1803fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICPENDR_SHIFT; 1813fea9c8bSAntonio Nino Diaz 182df373737SAchin Gupta mmio_write_32(base + GICD_ICPENDR + (n << 2), val); 183df373737SAchin Gupta } 184df373737SAchin Gupta 185df373737SAchin Gupta /* 186df373737SAchin Gupta * Accessor to write the GIC Distributor ISACTIVER corresponding to the 187df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 188df373737SAchin Gupta */ 189df373737SAchin Gupta void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) 190df373737SAchin Gupta { 1913fea9c8bSAntonio Nino Diaz unsigned int n = id >> ISACTIVER_SHIFT; 1923fea9c8bSAntonio Nino Diaz 193df373737SAchin Gupta mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); 194df373737SAchin Gupta } 195df373737SAchin Gupta 196df373737SAchin Gupta /* 197df373737SAchin Gupta * Accessor to write the GIC Distributor ICACTIVER corresponding to the 198df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 199df373737SAchin Gupta */ 200df373737SAchin Gupta void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) 201df373737SAchin Gupta { 2023fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICACTIVER_SHIFT; 2033fea9c8bSAntonio Nino Diaz 204df373737SAchin Gupta mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); 205df373737SAchin Gupta } 206df373737SAchin Gupta 207df373737SAchin Gupta /* 208df373737SAchin Gupta * Accessor to write the GIC Distributor IPRIORITYR corresponding to the 209df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 210df373737SAchin Gupta */ 211df373737SAchin Gupta void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 212df373737SAchin Gupta { 2133fea9c8bSAntonio Nino Diaz unsigned int n = id >> IPRIORITYR_SHIFT; 2143fea9c8bSAntonio Nino Diaz 215df373737SAchin Gupta mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); 216df373737SAchin Gupta } 217df373737SAchin Gupta 218df373737SAchin Gupta /* 219df373737SAchin Gupta * Accessor to write the GIC Distributor ICFGR corresponding to the 220df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 221df373737SAchin Gupta */ 222df373737SAchin Gupta void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) 223df373737SAchin Gupta { 2243fea9c8bSAntonio Nino Diaz unsigned int n = id >> ICFGR_SHIFT; 2253fea9c8bSAntonio Nino Diaz 226df373737SAchin Gupta mmio_write_32(base + GICD_ICFGR + (n << 2), val); 227df373737SAchin Gupta } 228df373737SAchin Gupta 229df373737SAchin Gupta /* 230df373737SAchin Gupta * Accessor to write the GIC Distributor NSACR corresponding to the 231df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 232df373737SAchin Gupta */ 233df373737SAchin Gupta void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) 234df373737SAchin Gupta { 2353fea9c8bSAntonio Nino Diaz unsigned int n = id >> NSACR_SHIFT; 2363fea9c8bSAntonio Nino Diaz 237df373737SAchin Gupta mmio_write_32(base + GICD_NSACR + (n << 2), val); 238df373737SAchin Gupta } 239df373737SAchin Gupta 240df373737SAchin Gupta /******************************************************************************* 241e9ec3cecSSoby Mathew * GIC Distributor functions for accessing the GIC registers 242e9ec3cecSSoby Mathew * corresponding to a single interrupt ID. These functions use bitwise 243e9ec3cecSSoby Mathew * operations or appropriate register accesses to modify or return 244e9ec3cecSSoby Mathew * the bit-field corresponding the single interrupt ID. 245df373737SAchin Gupta ******************************************************************************/ 246df373737SAchin Gupta unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) 247df373737SAchin Gupta { 2483fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 249df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 250df373737SAchin Gupta 2513fea9c8bSAntonio Nino Diaz return (reg_val >> bit_num) & 0x1U; 252df373737SAchin Gupta } 253df373737SAchin Gupta 254df373737SAchin Gupta void gicd_set_igroupr(uintptr_t base, unsigned int id) 255df373737SAchin Gupta { 2563fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 257df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 258df373737SAchin Gupta 2593fea9c8bSAntonio Nino Diaz gicd_write_igroupr(base, id, reg_val | (1U << bit_num)); 260df373737SAchin Gupta } 261df373737SAchin Gupta 262df373737SAchin Gupta void gicd_clr_igroupr(uintptr_t base, unsigned int id) 263df373737SAchin Gupta { 2643fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); 265df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 266df373737SAchin Gupta 2673fea9c8bSAntonio Nino Diaz gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num)); 268df373737SAchin Gupta } 269df373737SAchin Gupta 270df373737SAchin Gupta void gicd_set_isenabler(uintptr_t base, unsigned int id) 271df373737SAchin Gupta { 2723fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); 273df373737SAchin Gupta 2743fea9c8bSAntonio Nino Diaz gicd_write_isenabler(base, id, (1U << bit_num)); 275df373737SAchin Gupta } 276df373737SAchin Gupta 277df373737SAchin Gupta void gicd_set_icenabler(uintptr_t base, unsigned int id) 278df373737SAchin Gupta { 2793fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); 280df373737SAchin Gupta 2813fea9c8bSAntonio Nino Diaz gicd_write_icenabler(base, id, (1U << bit_num)); 282df373737SAchin Gupta } 283df373737SAchin Gupta 284df373737SAchin Gupta void gicd_set_ispendr(uintptr_t base, unsigned int id) 285df373737SAchin Gupta { 2863fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); 287df373737SAchin Gupta 2883fea9c8bSAntonio Nino Diaz gicd_write_ispendr(base, id, (1U << bit_num)); 289df373737SAchin Gupta } 290df373737SAchin Gupta 291df373737SAchin Gupta void gicd_set_icpendr(uintptr_t base, unsigned int id) 292df373737SAchin Gupta { 2933fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); 294df373737SAchin Gupta 2953fea9c8bSAntonio Nino Diaz gicd_write_icpendr(base, id, (1U << bit_num)); 296df373737SAchin Gupta } 297df373737SAchin Gupta 298cbd3f370SJeenu Viswambharan unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) 299cbd3f370SJeenu Viswambharan { 3003fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); 301cbd3f370SJeenu Viswambharan unsigned int reg_val = gicd_read_isactiver(base, id); 302cbd3f370SJeenu Viswambharan 3033fea9c8bSAntonio Nino Diaz return (reg_val >> bit_num) & 0x1U; 304cbd3f370SJeenu Viswambharan } 305cbd3f370SJeenu Viswambharan 306df373737SAchin Gupta void gicd_set_isactiver(uintptr_t base, unsigned int id) 307df373737SAchin Gupta { 3083fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); 309df373737SAchin Gupta 3103fea9c8bSAntonio Nino Diaz gicd_write_isactiver(base, id, (1U << bit_num)); 311df373737SAchin Gupta } 312df373737SAchin Gupta 313df373737SAchin Gupta void gicd_set_icactiver(uintptr_t base, unsigned int id) 314df373737SAchin Gupta { 3153fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U); 316df373737SAchin Gupta 3173fea9c8bSAntonio Nino Diaz gicd_write_icactiver(base, id, (1U << bit_num)); 318df373737SAchin Gupta } 31938a78614SSoby Mathew 32038a78614SSoby Mathew void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) 32138a78614SSoby Mathew { 3223fea9c8bSAntonio Nino Diaz uint8_t val = pri & GIC_PRI_MASK; 3233fea9c8bSAntonio Nino Diaz 3243fea9c8bSAntonio Nino Diaz mmio_write_8(base + GICD_IPRIORITYR + id, val); 32538a78614SSoby Mathew } 32622966106SJeenu Viswambharan 32722966106SJeenu Viswambharan void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) 32822966106SJeenu Viswambharan { 32917e84eedSJeenu Viswambharan /* Interrupt configuration is a 2-bit field */ 3303fea9c8bSAntonio Nino Diaz unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); 33117e84eedSJeenu Viswambharan unsigned int bit_shift = bit_num << 1; 33217e84eedSJeenu Viswambharan 33322966106SJeenu Viswambharan uint32_t reg_val = gicd_read_icfgr(base, id); 33422966106SJeenu Viswambharan 33522966106SJeenu Viswambharan /* Clear the field, and insert required configuration */ 33617e84eedSJeenu Viswambharan reg_val &= ~(GIC_CFG_MASK << bit_shift); 33717e84eedSJeenu Viswambharan reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); 33822966106SJeenu Viswambharan 33922966106SJeenu Viswambharan gicd_write_icfgr(base, id, reg_val); 34022966106SJeenu Viswambharan } 341