Home | History | Annotate | Download | only in v3
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #ifndef __GICV3_PRIVATE_H__
      8 #define __GICV3_PRIVATE_H__
      9 
     10 #include <assert.h>
     11 #include <gic_common.h>
     12 #include <gicv3.h>
     13 #include <mmio.h>
     14 #include <stdint.h>
     15 #include "../common/gic_common_private.h"
     16 
     17 /*******************************************************************************
     18  * GICv3 private macro definitions
     19  ******************************************************************************/
     20 
     21 /* Constants to indicate the status of the RWP bit */
     22 #define RWP_TRUE		1
     23 #define RWP_FALSE		0
     24 
     25 /*
     26  * Macro to convert an mpidr to a value suitable for programming into a
     27  * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
     28  * to GICv3.
     29  */
     30 #define gicd_irouter_val_from_mpidr(mpidr, irm)		\
     31 	((mpidr & ~(0xff << 24)) |			\
     32 	 (irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT)
     33 
     34 /*
     35  * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
     36  * are zeroes.
     37  */
     38 #ifdef AARCH32
     39 #define mpidr_from_gicr_typer(typer_val)	(((typer_val) >> 32) & 0xffffff)
     40 #else
     41 #define mpidr_from_gicr_typer(typer_val)				 \
     42 	(((((typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \
     43 	 (((typer_val) >> 32) & 0xffffff))
     44 #endif
     45 
     46 /*******************************************************************************
     47  * GICv3 private global variables declarations
     48  ******************************************************************************/
     49 extern const gicv3_driver_data_t *gicv3_driver_data;
     50 
     51 /*******************************************************************************
     52  * Private GICv3 function prototypes for accessing entire registers.
     53  * Note: The raw register values correspond to multiple interrupt IDs and
     54  * the number of interrupt IDs involved depends on the register accessed.
     55  ******************************************************************************/
     56 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id);
     57 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id);
     58 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val);
     59 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
     60 
     61 /*******************************************************************************
     62  * Private GICv3 function prototypes for accessing the GIC registers
     63  * corresponding to a single interrupt ID. These functions use bitwise
     64  * operations or appropriate register accesses to modify or return
     65  * the bit-field corresponding the single interrupt ID.
     66  ******************************************************************************/
     67 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
     68 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id);
     69 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id);
     70 unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id);
     71 void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
     72 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id);
     73 void gicr_set_isenabler0(uintptr_t base, unsigned int id);
     74 void gicr_set_icenabler0(uintptr_t base, unsigned int id);
     75 void gicr_set_ispendr0(uintptr_t base, unsigned int id);
     76 void gicr_set_icpendr0(uintptr_t base, unsigned int id);
     77 void gicr_set_igroupr0(uintptr_t base, unsigned int id);
     78 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id);
     79 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id);
     80 void gicr_clr_igroupr0(uintptr_t base, unsigned int id);
     81 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
     82 
     83 /*******************************************************************************
     84  * Private GICv3 helper function prototypes
     85  ******************************************************************************/
     86 void gicv3_spis_configure_defaults(uintptr_t gicd_base);
     87 void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base);
     88 #if !ERROR_DEPRECATED
     89 void gicv3_secure_spis_configure(uintptr_t gicd_base,
     90 				     unsigned int num_ints,
     91 				     const unsigned int *sec_intr_list,
     92 				     unsigned int int_grp);
     93 void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
     94 					unsigned int num_ints,
     95 					const unsigned int *sec_intr_list,
     96 					unsigned int int_grp);
     97 #endif
     98 void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
     99 		const interrupt_prop_t *interrupt_props,
    100 		unsigned int interrupt_props_num);
    101 unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base,
    102 		const interrupt_prop_t *interrupt_props,
    103 		unsigned int interrupt_props_num);
    104 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
    105 					unsigned int rdistif_num,
    106 					uintptr_t gicr_base,
    107 					mpidr_hash_fn mpidr_to_core_pos);
    108 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base);
    109 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base);
    110 
    111 /*******************************************************************************
    112  * GIC Distributor interface accessors
    113  ******************************************************************************/
    114 /*
    115  * Wait for updates to :
    116  * GICD_CTLR[2:0] - the Group Enables
    117  * GICD_CTLR[5:4] - the ARE bits
    118  * GICD_ICENABLERn - the clearing of enable state for SPIs
    119  */
    120 static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
    121 {
    122 	while (gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT)
    123 		;
    124 }
    125 
    126 static inline unsigned int gicd_read_pidr2(uintptr_t base)
    127 {
    128 	return mmio_read_32(base + GICD_PIDR2_GICV3);
    129 }
    130 
    131 static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id)
    132 {
    133 	assert(id >= MIN_SPI_ID);
    134 	return mmio_read_64(base + GICD_IROUTER + (id << 3));
    135 }
    136 
    137 static inline void gicd_write_irouter(uintptr_t base,
    138 				      unsigned int id,
    139 				      unsigned long long affinity)
    140 {
    141 	assert(id >= MIN_SPI_ID);
    142 	mmio_write_64(base + GICD_IROUTER + (id << 3), affinity);
    143 }
    144 
    145 static inline void gicd_clr_ctlr(uintptr_t base,
    146 				 unsigned int bitmap,
    147 				 unsigned int rwp)
    148 {
    149 	gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
    150 	if (rwp)
    151 		gicd_wait_for_pending_write(base);
    152 }
    153 
    154 static inline void gicd_set_ctlr(uintptr_t base,
    155 				 unsigned int bitmap,
    156 				 unsigned int rwp)
    157 {
    158 	gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
    159 	if (rwp)
    160 		gicd_wait_for_pending_write(base);
    161 }
    162 
    163 /*******************************************************************************
    164  * GIC Redistributor interface accessors
    165  ******************************************************************************/
    166 static inline unsigned long long gicr_read_ctlr(uintptr_t base)
    167 {
    168 	return mmio_read_64(base + GICR_CTLR);
    169 }
    170 
    171 static inline void gicr_write_ctlr(uintptr_t base, uint64_t val)
    172 {
    173 	mmio_write_64(base + GICR_CTLR, val);
    174 }
    175 
    176 static inline unsigned long long gicr_read_typer(uintptr_t base)
    177 {
    178 	return mmio_read_64(base + GICR_TYPER);
    179 }
    180 
    181 static inline unsigned int gicr_read_waker(uintptr_t base)
    182 {
    183 	return mmio_read_32(base + GICR_WAKER);
    184 }
    185 
    186 static inline void gicr_write_waker(uintptr_t base, unsigned int val)
    187 {
    188 	mmio_write_32(base + GICR_WAKER, val);
    189 }
    190 
    191 /*
    192  * Wait for updates to :
    193  * GICR_ICENABLER0
    194  * GICR_CTLR.DPG1S
    195  * GICR_CTLR.DPG1NS
    196  * GICR_CTLR.DPG0
    197  */
    198 static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
    199 {
    200 	while (gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT)
    201 		;
    202 }
    203 
    204 static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
    205 {
    206 	while (gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT)
    207 		;
    208 }
    209 
    210 /* Private implementation of Distributor power control hooks */
    211 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num);
    212 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
    213 
    214 /*******************************************************************************
    215  * GIC Re-distributor functions for accessing entire registers.
    216  * Note: The raw register values correspond to multiple interrupt IDs and
    217  * the number of interrupt IDs involved depends on the register accessed.
    218  ******************************************************************************/
    219 static inline unsigned int gicr_read_icenabler0(uintptr_t base)
    220 {
    221 	return mmio_read_32(base + GICR_ICENABLER0);
    222 }
    223 
    224 static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val)
    225 {
    226 	mmio_write_32(base + GICR_ICENABLER0, val);
    227 }
    228 
    229 static inline unsigned int gicr_read_isenabler0(uintptr_t base)
    230 {
    231 	return mmio_read_32(base + GICR_ISENABLER0);
    232 }
    233 
    234 static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val)
    235 {
    236 	mmio_write_32(base + GICR_ICPENDR0, val);
    237 }
    238 
    239 static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val)
    240 {
    241 	mmio_write_32(base + GICR_ISENABLER0, val);
    242 }
    243 
    244 static inline unsigned int gicr_read_igroupr0(uintptr_t base)
    245 {
    246 	return mmio_read_32(base + GICR_IGROUPR0);
    247 }
    248 
    249 static inline unsigned int gicr_read_ispendr0(uintptr_t base)
    250 {
    251 	return mmio_read_32(base + GICR_ISPENDR0);
    252 }
    253 
    254 static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val)
    255 {
    256 	mmio_write_32(base + GICR_ISPENDR0, val);
    257 }
    258 
    259 static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val)
    260 {
    261 	mmio_write_32(base + GICR_IGROUPR0, val);
    262 }
    263 
    264 static inline unsigned int gicr_read_igrpmodr0(uintptr_t base)
    265 {
    266 	return mmio_read_32(base + GICR_IGRPMODR0);
    267 }
    268 
    269 static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val)
    270 {
    271 	mmio_write_32(base + GICR_IGRPMODR0, val);
    272 }
    273 
    274 static inline unsigned int gicr_read_nsacr(uintptr_t base)
    275 {
    276 	return mmio_read_32(base + GICR_NSACR);
    277 }
    278 
    279 static inline void gicr_write_nsacr(uintptr_t base, unsigned int val)
    280 {
    281 	mmio_write_32(base + GICR_NSACR, val);
    282 }
    283 
    284 static inline unsigned int gicr_read_isactiver0(uintptr_t base)
    285 {
    286 	return mmio_read_32(base + GICR_ISACTIVER0);
    287 }
    288 
    289 static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val)
    290 {
    291 	mmio_write_32(base + GICR_ISACTIVER0, val);
    292 }
    293 
    294 static inline unsigned int gicr_read_icfgr0(uintptr_t base)
    295 {
    296 	return mmio_read_32(base + GICR_ICFGR0);
    297 }
    298 
    299 static inline unsigned int gicr_read_icfgr1(uintptr_t base)
    300 {
    301 	return mmio_read_32(base + GICR_ICFGR1);
    302 }
    303 
    304 static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val)
    305 {
    306 	mmio_write_32(base + GICR_ICFGR0, val);
    307 }
    308 
    309 static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val)
    310 {
    311 	mmio_write_32(base + GICR_ICFGR1, val);
    312 }
    313 
    314 static inline unsigned int gicr_read_propbaser(uintptr_t base)
    315 {
    316 	return mmio_read_32(base + GICR_PROPBASER);
    317 }
    318 
    319 static inline void gicr_write_propbaser(uintptr_t base, unsigned int val)
    320 {
    321 	mmio_write_32(base + GICR_PROPBASER, val);
    322 }
    323 
    324 static inline unsigned int gicr_read_pendbaser(uintptr_t base)
    325 {
    326 	return mmio_read_32(base + GICR_PENDBASER);
    327 }
    328 
    329 static inline void gicr_write_pendbaser(uintptr_t base, unsigned int val)
    330 {
    331 	mmio_write_32(base + GICR_PENDBASER, val);
    332 }
    333 
    334 /*******************************************************************************
    335  * GIC ITS functions to read and write entire ITS registers.
    336  ******************************************************************************/
    337 static inline uint32_t gits_read_ctlr(uintptr_t base)
    338 {
    339 	return mmio_read_32(base + GITS_CTLR);
    340 }
    341 
    342 static inline void gits_write_ctlr(uintptr_t base, unsigned int val)
    343 {
    344 	mmio_write_32(base + GITS_CTLR, val);
    345 }
    346 
    347 static inline uint64_t gits_read_cbaser(uintptr_t base)
    348 {
    349 	return mmio_read_64(base + GITS_CBASER);
    350 }
    351 
    352 static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
    353 {
    354 	mmio_write_32(base + GITS_CBASER, val);
    355 }
    356 
    357 static inline uint64_t gits_read_cwriter(uintptr_t base)
    358 {
    359 	return mmio_read_64(base + GITS_CWRITER);
    360 }
    361 
    362 static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
    363 {
    364 	mmio_write_32(base + GITS_CWRITER, val);
    365 }
    366 
    367 static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id)
    368 {
    369 	assert(its_table_id < 8);
    370 	return mmio_read_64(base + GITS_BASER + (8 * its_table_id));
    371 }
    372 
    373 static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val)
    374 {
    375 	assert(its_table_id < 8);
    376 	mmio_write_64(base + GITS_BASER + (8 * its_table_id), val);
    377 }
    378 
    379 /*
    380  * Wait for Quiescent bit when GIC ITS is disabled
    381  */
    382 static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
    383 {
    384 	assert(!(gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT));
    385 	while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0)
    386 		;
    387 }
    388 
    389 
    390 #endif /* __GICV3_PRIVATE_H__ */
    391