xref: /arm-trusted-firmware/plat/arm/css/sgi/ras/sgi_ras_common.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2018-2023, 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 #include <string.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <bl31/interrupt_mgmt.h>
11*91f16700Schasinglulu #include <plat/common/platform.h>
12*91f16700Schasinglulu #include <platform_def.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #include <sgi_ras.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu static struct plat_sgi_ras_config *sgi_ras_config;
17*91f16700Schasinglulu 
18*91f16700Schasinglulu /*
19*91f16700Schasinglulu  * Find event map for a given interrupt number. On success, returns pointer to
20*91f16700Schasinglulu  * the event map. On error, returns NULL.
21*91f16700Schasinglulu  */
22*91f16700Schasinglulu struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
23*91f16700Schasinglulu {
24*91f16700Schasinglulu 	struct sgi_ras_ev_map *map;
25*91f16700Schasinglulu 	int size;
26*91f16700Schasinglulu 	int i;
27*91f16700Schasinglulu 
28*91f16700Schasinglulu 	if (sgi_ras_config == NULL) {
29*91f16700Schasinglulu 		ERROR("RAS config is NULL\n");
30*91f16700Schasinglulu 		return NULL;
31*91f16700Schasinglulu 	}
32*91f16700Schasinglulu 
33*91f16700Schasinglulu 	map = sgi_ras_config->ev_map;
34*91f16700Schasinglulu 	size = sgi_ras_config->ev_map_size;
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	for (i = 0; i < size; i++) {
37*91f16700Schasinglulu 		if (map->intr == intr_num)
38*91f16700Schasinglulu 			return map;
39*91f16700Schasinglulu 
40*91f16700Schasinglulu 		map++;
41*91f16700Schasinglulu 	}
42*91f16700Schasinglulu 
43*91f16700Schasinglulu 	return NULL;
44*91f16700Schasinglulu }
45*91f16700Schasinglulu 
46*91f16700Schasinglulu /*
47*91f16700Schasinglulu  * Programs GIC registers and configures interrupt ID's as Group0 EL3
48*91f16700Schasinglulu  * interrupts. Current support is to register PPI and SPI interrupts.
49*91f16700Schasinglulu  */
50*91f16700Schasinglulu static void sgi_ras_intr_configure(int intr, int intr_type)
51*91f16700Schasinglulu {
52*91f16700Schasinglulu 	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
53*91f16700Schasinglulu 	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
54*91f16700Schasinglulu 	plat_ic_clear_interrupt_pending(intr);
55*91f16700Schasinglulu 
56*91f16700Schasinglulu 	/* Routing mode option available only for SPI interrupts */
57*91f16700Schasinglulu 	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
58*91f16700Schasinglulu 		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
59*91f16700Schasinglulu 					(u_register_t)read_mpidr_el1());
60*91f16700Schasinglulu 	}
61*91f16700Schasinglulu 	plat_ic_enable_interrupt(intr);
62*91f16700Schasinglulu }
63*91f16700Schasinglulu 
64*91f16700Schasinglulu /*
65*91f16700Schasinglulu  * Initialization function for the framework.
66*91f16700Schasinglulu  *
67*91f16700Schasinglulu  * Registers RAS config provided by the platform and then configures and
68*91f16700Schasinglulu  * enables interrupt for each registered error. On success, return 0.
69*91f16700Schasinglulu  */
70*91f16700Schasinglulu int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
71*91f16700Schasinglulu {
72*91f16700Schasinglulu 	struct sgi_ras_ev_map *map;
73*91f16700Schasinglulu 	int size;
74*91f16700Schasinglulu 	int i;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	/* Check if parameter is valid. */
77*91f16700Schasinglulu 	if (config == NULL) {
78*91f16700Schasinglulu 		ERROR("SGI: Failed to register RAS config\n");
79*91f16700Schasinglulu 		return -1;
80*91f16700Schasinglulu 	}
81*91f16700Schasinglulu 
82*91f16700Schasinglulu 	/*
83*91f16700Schasinglulu 	 * Maintain a reference to the platform RAS config data for later
84*91f16700Schasinglulu 	 * use.
85*91f16700Schasinglulu 	 */
86*91f16700Schasinglulu 	sgi_ras_config = config;
87*91f16700Schasinglulu 
88*91f16700Schasinglulu 	map = sgi_ras_config->ev_map;
89*91f16700Schasinglulu 	size = sgi_ras_config->ev_map_size;
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	for (i = 0; i < size; i++) {
92*91f16700Schasinglulu 		sgi_ras_intr_configure(map->intr, map->intr_type);
93*91f16700Schasinglulu 		map++;
94*91f16700Schasinglulu 	}
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 	INFO("SGI: Platform RAS setup successful\n");
97*91f16700Schasinglulu 
98*91f16700Schasinglulu 	return 0;
99*91f16700Schasinglulu }
100