xref: /rk3399_ARM-atf/drivers/arm/gic/v3/gicv3_helpers.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
1 /*
2  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <arch.h>
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <common/interrupt_props.h>
13 #include <drivers/arm/gic_common.h>
14 
15 #include "../common/gic_common_private.h"
16 #include "gicv3_private.h"
17 
18 /*
19  * Accessor to read the GIC Distributor IGRPMODR corresponding to the
20  * interrupt `id`, 32 interrupt IDs at a time.
21  */
22 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id)
23 {
24 	unsigned int n = id >> IGRPMODR_SHIFT;
25 
26 	return mmio_read_32(base + GICD_IGRPMODR + (n << 2));
27 }
28 
29 /*
30  * Accessor to write the GIC Distributor IGRPMODR corresponding to the
31  * interrupt `id`, 32 interrupt IDs at a time.
32  */
33 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val)
34 {
35 	unsigned int n = id >> IGRPMODR_SHIFT;
36 
37 	mmio_write_32(base + GICD_IGRPMODR + (n << 2), val);
38 }
39 
40 /*
41  * Accessor to get the bit corresponding to interrupt ID
42  * in GIC Distributor IGRPMODR.
43  */
44 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
45 {
46 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
47 	unsigned int reg_val = gicd_read_igrpmodr(base, id);
48 
49 	return (reg_val >> bit_num) & 0x1U;
50 }
51 
52 /*
53  * Accessor to set the bit corresponding to interrupt ID
54  * in GIC Distributor IGRPMODR.
55  */
56 void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
57 {
58 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
59 	unsigned int reg_val = gicd_read_igrpmodr(base, id);
60 
61 	gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num));
62 }
63 
64 /*
65  * Accessor to clear the bit corresponding to interrupt ID
66  * in GIC Distributor IGRPMODR.
67  */
68 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
69 {
70 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
71 	unsigned int reg_val = gicd_read_igrpmodr(base, id);
72 
73 	gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num));
74 }
75 
76 /*
77  * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the
78  * interrupt `id`, 4 interrupts IDs at a time.
79  */
80 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
81 {
82 	unsigned int n = id >> IPRIORITYR_SHIFT;
83 
84 	return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
85 }
86 
87 /*
88  * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the
89  * interrupt `id`, 4 interrupts IDs at a time.
90  */
91 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
92 {
93 	unsigned int n = id >> IPRIORITYR_SHIFT;
94 
95 	mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
96 }
97 
98 /*
99  * Accessor to get the bit corresponding to interrupt ID
100  * from GIC Re-distributor IGROUPR0.
101  */
102 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
103 {
104 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
105 	unsigned int reg_val = gicr_read_igroupr0(base);
106 
107 	return (reg_val >> bit_num) & 0x1U;
108 }
109 
110 /*
111  * Accessor to set the bit corresponding to interrupt ID
112  * in GIC Re-distributor IGROUPR0.
113  */
114 void gicr_set_igroupr0(uintptr_t base, unsigned int id)
115 {
116 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
117 	unsigned int reg_val = gicr_read_igroupr0(base);
118 
119 	gicr_write_igroupr0(base, reg_val | (1U << bit_num));
120 }
121 
122 /*
123  * Accessor to clear the bit corresponding to interrupt ID
124  * in GIC Re-distributor IGROUPR0.
125  */
126 void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
127 {
128 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
129 	unsigned int reg_val = gicr_read_igroupr0(base);
130 
131 	gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
132 }
133 
134 /*
135  * Accessor to get the bit corresponding to interrupt ID
136  * from GIC Re-distributor IGRPMODR0.
137  */
138 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
139 {
140 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
141 	unsigned int reg_val = gicr_read_igrpmodr0(base);
142 
143 	return (reg_val >> bit_num) & 0x1U;
144 }
145 
146 /*
147  * Accessor to set the bit corresponding to interrupt ID
148  * in GIC Re-distributor IGRPMODR0.
149  */
150 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
151 {
152 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
153 	unsigned int reg_val = gicr_read_igrpmodr0(base);
154 
155 	gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
156 }
157 
158 /*
159  * Accessor to clear the bit corresponding to interrupt ID
160  * in GIC Re-distributor IGRPMODR0.
161  */
162 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
163 {
164 	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
165 	unsigned int reg_val = gicr_read_igrpmodr0(base);
166 
167 	gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
168 }
169 
170 /*
171  * Accessor to set the bit corresponding to interrupt ID
172  * in GIC Re-distributor ISENABLER0.
173  */
174 void gicr_set_isenabler0(uintptr_t base, unsigned int id)
175 {
176 	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
177 
178 	gicr_write_isenabler0(base, (1U << bit_num));
179 }
180 
181 /*
182  * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
183  * ICENABLER0.
184  */
185 void gicr_set_icenabler0(uintptr_t base, unsigned int id)
186 {
187 	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
188 
189 	gicr_write_icenabler0(base, (1U << bit_num));
190 }
191 
192 /*
193  * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
194  * ISACTIVER0.
195  */
196 unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
197 {
198 	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
199 	unsigned int reg_val = gicr_read_isactiver0(base);
200 
201 	return (reg_val >> bit_num) & 0x1U;
202 }
203 
204 /*
205  * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor
206  * ICPENDRR0.
207  */
208 void gicr_set_icpendr0(uintptr_t base, unsigned int id)
209 {
210 	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
211 
212 	gicr_write_icpendr0(base, (1U << bit_num));
213 }
214 
215 /*
216  * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
217  * ISPENDR0.
218  */
219 void gicr_set_ispendr0(uintptr_t base, unsigned int id)
220 {
221 	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
222 
223 	gicr_write_ispendr0(base, (1U << bit_num));
224 }
225 
226 /*
227  * Accessor to set the byte corresponding to interrupt ID
228  * in GIC Re-distributor IPRIORITYR.
229  */
230 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
231 {
232 	uint8_t val = pri & GIC_PRI_MASK;
233 
234 	mmio_write_8(base + GICR_IPRIORITYR + id, val);
235 }
236 
237 /*
238  * Accessor to set the bit fields corresponding to interrupt ID
239  * in GIC Re-distributor ICFGR0.
240  */
241 void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
242 {
243 	/* Interrupt configuration is a 2-bit field */
244 	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
245 	unsigned int bit_shift = bit_num << 1U;
246 
247 	uint32_t reg_val = gicr_read_icfgr0(base);
248 
249 	/* Clear the field, and insert required configuration */
250 	reg_val &= ~(GIC_CFG_MASK << bit_shift);
251 	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
252 
253 	gicr_write_icfgr0(base, reg_val);
254 }
255 
256 /*
257  * Accessor to set the bit fields corresponding to interrupt ID
258  * in GIC Re-distributor ICFGR1.
259  */
260 void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
261 {
262 	/* Interrupt configuration is a 2-bit field */
263 	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
264 	unsigned int bit_shift = bit_num << 1U;
265 
266 	uint32_t reg_val = gicr_read_icfgr1(base);
267 
268 	/* Clear the field, and insert required configuration */
269 	reg_val &= ~(GIC_CFG_MASK << bit_shift);
270 	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
271 
272 	gicr_write_icfgr1(base, reg_val);
273 }
274 
275 /******************************************************************************
276  * This function marks the core as awake in the re-distributor and
277  * ensures that the interface is active.
278  *****************************************************************************/
279 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base)
280 {
281 	/*
282 	 * The WAKER_PS_BIT should be changed to 0
283 	 * only when WAKER_CA_BIT is 1.
284 	 */
285 	assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U);
286 
287 	/* Mark the connected core as awake */
288 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT);
289 
290 	/* Wait till the WAKER_CA_BIT changes to 0 */
291 	while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U)
292 		;
293 }
294 
295 
296 /******************************************************************************
297  * This function marks the core as asleep in the re-distributor and ensures
298  * that the interface is quiescent.
299  *****************************************************************************/
300 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base)
301 {
302 	/* Mark the connected core as asleep */
303 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT);
304 
305 	/* Wait till the WAKER_CA_BIT changes to 1 */
306 	while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U)
307 		;
308 }
309 
310 
311 /*******************************************************************************
312  * This function probes the Redistributor frames when the driver is initialised
313  * and saves their base addresses. These base addresses are used later to
314  * initialise each Redistributor interface.
315  ******************************************************************************/
316 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
317 					unsigned int rdistif_num,
318 					uintptr_t gicr_base,
319 					mpidr_hash_fn mpidr_to_core_pos)
320 {
321 	u_register_t mpidr;
322 	unsigned int proc_num;
323 	uint64_t typer_val;
324 	uintptr_t rdistif_base = gicr_base;
325 
326 	assert(rdistif_base_addrs != NULL);
327 
328 	/*
329 	 * Iterate over the Redistributor frames. Store the base address of each
330 	 * frame in the platform provided array. Use the "Processor Number"
331 	 * field to index into the array if the platform has not provided a hash
332 	 * function to convert an MPIDR (obtained from the "Affinity Value"
333 	 * field into a linear index.
334 	 */
335 	do {
336 		typer_val = gicr_read_typer(rdistif_base);
337 		if (mpidr_to_core_pos != NULL) {
338 			mpidr = mpidr_from_gicr_typer(typer_val);
339 			proc_num = mpidr_to_core_pos(mpidr);
340 		} else {
341 			proc_num = (typer_val >> TYPER_PROC_NUM_SHIFT) &
342 				TYPER_PROC_NUM_MASK;
343 		}
344 		assert(proc_num < rdistif_num);
345 		rdistif_base_addrs[proc_num] = rdistif_base;
346 		rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
347 	} while ((typer_val & TYPER_LAST_BIT) == 0U);
348 }
349 
350 /*******************************************************************************
351  * Helper function to configure the default attributes of SPIs.
352  ******************************************************************************/
353 void gicv3_spis_config_defaults(uintptr_t gicd_base)
354 {
355 	unsigned int index, num_ints;
356 
357 	num_ints = gicd_read_typer(gicd_base);
358 	num_ints &= TYPER_IT_LINES_NO_MASK;
359 	num_ints = (num_ints + 1U) << 5;
360 
361 	/*
362 	 * Treat all SPIs as G1NS by default. The number of interrupts is
363 	 * calculated as 32 * (IT_LINES + 1). We do 32 at a time.
364 	 */
365 	for (index = MIN_SPI_ID; index < num_ints; index += 32U)
366 		gicd_write_igroupr(gicd_base, index, ~0U);
367 
368 	/* Setup the default SPI priorities doing four at a time */
369 	for (index = MIN_SPI_ID; index < num_ints; index += 4U)
370 		gicd_write_ipriorityr(gicd_base,
371 				      index,
372 				      GICD_IPRIORITYR_DEF_VAL);
373 
374 	/*
375 	 * Treat all SPIs as level triggered by default, write 16 at
376 	 * a time
377 	 */
378 	for (index = MIN_SPI_ID; index < num_ints; index += 16U)
379 		gicd_write_icfgr(gicd_base, index, 0U);
380 }
381 
382 /*******************************************************************************
383  * Helper function to configure properties of secure SPIs
384  ******************************************************************************/
385 unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
386 		const interrupt_prop_t *interrupt_props,
387 		unsigned int interrupt_props_num)
388 {
389 	unsigned int i;
390 	const interrupt_prop_t *current_prop;
391 	unsigned long long gic_affinity_val;
392 	unsigned int ctlr_enable = 0U;
393 
394 	/* Make sure there's a valid property array */
395 	if (interrupt_props_num > 0U)
396 		assert(interrupt_props != NULL);
397 
398 	for (i = 0U; i < interrupt_props_num; i++) {
399 		current_prop = &interrupt_props[i];
400 
401 		if (current_prop->intr_num < MIN_SPI_ID)
402 			continue;
403 
404 		/* Configure this interrupt as a secure interrupt */
405 		gicd_clr_igroupr(gicd_base, current_prop->intr_num);
406 
407 		/* Configure this interrupt as G0 or a G1S interrupt */
408 		assert((current_prop->intr_grp == INTR_GROUP0) ||
409 				(current_prop->intr_grp == INTR_GROUP1S));
410 		if (current_prop->intr_grp == INTR_GROUP1S) {
411 			gicd_set_igrpmodr(gicd_base, current_prop->intr_num);
412 			ctlr_enable |= CTLR_ENABLE_G1S_BIT;
413 		} else {
414 			gicd_clr_igrpmodr(gicd_base, current_prop->intr_num);
415 			ctlr_enable |= CTLR_ENABLE_G0_BIT;
416 		}
417 
418 		/* Set interrupt configuration */
419 		gicd_set_icfgr(gicd_base, current_prop->intr_num,
420 				current_prop->intr_cfg);
421 
422 		/* Set the priority of this interrupt */
423 		gicd_set_ipriorityr(gicd_base, current_prop->intr_num,
424 				current_prop->intr_pri);
425 
426 		/* Target SPIs to the primary CPU */
427 		gic_affinity_val =
428 			gicd_irouter_val_from_mpidr(read_mpidr(), 0U);
429 		gicd_write_irouter(gicd_base, current_prop->intr_num,
430 				gic_affinity_val);
431 
432 		/* Enable this interrupt */
433 		gicd_set_isenabler(gicd_base, current_prop->intr_num);
434 	}
435 
436 	return ctlr_enable;
437 }
438 
439 /*******************************************************************************
440  * Helper function to configure the default attributes of SPIs.
441  ******************************************************************************/
442 void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base)
443 {
444 	unsigned int index;
445 
446 	/*
447 	 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a
448 	 * more scalable approach as it avoids clearing the enable bits in the
449 	 * GICD_CTLR
450 	 */
451 	gicr_write_icenabler0(gicr_base, ~0U);
452 	gicr_wait_for_pending_write(gicr_base);
453 
454 	/* Treat all SGIs/PPIs as G1NS by default. */
455 	gicr_write_igroupr0(gicr_base, ~0U);
456 
457 	/* Setup the default PPI/SGI priorities doing four at a time */
458 	for (index = 0U; index < MIN_SPI_ID; index += 4U)
459 		gicr_write_ipriorityr(gicr_base,
460 				      index,
461 				      GICD_IPRIORITYR_DEF_VAL);
462 
463 	/* Configure all PPIs as level triggered by default */
464 	gicr_write_icfgr1(gicr_base, 0U);
465 }
466 
467 /*******************************************************************************
468  * Helper function to configure properties of secure G0 and G1S PPIs and SGIs.
469  ******************************************************************************/
470 unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
471 		const interrupt_prop_t *interrupt_props,
472 		unsigned int interrupt_props_num)
473 {
474 	unsigned int i;
475 	const interrupt_prop_t *current_prop;
476 	unsigned int ctlr_enable = 0U;
477 
478 	/* Make sure there's a valid property array */
479 	if (interrupt_props_num > 0U)
480 		assert(interrupt_props != NULL);
481 
482 	for (i = 0U; i < interrupt_props_num; i++) {
483 		current_prop = &interrupt_props[i];
484 
485 		if (current_prop->intr_num >= MIN_SPI_ID)
486 			continue;
487 
488 		/* Configure this interrupt as a secure interrupt */
489 		gicr_clr_igroupr0(gicr_base, current_prop->intr_num);
490 
491 		/* Configure this interrupt as G0 or a G1S interrupt */
492 		assert((current_prop->intr_grp == INTR_GROUP0) ||
493 				(current_prop->intr_grp == INTR_GROUP1S));
494 		if (current_prop->intr_grp == INTR_GROUP1S) {
495 			gicr_set_igrpmodr0(gicr_base, current_prop->intr_num);
496 			ctlr_enable |= CTLR_ENABLE_G1S_BIT;
497 		} else {
498 			gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num);
499 			ctlr_enable |= CTLR_ENABLE_G0_BIT;
500 		}
501 
502 		/* Set the priority of this interrupt */
503 		gicr_set_ipriorityr(gicr_base, current_prop->intr_num,
504 				current_prop->intr_pri);
505 
506 		/*
507 		 * Set interrupt configuration for PPIs. Configuration for SGIs
508 		 * are ignored.
509 		 */
510 		if ((current_prop->intr_num >= MIN_PPI_ID) &&
511 				(current_prop->intr_num < MIN_SPI_ID)) {
512 			gicr_set_icfgr1(gicr_base, current_prop->intr_num,
513 					current_prop->intr_cfg);
514 		}
515 
516 		/* Enable this interrupt */
517 		gicr_set_isenabler0(gicr_base, current_prop->intr_num);
518 	}
519 
520 	return ctlr_enable;
521 }
522