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