xref: /rk3399_ARM-atf/drivers/arm/gic/v2/gicv2_main.c (revision e67606cf8e023de469c011ecb2a18a06d48a66a4)
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 <arch.h>
8 #include <arch_helpers.h>
9 #include <assert.h>
10 #include <debug.h>
11 #include <gic_common.h>
12 #include <gicv2.h>
13 #include <interrupt_props.h>
14 #include <spinlock.h>
15 #include <stdbool.h>
16 
17 #include "../common/gic_common_private.h"
18 #include "gicv2_private.h"
19 
20 static const gicv2_driver_data_t *driver_data;
21 
22 /*
23  * Spinlock to guard registers needing read-modify-write. APIs protected by this
24  * spinlock are used either at boot time (when only a single CPU is active), or
25  * when the system is fully coherent.
26  */
27 static spinlock_t gic_lock;
28 
29 /*******************************************************************************
30  * Enable secure interrupts and use FIQs to route them. Disable legacy bypass
31  * and set the priority mask register to allow all interrupts to trickle in.
32  ******************************************************************************/
33 void gicv2_cpuif_enable(void)
34 {
35 	unsigned int val;
36 
37 	assert(driver_data != NULL);
38 	assert(driver_data->gicc_base != 0U);
39 
40 	/*
41 	 * Enable the Group 0 interrupts, FIQEn and disable Group 0/1
42 	 * bypass.
43 	 */
44 	val = CTLR_ENABLE_G0_BIT | FIQ_EN_BIT | FIQ_BYP_DIS_GRP0;
45 	val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
46 
47 	/* Program the idle priority in the PMR */
48 	gicc_write_pmr(driver_data->gicc_base, GIC_PRI_MASK);
49 	gicc_write_ctlr(driver_data->gicc_base, val);
50 }
51 
52 /*******************************************************************************
53  * Place the cpu interface in a state where it can never make a cpu exit wfi as
54  * as result of an asserted interrupt. This is critical for powering down a cpu
55  ******************************************************************************/
56 void gicv2_cpuif_disable(void)
57 {
58 	unsigned int val;
59 
60 	assert(driver_data != NULL);
61 	assert(driver_data->gicc_base != 0U);
62 
63 	/* Disable secure, non-secure interrupts and disable their bypass */
64 	val = gicc_read_ctlr(driver_data->gicc_base);
65 	val &= ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT);
66 	val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
67 	val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
68 	gicc_write_ctlr(driver_data->gicc_base, val);
69 }
70 
71 /*******************************************************************************
72  * Per cpu gic distributor setup which will be done by all cpus after a cold
73  * boot/hotplug. This marks out the secure SPIs and PPIs & enables them.
74  ******************************************************************************/
75 void gicv2_pcpu_distif_init(void)
76 {
77 	unsigned int ctlr;
78 
79 	assert(driver_data != NULL);
80 	assert(driver_data->gicd_base != 0U);
81 
82 #if !ERROR_DEPRECATED
83 	if (driver_data->interrupt_props != NULL) {
84 #endif
85 		gicv2_secure_ppi_sgi_setup_props(driver_data->gicd_base,
86 				driver_data->interrupt_props,
87 				driver_data->interrupt_props_num);
88 #if !ERROR_DEPRECATED
89 	} else {
90 		/*
91 		 * Suppress deprecated declaration warnings in compatibility
92 		 * function
93 		 */
94 #pragma GCC diagnostic push
95 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
96 		assert(driver_data->g0_interrupt_array);
97 		gicv2_secure_ppi_sgi_setup(driver_data->gicd_base,
98 				driver_data->g0_interrupt_num,
99 				driver_data->g0_interrupt_array);
100 #pragma GCC diagnostic pop
101 	}
102 #endif
103 
104 	/* Enable G0 interrupts if not already */
105 	ctlr = gicd_read_ctlr(driver_data->gicd_base);
106 	if ((ctlr & CTLR_ENABLE_G0_BIT) == 0U) {
107 		gicd_write_ctlr(driver_data->gicd_base,
108 				ctlr | CTLR_ENABLE_G0_BIT);
109 	}
110 }
111 
112 /*******************************************************************************
113  * Global gic distributor init which will be done by the primary cpu after a
114  * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
115  * then enables the secure GIC distributor interface.
116  ******************************************************************************/
117 void gicv2_distif_init(void)
118 {
119 	unsigned int ctlr;
120 
121 	assert(driver_data != NULL);
122 	assert(driver_data->gicd_base != 0U);
123 
124 	/* Disable the distributor before going further */
125 	ctlr = gicd_read_ctlr(driver_data->gicd_base);
126 	gicd_write_ctlr(driver_data->gicd_base,
127 			ctlr & ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT));
128 
129 	/* Set the default attribute of all SPIs */
130 	gicv2_spis_configure_defaults(driver_data->gicd_base);
131 
132 #if !ERROR_DEPRECATED
133 	if (driver_data->interrupt_props != NULL) {
134 #endif
135 		gicv2_secure_spis_configure_props(driver_data->gicd_base,
136 				driver_data->interrupt_props,
137 				driver_data->interrupt_props_num);
138 #if !ERROR_DEPRECATED
139 	} else {
140 		/*
141 		 * Suppress deprecated declaration warnings in compatibility
142 		 * function
143 		 */
144 #pragma GCC diagnostic push
145 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
146 
147 		assert(driver_data->g0_interrupt_array);
148 
149 		/* Configure the G0 SPIs */
150 		gicv2_secure_spis_configure(driver_data->gicd_base,
151 				driver_data->g0_interrupt_num,
152 				driver_data->g0_interrupt_array);
153 #pragma GCC diagnostic pop
154 	}
155 #endif
156 
157 	/* Re-enable the secure SPIs now that they have been configured */
158 	gicd_write_ctlr(driver_data->gicd_base, ctlr | CTLR_ENABLE_G0_BIT);
159 }
160 
161 /*******************************************************************************
162  * Initialize the ARM GICv2 driver with the provided platform inputs
163  ******************************************************************************/
164 void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data)
165 {
166 	unsigned int gic_version;
167 
168 	assert(plat_driver_data != NULL);
169 	assert(plat_driver_data->gicd_base != 0U);
170 	assert(plat_driver_data->gicc_base != 0U);
171 
172 #if !ERROR_DEPRECATED
173 	if (plat_driver_data->interrupt_props == NULL) {
174 		/* Interrupt properties array size must be 0 */
175 		assert(plat_driver_data->interrupt_props_num == 0);
176 
177 		/*
178 		 * Suppress deprecated declaration warnings in compatibility
179 		 * function
180 		 */
181 #pragma GCC diagnostic push
182 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
183 
184 		/*
185 		 * If there are no interrupts of a particular type, then the
186 		 * number of interrupts of that type should be 0 and vice-versa.
187 		 */
188 		assert(plat_driver_data->g0_interrupt_array ?
189 				plat_driver_data->g0_interrupt_num :
190 				plat_driver_data->g0_interrupt_num == 0);
191 #pragma GCC diagnostic pop
192 
193 		WARN("Using deprecated integer interrupt array in "
194 		     "gicv2_driver_data_t\n");
195 		WARN("Please migrate to using an interrupt_prop_t array\n");
196 	}
197 #else
198 	assert(plat_driver_data->interrupt_props_num > 0 ?
199 			plat_driver_data->interrupt_props != NULL : 1);
200 #endif
201 
202 	/* Ensure that this is a GICv2 system */
203 	gic_version = gicd_read_pidr2(plat_driver_data->gicd_base);
204 	gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT)
205 					& PIDR2_ARCH_REV_MASK;
206 
207 	/*
208 	 * GICv1 with security extension complies with trusted firmware
209 	 * GICv2 driver as far as virtualization and few tricky power
210 	 * features are not used. GICv2 features that are not supported
211 	 * by GICv1 with Security Extensions are:
212 	 * - virtual interrupt support.
213 	 * - wake up events.
214 	 * - writeable GIC state register (for power sequences)
215 	 * - interrupt priority drop.
216 	 * - interrupt signal bypass.
217 	 */
218 	assert((gic_version == ARCH_REV_GICV2) ||
219 	       (gic_version == ARCH_REV_GICV1));
220 
221 	driver_data = plat_driver_data;
222 
223 	/*
224 	 * The GIC driver data is initialized by the primary CPU with caches
225 	 * enabled. When the secondary CPU boots up, it initializes the
226 	 * GICC/GICR interface with the caches disabled. Hence flush the
227 	 * driver_data to ensure coherency. This is not required if the
228 	 * platform has HW_ASSISTED_COHERENCY or WARMBOOT_ENABLE_DCACHE_EARLY
229 	 * enabled.
230 	 */
231 #if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
232 	flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data));
233 	flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data));
234 #endif
235 	INFO("ARM GICv2 driver initialized\n");
236 }
237 
238 /******************************************************************************
239  * This function returns whether FIQ is enabled in the GIC CPU interface.
240  *****************************************************************************/
241 unsigned int gicv2_is_fiq_enabled(void)
242 {
243 	unsigned int gicc_ctlr;
244 
245 	assert(driver_data != NULL);
246 	assert(driver_data->gicc_base != 0U);
247 
248 	gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base);
249 	return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1U;
250 }
251 
252 /*******************************************************************************
253  * This function returns the type of the highest priority pending interrupt at
254  * the GIC cpu interface. The return values can be one of the following :
255  *   PENDING_G1_INTID   : The interrupt type is non secure Group 1.
256  *   0 - 1019           : The interrupt type is secure Group 0.
257  *   GIC_SPURIOUS_INTERRUPT : there is no pending interrupt with
258  *                            sufficient priority to be signaled
259  ******************************************************************************/
260 unsigned int gicv2_get_pending_interrupt_type(void)
261 {
262 	assert(driver_data != NULL);
263 	assert(driver_data->gicc_base != 0U);
264 
265 	return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK;
266 }
267 
268 /*******************************************************************************
269  * This function returns the id of the highest priority pending interrupt at
270  * the GIC cpu interface. GIC_SPURIOUS_INTERRUPT is returned when there is no
271  * interrupt pending.
272  ******************************************************************************/
273 unsigned int gicv2_get_pending_interrupt_id(void)
274 {
275 	unsigned int id;
276 
277 	assert(driver_data != NULL);
278 	assert(driver_data->gicc_base != 0U);
279 
280 	id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK;
281 
282 	/*
283 	 * Find out which non-secure interrupt it is under the assumption that
284 	 * the GICC_CTLR.AckCtl bit is 0.
285 	 */
286 	if (id == PENDING_G1_INTID)
287 		id = gicc_read_ahppir(driver_data->gicc_base) & INT_ID_MASK;
288 
289 	return id;
290 }
291 
292 /*******************************************************************************
293  * This functions reads the GIC cpu interface Interrupt Acknowledge register
294  * to start handling the pending secure 0 interrupt. It returns the
295  * contents of the IAR.
296  ******************************************************************************/
297 unsigned int gicv2_acknowledge_interrupt(void)
298 {
299 	assert(driver_data != NULL);
300 	assert(driver_data->gicc_base != 0U);
301 
302 	return gicc_read_IAR(driver_data->gicc_base);
303 }
304 
305 /*******************************************************************************
306  * This functions writes the GIC cpu interface End Of Interrupt register with
307  * the passed value to finish handling the active secure group 0 interrupt.
308  ******************************************************************************/
309 void gicv2_end_of_interrupt(unsigned int id)
310 {
311 	assert(driver_data != NULL);
312 	assert(driver_data->gicc_base != 0U);
313 
314 	gicc_write_EOIR(driver_data->gicc_base, id);
315 }
316 
317 /*******************************************************************************
318  * This function returns the type of the interrupt id depending upon the group
319  * this interrupt has been configured under by the interrupt controller i.e.
320  * group0 secure or group1 non secure. It returns zero for Group 0 secure and
321  * one for Group 1 non secure interrupt.
322  ******************************************************************************/
323 unsigned int gicv2_get_interrupt_group(unsigned int id)
324 {
325 	assert(driver_data != NULL);
326 	assert(driver_data->gicd_base != 0U);
327 
328 	return gicd_get_igroupr(driver_data->gicd_base, id);
329 }
330 
331 /*******************************************************************************
332  * This function returns the priority of the interrupt the processor is
333  * currently servicing.
334  ******************************************************************************/
335 unsigned int gicv2_get_running_priority(void)
336 {
337 	assert(driver_data != NULL);
338 	assert(driver_data->gicc_base != 0U);
339 
340 	return gicc_read_rpr(driver_data->gicc_base);
341 }
342 
343 /*******************************************************************************
344  * This function sets the GICv2 target mask pattern for the current PE. The PE
345  * target mask is used to translate linear PE index (returned by platform core
346  * position) to a bit mask used when targeting interrupts to a PE, viz. when
347  * raising SGIs and routing SPIs.
348  ******************************************************************************/
349 void gicv2_set_pe_target_mask(unsigned int proc_num)
350 {
351 	assert(driver_data != NULL);
352 	assert(driver_data->gicd_base != 0U);
353 	assert(driver_data->target_masks != NULL);
354 	assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
355 	assert((unsigned int)proc_num < driver_data->target_masks_num);
356 
357 	/* Return if the target mask is already populated */
358 	if (driver_data->target_masks[proc_num] != 0U)
359 		return;
360 
361 	/*
362 	 * Update target register corresponding to this CPU and flush for it to
363 	 * be visible to other CPUs.
364 	 */
365 	if (driver_data->target_masks[proc_num] == 0U) {
366 		driver_data->target_masks[proc_num] =
367 			gicv2_get_cpuif_id(driver_data->gicd_base);
368 #if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
369 		/*
370 		 * PEs only update their own masks. Primary updates it with
371 		 * caches on. But because secondaries does it with caches off,
372 		 * all updates go to memory directly, and there's no danger of
373 		 * secondaries overwriting each others' mask, despite
374 		 * target_masks[] not being cache line aligned.
375 		 */
376 		flush_dcache_range((uintptr_t)
377 				&driver_data->target_masks[proc_num],
378 				sizeof(driver_data->target_masks[proc_num]));
379 #endif
380 	}
381 }
382 
383 /*******************************************************************************
384  * This function returns the active status of the interrupt (either because the
385  * state is active, or active and pending).
386  ******************************************************************************/
387 unsigned int gicv2_get_interrupt_active(unsigned int id)
388 {
389 	assert(driver_data != NULL);
390 	assert(driver_data->gicd_base != 0U);
391 	assert(id <= MAX_SPI_ID);
392 
393 	return gicd_get_isactiver(driver_data->gicd_base, id);
394 }
395 
396 /*******************************************************************************
397  * This function enables the interrupt identified by id.
398  ******************************************************************************/
399 void gicv2_enable_interrupt(unsigned int id)
400 {
401 	assert(driver_data != NULL);
402 	assert(driver_data->gicd_base != 0U);
403 	assert(id <= MAX_SPI_ID);
404 
405 	/*
406 	 * Ensure that any shared variable updates depending on out of band
407 	 * interrupt trigger are observed before enabling interrupt.
408 	 */
409 	dsbishst();
410 	gicd_set_isenabler(driver_data->gicd_base, id);
411 }
412 
413 /*******************************************************************************
414  * This function disables the interrupt identified by id.
415  ******************************************************************************/
416 void gicv2_disable_interrupt(unsigned int id)
417 {
418 	assert(driver_data != NULL);
419 	assert(driver_data->gicd_base != 0U);
420 	assert(id <= MAX_SPI_ID);
421 
422 	/*
423 	 * Disable interrupt, and ensure that any shared variable updates
424 	 * depending on out of band interrupt trigger are observed afterwards.
425 	 */
426 	gicd_set_icenabler(driver_data->gicd_base, id);
427 	dsbishst();
428 }
429 
430 /*******************************************************************************
431  * This function sets the interrupt priority as supplied for the given interrupt
432  * id.
433  ******************************************************************************/
434 void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority)
435 {
436 	assert(driver_data != NULL);
437 	assert(driver_data->gicd_base != 0U);
438 	assert(id <= MAX_SPI_ID);
439 
440 	gicd_set_ipriorityr(driver_data->gicd_base, id, priority);
441 }
442 
443 /*******************************************************************************
444  * This function assigns group for the interrupt identified by id. The group can
445  * be any of GICV2_INTR_GROUP*
446  ******************************************************************************/
447 void gicv2_set_interrupt_type(unsigned int id, unsigned int type)
448 {
449 	assert(driver_data != NULL);
450 	assert(driver_data->gicd_base != 0U);
451 	assert(id <= MAX_SPI_ID);
452 
453 	/* Serialize read-modify-write to Distributor registers */
454 	spin_lock(&gic_lock);
455 	switch (type) {
456 	case GICV2_INTR_GROUP1:
457 		gicd_set_igroupr(driver_data->gicd_base, id);
458 		break;
459 	case GICV2_INTR_GROUP0:
460 		gicd_clr_igroupr(driver_data->gicd_base, id);
461 		break;
462 	default:
463 		assert(false);
464 		break;
465 	}
466 	spin_unlock(&gic_lock);
467 }
468 
469 /*******************************************************************************
470  * This function raises the specified SGI to requested targets.
471  *
472  * The proc_num parameter must be the linear index of the target PE in the
473  * system.
474  ******************************************************************************/
475 void gicv2_raise_sgi(int sgi_num, int proc_num)
476 {
477 	unsigned int sgir_val, target;
478 
479 	assert(driver_data != NULL);
480 	assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
481 	assert(driver_data->gicd_base != 0U);
482 
483 	/*
484 	 * Target masks array must have been supplied, and the core position
485 	 * should be valid.
486 	 */
487 	assert(driver_data->target_masks != NULL);
488 	assert((unsigned int)proc_num < driver_data->target_masks_num);
489 
490 	/* Don't raise SGI if the mask hasn't been populated */
491 	target = driver_data->target_masks[proc_num];
492 	assert(target != 0U);
493 
494 	sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num);
495 
496 	/*
497 	 * Ensure that any shared variable updates depending on out of band
498 	 * interrupt trigger are observed before raising SGI.
499 	 */
500 	dsbishst();
501 	gicd_write_sgir(driver_data->gicd_base, sgir_val);
502 }
503 
504 /*******************************************************************************
505  * This function sets the interrupt routing for the given SPI interrupt id.
506  * The interrupt routing is specified in routing mode. The proc_num parameter is
507  * linear index of the PE to target SPI. When proc_num < 0, the SPI may target
508  * all PEs.
509  ******************************************************************************/
510 void gicv2_set_spi_routing(unsigned int id, int proc_num)
511 {
512 	unsigned int target;
513 
514 	assert(driver_data != NULL);
515 	assert(driver_data->gicd_base != 0U);
516 
517 	assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID));
518 
519 	/*
520 	 * Target masks array must have been supplied, and the core position
521 	 * should be valid.
522 	 */
523 	assert(driver_data->target_masks != NULL);
524 	assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
525 	assert((unsigned int)proc_num < driver_data->target_masks_num);
526 
527 	if (proc_num < 0) {
528 		/* Target all PEs */
529 		target = GIC_TARGET_CPU_MASK;
530 	} else {
531 		/* Don't route interrupt if the mask hasn't been populated */
532 		target = driver_data->target_masks[proc_num];
533 		assert(target != 0U);
534 	}
535 
536 	gicd_set_itargetsr(driver_data->gicd_base, id, target);
537 }
538 
539 /*******************************************************************************
540  * This function clears the pending status of an interrupt identified by id.
541  ******************************************************************************/
542 void gicv2_clear_interrupt_pending(unsigned int id)
543 {
544 	assert(driver_data != NULL);
545 	assert(driver_data->gicd_base != 0U);
546 
547 	/* SGIs can't be cleared pending */
548 	assert(id >= MIN_PPI_ID);
549 
550 	/*
551 	 * Clear pending interrupt, and ensure that any shared variable updates
552 	 * depending on out of band interrupt trigger are observed afterwards.
553 	 */
554 	gicd_set_icpendr(driver_data->gicd_base, id);
555 	dsbishst();
556 }
557 
558 /*******************************************************************************
559  * This function sets the pending status of an interrupt identified by id.
560  ******************************************************************************/
561 void gicv2_set_interrupt_pending(unsigned int id)
562 {
563 	assert(driver_data != NULL);
564 	assert(driver_data->gicd_base != 0U);
565 
566 	/* SGIs can't be cleared pending */
567 	assert(id >= MIN_PPI_ID);
568 
569 	/*
570 	 * Ensure that any shared variable updates depending on out of band
571 	 * interrupt trigger are observed before setting interrupt pending.
572 	 */
573 	dsbishst();
574 	gicd_set_ispendr(driver_data->gicd_base, id);
575 }
576 
577 /*******************************************************************************
578  * This function sets the PMR register with the supplied value. Returns the
579  * original PMR.
580  ******************************************************************************/
581 unsigned int gicv2_set_pmr(unsigned int mask)
582 {
583 	unsigned int old_mask;
584 
585 	assert(driver_data != NULL);
586 	assert(driver_data->gicc_base != 0U);
587 
588 	old_mask = gicc_read_pmr(driver_data->gicc_base);
589 
590 	/*
591 	 * Order memory updates w.r.t. PMR write, and ensure they're visible
592 	 * before potential out of band interrupt trigger because of PMR update.
593 	 */
594 	dmbishst();
595 	gicc_write_pmr(driver_data->gicc_base, mask);
596 	dsbishst();
597 
598 	return old_mask;
599 }
600