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