xref: /rk3399_ARM-atf/services/std_svc/sdei/sdei_event.c (revision ba6e5ca67160f3847b0e68a0f7bc16d12989f2b4)
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