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