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