1*df373737SAchin Gupta /* 2*df373737SAchin Gupta * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*df373737SAchin Gupta * 4*df373737SAchin Gupta * Redistribution and use in source and binary forms, with or without 5*df373737SAchin Gupta * modification, are permitted provided that the following conditions are met: 6*df373737SAchin Gupta * 7*df373737SAchin Gupta * Redistributions of source code must retain the above copyright notice, this 8*df373737SAchin Gupta * list of conditions and the following disclaimer. 9*df373737SAchin Gupta * 10*df373737SAchin Gupta * Redistributions in binary form must reproduce the above copyright notice, 11*df373737SAchin Gupta * this list of conditions and the following disclaimer in the documentation 12*df373737SAchin Gupta * and/or other materials provided with the distribution. 13*df373737SAchin Gupta * 14*df373737SAchin Gupta * Neither the name of ARM nor the names of its contributors may be used 15*df373737SAchin Gupta * to endorse or promote products derived from this software without specific 16*df373737SAchin Gupta * prior written permission. 17*df373737SAchin Gupta * 18*df373737SAchin Gupta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*df373737SAchin Gupta * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*df373737SAchin Gupta * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*df373737SAchin Gupta * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*df373737SAchin Gupta * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*df373737SAchin Gupta * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*df373737SAchin Gupta * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*df373737SAchin Gupta * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*df373737SAchin Gupta * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*df373737SAchin Gupta * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*df373737SAchin Gupta * POSSIBILITY OF SUCH DAMAGE. 29*df373737SAchin Gupta */ 30*df373737SAchin Gupta 31*df373737SAchin Gupta #include <assert.h> 32*df373737SAchin Gupta #include <gic_common.h> 33*df373737SAchin Gupta #include <mmio.h> 34*df373737SAchin Gupta 35*df373737SAchin Gupta /******************************************************************************* 36*df373737SAchin Gupta * GIC Distributor interface accessors for reading entire registers 37*df373737SAchin Gupta ******************************************************************************/ 38*df373737SAchin Gupta /* 39*df373737SAchin Gupta * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt 40*df373737SAchin Gupta * `id`, 32 interrupt ids at a time. 41*df373737SAchin Gupta */ 42*df373737SAchin Gupta unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) 43*df373737SAchin Gupta { 44*df373737SAchin Gupta unsigned n = id >> IGROUPR_SHIFT; 45*df373737SAchin Gupta return mmio_read_32(base + GICD_IGROUPR + (n << 2)); 46*df373737SAchin Gupta } 47*df373737SAchin Gupta 48*df373737SAchin Gupta /* 49*df373737SAchin Gupta * Accessor to read the GIC Distributor ISENABLER corresponding to the 50*df373737SAchin Gupta * interrupt `id`, 32 interrupt ids at a time. 51*df373737SAchin Gupta */ 52*df373737SAchin Gupta unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) 53*df373737SAchin Gupta { 54*df373737SAchin Gupta unsigned n = id >> ISENABLER_SHIFT; 55*df373737SAchin Gupta return mmio_read_32(base + GICD_ISENABLER + (n << 2)); 56*df373737SAchin Gupta } 57*df373737SAchin Gupta 58*df373737SAchin Gupta /* 59*df373737SAchin Gupta * Accessor to read the GIC Distributor ICENABLER corresponding to the 60*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 61*df373737SAchin Gupta */ 62*df373737SAchin Gupta unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) 63*df373737SAchin Gupta { 64*df373737SAchin Gupta unsigned n = id >> ICENABLER_SHIFT; 65*df373737SAchin Gupta return mmio_read_32(base + GICD_ICENABLER + (n << 2)); 66*df373737SAchin Gupta } 67*df373737SAchin Gupta 68*df373737SAchin Gupta /* 69*df373737SAchin Gupta * Accessor to read the GIC Distributor ISPENDR corresponding to the 70*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 71*df373737SAchin Gupta */ 72*df373737SAchin Gupta unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) 73*df373737SAchin Gupta { 74*df373737SAchin Gupta unsigned n = id >> ISPENDR_SHIFT; 75*df373737SAchin Gupta return mmio_read_32(base + GICD_ISPENDR + (n << 2)); 76*df373737SAchin Gupta } 77*df373737SAchin Gupta 78*df373737SAchin Gupta /* 79*df373737SAchin Gupta * Accessor to read the GIC Distributor ICPENDR corresponding to the 80*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 81*df373737SAchin Gupta */ 82*df373737SAchin Gupta unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) 83*df373737SAchin Gupta { 84*df373737SAchin Gupta unsigned n = id >> ICPENDR_SHIFT; 85*df373737SAchin Gupta return mmio_read_32(base + GICD_ICPENDR + (n << 2)); 86*df373737SAchin Gupta } 87*df373737SAchin Gupta 88*df373737SAchin Gupta /* 89*df373737SAchin Gupta * Accessor to read the GIC Distributor ISACTIVER corresponding to the 90*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 91*df373737SAchin Gupta */ 92*df373737SAchin Gupta unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) 93*df373737SAchin Gupta { 94*df373737SAchin Gupta unsigned n = id >> ISACTIVER_SHIFT; 95*df373737SAchin Gupta return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); 96*df373737SAchin Gupta } 97*df373737SAchin Gupta 98*df373737SAchin Gupta /* 99*df373737SAchin Gupta * Accessor to read the GIC Distributor ICACTIVER corresponding to the 100*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 101*df373737SAchin Gupta */ 102*df373737SAchin Gupta unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) 103*df373737SAchin Gupta { 104*df373737SAchin Gupta unsigned n = id >> ICACTIVER_SHIFT; 105*df373737SAchin Gupta return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); 106*df373737SAchin Gupta } 107*df373737SAchin Gupta 108*df373737SAchin Gupta /* 109*df373737SAchin Gupta * Accessor to read the GIC Distributor IPRIORITYR corresponding to the 110*df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 111*df373737SAchin Gupta */ 112*df373737SAchin Gupta unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) 113*df373737SAchin Gupta { 114*df373737SAchin Gupta unsigned n = id >> IPRIORITYR_SHIFT; 115*df373737SAchin Gupta return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); 116*df373737SAchin Gupta } 117*df373737SAchin Gupta 118*df373737SAchin Gupta /* 119*df373737SAchin Gupta * Accessor to read the GIC Distributor ICGFR corresponding to the 120*df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 121*df373737SAchin Gupta */ 122*df373737SAchin Gupta unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) 123*df373737SAchin Gupta { 124*df373737SAchin Gupta unsigned n = id >> ICFGR_SHIFT; 125*df373737SAchin Gupta return mmio_read_32(base + GICD_ICFGR + (n << 2)); 126*df373737SAchin Gupta } 127*df373737SAchin Gupta 128*df373737SAchin Gupta /* 129*df373737SAchin Gupta * Accessor to read the GIC Distributor NSACR corresponding to the 130*df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 131*df373737SAchin Gupta */ 132*df373737SAchin Gupta unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) 133*df373737SAchin Gupta { 134*df373737SAchin Gupta unsigned n = id >> NSACR_SHIFT; 135*df373737SAchin Gupta return mmio_read_32(base + GICD_NSACR + (n << 2)); 136*df373737SAchin Gupta } 137*df373737SAchin Gupta 138*df373737SAchin Gupta /******************************************************************************* 139*df373737SAchin Gupta * GIC Distributor interface accessors for writing entire registers 140*df373737SAchin Gupta ******************************************************************************/ 141*df373737SAchin Gupta /* 142*df373737SAchin Gupta * Accessor to write the GIC Distributor IGROUPR corresponding to the 143*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 144*df373737SAchin Gupta */ 145*df373737SAchin Gupta void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) 146*df373737SAchin Gupta { 147*df373737SAchin Gupta unsigned n = id >> IGROUPR_SHIFT; 148*df373737SAchin Gupta mmio_write_32(base + GICD_IGROUPR + (n << 2), val); 149*df373737SAchin Gupta } 150*df373737SAchin Gupta 151*df373737SAchin Gupta /* 152*df373737SAchin Gupta * Accessor to write the GIC Distributor ISENABLER corresponding to the 153*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 154*df373737SAchin Gupta */ 155*df373737SAchin Gupta void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) 156*df373737SAchin Gupta { 157*df373737SAchin Gupta unsigned n = id >> ISENABLER_SHIFT; 158*df373737SAchin Gupta mmio_write_32(base + GICD_ISENABLER + (n << 2), val); 159*df373737SAchin Gupta } 160*df373737SAchin Gupta 161*df373737SAchin Gupta /* 162*df373737SAchin Gupta * Accessor to write the GIC Distributor ICENABLER corresponding to the 163*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 164*df373737SAchin Gupta */ 165*df373737SAchin Gupta void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) 166*df373737SAchin Gupta { 167*df373737SAchin Gupta unsigned n = id >> ICENABLER_SHIFT; 168*df373737SAchin Gupta mmio_write_32(base + GICD_ICENABLER + (n << 2), val); 169*df373737SAchin Gupta } 170*df373737SAchin Gupta 171*df373737SAchin Gupta /* 172*df373737SAchin Gupta * Accessor to write the GIC Distributor ISPENDR corresponding to the 173*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 174*df373737SAchin Gupta */ 175*df373737SAchin Gupta void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) 176*df373737SAchin Gupta { 177*df373737SAchin Gupta unsigned n = id >> ISPENDR_SHIFT; 178*df373737SAchin Gupta mmio_write_32(base + GICD_ISPENDR + (n << 2), val); 179*df373737SAchin Gupta } 180*df373737SAchin Gupta 181*df373737SAchin Gupta /* 182*df373737SAchin Gupta * Accessor to write the GIC Distributor ICPENDR corresponding to the 183*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 184*df373737SAchin Gupta */ 185*df373737SAchin Gupta void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) 186*df373737SAchin Gupta { 187*df373737SAchin Gupta unsigned n = id >> ICPENDR_SHIFT; 188*df373737SAchin Gupta mmio_write_32(base + GICD_ICPENDR + (n << 2), val); 189*df373737SAchin Gupta } 190*df373737SAchin Gupta 191*df373737SAchin Gupta /* 192*df373737SAchin Gupta * Accessor to write the GIC Distributor ISACTIVER corresponding to the 193*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 194*df373737SAchin Gupta */ 195*df373737SAchin Gupta void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) 196*df373737SAchin Gupta { 197*df373737SAchin Gupta unsigned n = id >> ISACTIVER_SHIFT; 198*df373737SAchin Gupta mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); 199*df373737SAchin Gupta } 200*df373737SAchin Gupta 201*df373737SAchin Gupta /* 202*df373737SAchin Gupta * Accessor to write the GIC Distributor ICACTIVER corresponding to the 203*df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 204*df373737SAchin Gupta */ 205*df373737SAchin Gupta void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) 206*df373737SAchin Gupta { 207*df373737SAchin Gupta unsigned n = id >> ICACTIVER_SHIFT; 208*df373737SAchin Gupta mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); 209*df373737SAchin Gupta } 210*df373737SAchin Gupta 211*df373737SAchin Gupta /* 212*df373737SAchin Gupta * Accessor to write the GIC Distributor IPRIORITYR corresponding to the 213*df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 214*df373737SAchin Gupta */ 215*df373737SAchin Gupta void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 216*df373737SAchin Gupta { 217*df373737SAchin Gupta unsigned n = id >> IPRIORITYR_SHIFT; 218*df373737SAchin Gupta mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); 219*df373737SAchin Gupta } 220*df373737SAchin Gupta 221*df373737SAchin Gupta /* 222*df373737SAchin Gupta * Accessor to write the GIC Distributor ICFGR corresponding to the 223*df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 224*df373737SAchin Gupta */ 225*df373737SAchin Gupta void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) 226*df373737SAchin Gupta { 227*df373737SAchin Gupta unsigned n = id >> ICFGR_SHIFT; 228*df373737SAchin Gupta mmio_write_32(base + GICD_ICFGR + (n << 2), val); 229*df373737SAchin Gupta } 230*df373737SAchin Gupta 231*df373737SAchin Gupta /* 232*df373737SAchin Gupta * Accessor to write the GIC Distributor NSACR corresponding to the 233*df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 234*df373737SAchin Gupta */ 235*df373737SAchin Gupta void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) 236*df373737SAchin Gupta { 237*df373737SAchin Gupta unsigned n = id >> NSACR_SHIFT; 238*df373737SAchin Gupta mmio_write_32(base + GICD_NSACR + (n << 2), val); 239*df373737SAchin Gupta } 240*df373737SAchin Gupta 241*df373737SAchin Gupta /******************************************************************************* 242*df373737SAchin Gupta * GIC Distributor interface accessors for individual interrupt manipulation 243*df373737SAchin Gupta ******************************************************************************/ 244*df373737SAchin Gupta unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) 245*df373737SAchin Gupta { 246*df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 247*df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 248*df373737SAchin Gupta 249*df373737SAchin Gupta return (reg_val >> bit_num) & 0x1; 250*df373737SAchin Gupta } 251*df373737SAchin Gupta 252*df373737SAchin Gupta void gicd_set_igroupr(uintptr_t base, unsigned int id) 253*df373737SAchin Gupta { 254*df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 255*df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 256*df373737SAchin Gupta 257*df373737SAchin Gupta gicd_write_igroupr(base, id, reg_val | (1 << bit_num)); 258*df373737SAchin Gupta } 259*df373737SAchin Gupta 260*df373737SAchin Gupta void gicd_clr_igroupr(uintptr_t base, unsigned int id) 261*df373737SAchin Gupta { 262*df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 263*df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 264*df373737SAchin Gupta 265*df373737SAchin Gupta gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num)); 266*df373737SAchin Gupta } 267*df373737SAchin Gupta 268*df373737SAchin Gupta void gicd_set_isenabler(uintptr_t base, unsigned int id) 269*df373737SAchin Gupta { 270*df373737SAchin Gupta unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); 271*df373737SAchin Gupta 272*df373737SAchin Gupta gicd_write_isenabler(base, id, (1 << bit_num)); 273*df373737SAchin Gupta } 274*df373737SAchin Gupta 275*df373737SAchin Gupta void gicd_set_icenabler(uintptr_t base, unsigned int id) 276*df373737SAchin Gupta { 277*df373737SAchin Gupta unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); 278*df373737SAchin Gupta 279*df373737SAchin Gupta gicd_write_icenabler(base, id, (1 << bit_num)); 280*df373737SAchin Gupta } 281*df373737SAchin Gupta 282*df373737SAchin Gupta void gicd_set_ispendr(uintptr_t base, unsigned int id) 283*df373737SAchin Gupta { 284*df373737SAchin Gupta unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); 285*df373737SAchin Gupta 286*df373737SAchin Gupta gicd_write_ispendr(base, id, (1 << bit_num)); 287*df373737SAchin Gupta } 288*df373737SAchin Gupta 289*df373737SAchin Gupta void gicd_set_icpendr(uintptr_t base, unsigned int id) 290*df373737SAchin Gupta { 291*df373737SAchin Gupta unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); 292*df373737SAchin Gupta 293*df373737SAchin Gupta gicd_write_icpendr(base, id, (1 << bit_num)); 294*df373737SAchin Gupta } 295*df373737SAchin Gupta 296*df373737SAchin Gupta void gicd_set_isactiver(uintptr_t base, unsigned int id) 297*df373737SAchin Gupta { 298*df373737SAchin Gupta unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); 299*df373737SAchin Gupta 300*df373737SAchin Gupta gicd_write_isactiver(base, id, (1 << bit_num)); 301*df373737SAchin Gupta } 302*df373737SAchin Gupta 303*df373737SAchin Gupta void gicd_set_icactiver(uintptr_t base, unsigned int id) 304*df373737SAchin Gupta { 305*df373737SAchin Gupta unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1); 306*df373737SAchin Gupta 307*df373737SAchin Gupta gicd_write_icactiver(base, id, (1 << bit_num)); 308*df373737SAchin Gupta } 309