1 /* 2 * Copyright (c) 2017-2018, 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 base_idx; 25 long int idx; 26 27 if (is_event_private(map)) { 28 /* 29 * For a private map, find the index of the mapping in the 30 * array. 31 */ 32 mapping = SDEI_PRIVATE_MAPPING(); 33 idx = MAP_OFF(map, mapping); 34 35 /* Base of private mappings for this CPU */ 36 base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps); 37 cpu_priv_base = &sdei_private_event_table[base_idx]; 38 39 /* 40 * Return the address of the entry at the same index in the 41 * per-CPU event entry. 42 */ 43 return &cpu_priv_base[idx]; 44 } else { 45 mapping = SDEI_SHARED_MAPPING(); 46 idx = MAP_OFF(map, mapping); 47 48 return &sdei_shared_event_table[idx]; 49 } 50 } 51 52 /* 53 * Find event mapping for a given interrupt number: On success, returns pointer 54 * to the event mapping. On error, returns NULL. 55 */ 56 sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared) 57 { 58 const sdei_mapping_t *mapping; 59 sdei_ev_map_t *map; 60 unsigned int i; 61 62 /* 63 * Look for a match in private and shared mappings, as requested. This 64 * is a linear search. However, if the mappings are required to be 65 * sorted, for large maps, we could consider binary search. 66 */ 67 mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING(); 68 iterate_mapping(mapping, i, map) { 69 if (map->intr == intr_num) 70 return map; 71 } 72 73 return NULL; 74 } 75 76 /* 77 * Find event mapping for a given event number: On success returns pointer to 78 * the event mapping. On error, returns NULL. 79 */ 80 sdei_ev_map_t *find_event_map(int ev_num) 81 { 82 const sdei_mapping_t *mapping; 83 sdei_ev_map_t *map; 84 unsigned int i, j; 85 86 /* 87 * Iterate through mappings to find a match. This is a linear search. 88 * However, if the mappings are required to be sorted, for large maps, 89 * we could consider binary search. 90 */ 91 for_each_mapping_type(i, mapping) { 92 iterate_mapping(mapping, j, map) { 93 if (map->ev_num == ev_num) 94 return map; 95 } 96 } 97 98 return NULL; 99 } 100