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