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