1df373737SAchin Gupta /* 238a78614SSoby 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> 34*e9ec3cecSSoby Mathew #include "gic_common_private.h" 35df373737SAchin Gupta 36df373737SAchin Gupta /******************************************************************************* 37df373737SAchin Gupta * GIC Distributor interface accessors for reading entire registers 38df373737SAchin Gupta ******************************************************************************/ 39df373737SAchin Gupta /* 40df373737SAchin Gupta * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt 41df373737SAchin Gupta * `id`, 32 interrupt ids at a time. 42df373737SAchin Gupta */ 43df373737SAchin Gupta unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) 44df373737SAchin Gupta { 45df373737SAchin Gupta unsigned n = id >> IGROUPR_SHIFT; 46df373737SAchin Gupta return mmio_read_32(base + GICD_IGROUPR + (n << 2)); 47df373737SAchin Gupta } 48df373737SAchin Gupta 49df373737SAchin Gupta /* 50df373737SAchin Gupta * Accessor to read the GIC Distributor ISENABLER corresponding to the 51df373737SAchin Gupta * interrupt `id`, 32 interrupt ids at a time. 52df373737SAchin Gupta */ 53df373737SAchin Gupta unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) 54df373737SAchin Gupta { 55df373737SAchin Gupta unsigned n = id >> ISENABLER_SHIFT; 56df373737SAchin Gupta return mmio_read_32(base + GICD_ISENABLER + (n << 2)); 57df373737SAchin Gupta } 58df373737SAchin Gupta 59df373737SAchin Gupta /* 60df373737SAchin Gupta * Accessor to read the GIC Distributor ICENABLER corresponding to the 61df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 62df373737SAchin Gupta */ 63df373737SAchin Gupta unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) 64df373737SAchin Gupta { 65df373737SAchin Gupta unsigned n = id >> ICENABLER_SHIFT; 66df373737SAchin Gupta return mmio_read_32(base + GICD_ICENABLER + (n << 2)); 67df373737SAchin Gupta } 68df373737SAchin Gupta 69df373737SAchin Gupta /* 70df373737SAchin Gupta * Accessor to read the GIC Distributor ISPENDR corresponding to the 71df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 72df373737SAchin Gupta */ 73df373737SAchin Gupta unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) 74df373737SAchin Gupta { 75df373737SAchin Gupta unsigned n = id >> ISPENDR_SHIFT; 76df373737SAchin Gupta return mmio_read_32(base + GICD_ISPENDR + (n << 2)); 77df373737SAchin Gupta } 78df373737SAchin Gupta 79df373737SAchin Gupta /* 80df373737SAchin Gupta * Accessor to read the GIC Distributor ICPENDR corresponding to the 81df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 82df373737SAchin Gupta */ 83df373737SAchin Gupta unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) 84df373737SAchin Gupta { 85df373737SAchin Gupta unsigned n = id >> ICPENDR_SHIFT; 86df373737SAchin Gupta return mmio_read_32(base + GICD_ICPENDR + (n << 2)); 87df373737SAchin Gupta } 88df373737SAchin Gupta 89df373737SAchin Gupta /* 90df373737SAchin Gupta * Accessor to read the GIC Distributor ISACTIVER corresponding to the 91df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 92df373737SAchin Gupta */ 93df373737SAchin Gupta unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) 94df373737SAchin Gupta { 95df373737SAchin Gupta unsigned n = id >> ISACTIVER_SHIFT; 96df373737SAchin Gupta return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); 97df373737SAchin Gupta } 98df373737SAchin Gupta 99df373737SAchin Gupta /* 100df373737SAchin Gupta * Accessor to read the GIC Distributor ICACTIVER corresponding to the 101df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 102df373737SAchin Gupta */ 103df373737SAchin Gupta unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) 104df373737SAchin Gupta { 105df373737SAchin Gupta unsigned n = id >> ICACTIVER_SHIFT; 106df373737SAchin Gupta return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); 107df373737SAchin Gupta } 108df373737SAchin Gupta 109df373737SAchin Gupta /* 110df373737SAchin Gupta * Accessor to read the GIC Distributor IPRIORITYR corresponding to the 111df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 112df373737SAchin Gupta */ 113df373737SAchin Gupta unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) 114df373737SAchin Gupta { 115df373737SAchin Gupta unsigned n = id >> IPRIORITYR_SHIFT; 116df373737SAchin Gupta return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); 117df373737SAchin Gupta } 118df373737SAchin Gupta 119df373737SAchin Gupta /* 120df373737SAchin Gupta * Accessor to read the GIC Distributor ICGFR corresponding to the 121df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 122df373737SAchin Gupta */ 123df373737SAchin Gupta unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) 124df373737SAchin Gupta { 125df373737SAchin Gupta unsigned n = id >> ICFGR_SHIFT; 126df373737SAchin Gupta return mmio_read_32(base + GICD_ICFGR + (n << 2)); 127df373737SAchin Gupta } 128df373737SAchin Gupta 129df373737SAchin Gupta /* 130df373737SAchin Gupta * Accessor to read the GIC Distributor NSACR corresponding to the 131df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 132df373737SAchin Gupta */ 133df373737SAchin Gupta unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) 134df373737SAchin Gupta { 135df373737SAchin Gupta unsigned n = id >> NSACR_SHIFT; 136df373737SAchin Gupta return mmio_read_32(base + GICD_NSACR + (n << 2)); 137df373737SAchin Gupta } 138df373737SAchin Gupta 139df373737SAchin Gupta /******************************************************************************* 140df373737SAchin Gupta * GIC Distributor interface accessors for writing entire registers 141df373737SAchin Gupta ******************************************************************************/ 142df373737SAchin Gupta /* 143df373737SAchin Gupta * Accessor to write the GIC Distributor IGROUPR corresponding to the 144df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 145df373737SAchin Gupta */ 146df373737SAchin Gupta void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) 147df373737SAchin Gupta { 148df373737SAchin Gupta unsigned n = id >> IGROUPR_SHIFT; 149df373737SAchin Gupta mmio_write_32(base + GICD_IGROUPR + (n << 2), val); 150df373737SAchin Gupta } 151df373737SAchin Gupta 152df373737SAchin Gupta /* 153df373737SAchin Gupta * Accessor to write the GIC Distributor ISENABLER corresponding to the 154df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 155df373737SAchin Gupta */ 156df373737SAchin Gupta void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) 157df373737SAchin Gupta { 158df373737SAchin Gupta unsigned n = id >> ISENABLER_SHIFT; 159df373737SAchin Gupta mmio_write_32(base + GICD_ISENABLER + (n << 2), val); 160df373737SAchin Gupta } 161df373737SAchin Gupta 162df373737SAchin Gupta /* 163df373737SAchin Gupta * Accessor to write the GIC Distributor ICENABLER corresponding to the 164df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 165df373737SAchin Gupta */ 166df373737SAchin Gupta void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) 167df373737SAchin Gupta { 168df373737SAchin Gupta unsigned n = id >> ICENABLER_SHIFT; 169df373737SAchin Gupta mmio_write_32(base + GICD_ICENABLER + (n << 2), val); 170df373737SAchin Gupta } 171df373737SAchin Gupta 172df373737SAchin Gupta /* 173df373737SAchin Gupta * Accessor to write the GIC Distributor ISPENDR corresponding to the 174df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 175df373737SAchin Gupta */ 176df373737SAchin Gupta void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) 177df373737SAchin Gupta { 178df373737SAchin Gupta unsigned n = id >> ISPENDR_SHIFT; 179df373737SAchin Gupta mmio_write_32(base + GICD_ISPENDR + (n << 2), val); 180df373737SAchin Gupta } 181df373737SAchin Gupta 182df373737SAchin Gupta /* 183df373737SAchin Gupta * Accessor to write the GIC Distributor ICPENDR corresponding to the 184df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 185df373737SAchin Gupta */ 186df373737SAchin Gupta void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) 187df373737SAchin Gupta { 188df373737SAchin Gupta unsigned n = id >> ICPENDR_SHIFT; 189df373737SAchin Gupta mmio_write_32(base + GICD_ICPENDR + (n << 2), val); 190df373737SAchin Gupta } 191df373737SAchin Gupta 192df373737SAchin Gupta /* 193df373737SAchin Gupta * Accessor to write the GIC Distributor ISACTIVER corresponding to the 194df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 195df373737SAchin Gupta */ 196df373737SAchin Gupta void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) 197df373737SAchin Gupta { 198df373737SAchin Gupta unsigned n = id >> ISACTIVER_SHIFT; 199df373737SAchin Gupta mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); 200df373737SAchin Gupta } 201df373737SAchin Gupta 202df373737SAchin Gupta /* 203df373737SAchin Gupta * Accessor to write the GIC Distributor ICACTIVER corresponding to the 204df373737SAchin Gupta * interrupt `id`, 32 interrupt IDs at a time. 205df373737SAchin Gupta */ 206df373737SAchin Gupta void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) 207df373737SAchin Gupta { 208df373737SAchin Gupta unsigned n = id >> ICACTIVER_SHIFT; 209df373737SAchin Gupta mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); 210df373737SAchin Gupta } 211df373737SAchin Gupta 212df373737SAchin Gupta /* 213df373737SAchin Gupta * Accessor to write the GIC Distributor IPRIORITYR corresponding to the 214df373737SAchin Gupta * interrupt `id`, 4 interrupt IDs at a time. 215df373737SAchin Gupta */ 216df373737SAchin Gupta void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 217df373737SAchin Gupta { 218df373737SAchin Gupta unsigned n = id >> IPRIORITYR_SHIFT; 219df373737SAchin Gupta mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); 220df373737SAchin Gupta } 221df373737SAchin Gupta 222df373737SAchin Gupta /* 223df373737SAchin Gupta * Accessor to write the GIC Distributor ICFGR corresponding to the 224df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 225df373737SAchin Gupta */ 226df373737SAchin Gupta void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) 227df373737SAchin Gupta { 228df373737SAchin Gupta unsigned n = id >> ICFGR_SHIFT; 229df373737SAchin Gupta mmio_write_32(base + GICD_ICFGR + (n << 2), val); 230df373737SAchin Gupta } 231df373737SAchin Gupta 232df373737SAchin Gupta /* 233df373737SAchin Gupta * Accessor to write the GIC Distributor NSACR corresponding to the 234df373737SAchin Gupta * interrupt `id`, 16 interrupt IDs at a time. 235df373737SAchin Gupta */ 236df373737SAchin Gupta void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) 237df373737SAchin Gupta { 238df373737SAchin Gupta unsigned n = id >> NSACR_SHIFT; 239df373737SAchin Gupta mmio_write_32(base + GICD_NSACR + (n << 2), val); 240df373737SAchin Gupta } 241df373737SAchin Gupta 242df373737SAchin Gupta /******************************************************************************* 243*e9ec3cecSSoby Mathew * GIC Distributor functions for accessing the GIC registers 244*e9ec3cecSSoby Mathew * corresponding to a single interrupt ID. These functions use bitwise 245*e9ec3cecSSoby Mathew * operations or appropriate register accesses to modify or return 246*e9ec3cecSSoby Mathew * the bit-field corresponding the single interrupt ID. 247df373737SAchin Gupta ******************************************************************************/ 248df373737SAchin Gupta unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) 249df373737SAchin Gupta { 250df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 251df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 252df373737SAchin Gupta 253df373737SAchin Gupta return (reg_val >> bit_num) & 0x1; 254df373737SAchin Gupta } 255df373737SAchin Gupta 256df373737SAchin Gupta void gicd_set_igroupr(uintptr_t base, unsigned int id) 257df373737SAchin Gupta { 258df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 259df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 260df373737SAchin Gupta 261df373737SAchin Gupta gicd_write_igroupr(base, id, reg_val | (1 << bit_num)); 262df373737SAchin Gupta } 263df373737SAchin Gupta 264df373737SAchin Gupta void gicd_clr_igroupr(uintptr_t base, unsigned int id) 265df373737SAchin Gupta { 266df373737SAchin Gupta unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 267df373737SAchin Gupta unsigned int reg_val = gicd_read_igroupr(base, id); 268df373737SAchin Gupta 269df373737SAchin Gupta gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num)); 270df373737SAchin Gupta } 271df373737SAchin Gupta 272df373737SAchin Gupta void gicd_set_isenabler(uintptr_t base, unsigned int id) 273df373737SAchin Gupta { 274df373737SAchin Gupta unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); 275df373737SAchin Gupta 276df373737SAchin Gupta gicd_write_isenabler(base, id, (1 << bit_num)); 277df373737SAchin Gupta } 278df373737SAchin Gupta 279df373737SAchin Gupta void gicd_set_icenabler(uintptr_t base, unsigned int id) 280df373737SAchin Gupta { 281df373737SAchin Gupta unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); 282df373737SAchin Gupta 283df373737SAchin Gupta gicd_write_icenabler(base, id, (1 << bit_num)); 284df373737SAchin Gupta } 285df373737SAchin Gupta 286df373737SAchin Gupta void gicd_set_ispendr(uintptr_t base, unsigned int id) 287df373737SAchin Gupta { 288df373737SAchin Gupta unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); 289df373737SAchin Gupta 290df373737SAchin Gupta gicd_write_ispendr(base, id, (1 << bit_num)); 291df373737SAchin Gupta } 292df373737SAchin Gupta 293df373737SAchin Gupta void gicd_set_icpendr(uintptr_t base, unsigned int id) 294df373737SAchin Gupta { 295df373737SAchin Gupta unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); 296df373737SAchin Gupta 297df373737SAchin Gupta gicd_write_icpendr(base, id, (1 << bit_num)); 298df373737SAchin Gupta } 299df373737SAchin Gupta 300df373737SAchin Gupta void gicd_set_isactiver(uintptr_t base, unsigned int id) 301df373737SAchin Gupta { 302df373737SAchin Gupta unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); 303df373737SAchin Gupta 304df373737SAchin Gupta gicd_write_isactiver(base, id, (1 << bit_num)); 305df373737SAchin Gupta } 306df373737SAchin Gupta 307df373737SAchin Gupta void gicd_set_icactiver(uintptr_t base, unsigned int id) 308df373737SAchin Gupta { 309df373737SAchin Gupta unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1); 310df373737SAchin Gupta 311df373737SAchin Gupta gicd_write_icactiver(base, id, (1 << bit_num)); 312df373737SAchin Gupta } 31338a78614SSoby Mathew 31438a78614SSoby Mathew void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) 31538a78614SSoby Mathew { 31638a78614SSoby Mathew mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); 31738a78614SSoby Mathew } 318