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