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