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