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