1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017-2022, 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 9*91f16700Schasinglulu #include <lib/utils.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include "sdei_private.h" 12*91f16700Schasinglulu 13*91f16700Schasinglulu #define MAP_OFF(_map, _mapping) ((_map) - (_mapping)->map) 14*91f16700Schasinglulu 15*91f16700Schasinglulu /* 16*91f16700Schasinglulu * Get SDEI entry with the given mapping: on success, returns pointer to SDEI 17*91f16700Schasinglulu * entry. On error, returns NULL. 18*91f16700Schasinglulu * 19*91f16700Schasinglulu * Both shared and private maps are stored in single-dimensional array. Private 20*91f16700Schasinglulu * event entries are kept for each PE forming a 2D array. 21*91f16700Schasinglulu */ 22*91f16700Schasinglulu sdei_entry_t *get_event_entry(sdei_ev_map_t *map) 23*91f16700Schasinglulu { 24*91f16700Schasinglulu const sdei_mapping_t *mapping; 25*91f16700Schasinglulu sdei_entry_t *cpu_priv_base; 26*91f16700Schasinglulu unsigned int base_idx; 27*91f16700Schasinglulu long int idx; 28*91f16700Schasinglulu 29*91f16700Schasinglulu if (is_event_private(map)) { 30*91f16700Schasinglulu /* 31*91f16700Schasinglulu * For a private map, find the index of the mapping in the 32*91f16700Schasinglulu * array. 33*91f16700Schasinglulu */ 34*91f16700Schasinglulu mapping = SDEI_PRIVATE_MAPPING(); 35*91f16700Schasinglulu idx = MAP_OFF(map, mapping); 36*91f16700Schasinglulu 37*91f16700Schasinglulu /* Base of private mappings for this CPU */ 38*91f16700Schasinglulu base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps); 39*91f16700Schasinglulu cpu_priv_base = &sdei_private_event_table[base_idx]; 40*91f16700Schasinglulu 41*91f16700Schasinglulu /* 42*91f16700Schasinglulu * Return the address of the entry at the same index in the 43*91f16700Schasinglulu * per-CPU event entry. 44*91f16700Schasinglulu */ 45*91f16700Schasinglulu return &cpu_priv_base[idx]; 46*91f16700Schasinglulu } else { 47*91f16700Schasinglulu mapping = SDEI_SHARED_MAPPING(); 48*91f16700Schasinglulu idx = MAP_OFF(map, mapping); 49*91f16700Schasinglulu 50*91f16700Schasinglulu return &sdei_shared_event_table[idx]; 51*91f16700Schasinglulu } 52*91f16700Schasinglulu } 53*91f16700Schasinglulu 54*91f16700Schasinglulu /* 55*91f16700Schasinglulu * Find event mapping for a given interrupt number: On success, returns pointer 56*91f16700Schasinglulu * to the event mapping. On error, returns NULL. 57*91f16700Schasinglulu */ 58*91f16700Schasinglulu sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared) 59*91f16700Schasinglulu { 60*91f16700Schasinglulu const sdei_mapping_t *mapping; 61*91f16700Schasinglulu sdei_ev_map_t *map; 62*91f16700Schasinglulu unsigned int i; 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* 65*91f16700Schasinglulu * Look for a match in private and shared mappings, as requested. This 66*91f16700Schasinglulu * is a linear search. However, if the mappings are required to be 67*91f16700Schasinglulu * sorted, for large maps, we could consider binary search. 68*91f16700Schasinglulu */ 69*91f16700Schasinglulu mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING(); 70*91f16700Schasinglulu iterate_mapping(mapping, i, map) { 71*91f16700Schasinglulu if (map->intr == intr_num) 72*91f16700Schasinglulu return map; 73*91f16700Schasinglulu } 74*91f16700Schasinglulu 75*91f16700Schasinglulu return NULL; 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu /* 79*91f16700Schasinglulu * Find event mapping for a given event number: On success returns pointer to 80*91f16700Schasinglulu * the event mapping. On error, returns NULL. 81*91f16700Schasinglulu */ 82*91f16700Schasinglulu sdei_ev_map_t *find_event_map(int ev_num) 83*91f16700Schasinglulu { 84*91f16700Schasinglulu const sdei_mapping_t *mapping; 85*91f16700Schasinglulu sdei_ev_map_t *map; 86*91f16700Schasinglulu unsigned int i, j; 87*91f16700Schasinglulu 88*91f16700Schasinglulu /* 89*91f16700Schasinglulu * Iterate through mappings to find a match. This is a linear search. 90*91f16700Schasinglulu * However, if the mappings are required to be sorted, for large maps, 91*91f16700Schasinglulu * we could consider binary search. 92*91f16700Schasinglulu */ 93*91f16700Schasinglulu for_each_mapping_type(i, mapping) { 94*91f16700Schasinglulu iterate_mapping(mapping, j, map) { 95*91f16700Schasinglulu if (map->ev_num == ev_num) 96*91f16700Schasinglulu return map; 97*91f16700Schasinglulu } 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu return NULL; 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* 104*91f16700Schasinglulu * Return the total number of currently registered SDEI events. 105*91f16700Schasinglulu */ 106*91f16700Schasinglulu int sdei_get_registered_event_count(void) 107*91f16700Schasinglulu { 108*91f16700Schasinglulu const sdei_mapping_t *mapping; 109*91f16700Schasinglulu sdei_ev_map_t *map; 110*91f16700Schasinglulu unsigned int i; 111*91f16700Schasinglulu unsigned int j; 112*91f16700Schasinglulu int count = 0; 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* Add up reg counts for each mapping. */ 115*91f16700Schasinglulu for_each_mapping_type(i, mapping) { 116*91f16700Schasinglulu iterate_mapping(mapping, j, map) { 117*91f16700Schasinglulu count += map->reg_count; 118*91f16700Schasinglulu } 119*91f16700Schasinglulu } 120*91f16700Schasinglulu 121*91f16700Schasinglulu return count; 122*91f16700Schasinglulu } 123