xref: /rk3399_ARM-atf/services/std_svc/sdei/sdei_event.c (revision 9dde2cc1b8838807c1b4a7fa1ec62e883249d50d)
1b7cb133eSJeenu Viswambharan /*
2b142ede7SIgor Podgainõi  * Copyright (c) 2017-2025, 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>
809d40e0eSAntonio Nino Diaz 
909d40e0eSAntonio Nino Diaz #include <lib/utils.h>
1009d40e0eSAntonio Nino Diaz 
11b7cb133eSJeenu Viswambharan #include "sdei_private.h"
12b7cb133eSJeenu Viswambharan 
13b7cb133eSJeenu Viswambharan #define MAP_OFF(_map, _mapping) ((_map) - (_mapping)->map)
14b7cb133eSJeenu Viswambharan 
15b7cb133eSJeenu Viswambharan /*
16b7cb133eSJeenu Viswambharan  * Get SDEI entry with the given mapping: on success, returns pointer to SDEI
17b7cb133eSJeenu Viswambharan  * entry. On error, returns NULL.
18b7cb133eSJeenu Viswambharan  *
19b7cb133eSJeenu Viswambharan  * Both shared and private maps are stored in single-dimensional array. Private
20b7cb133eSJeenu Viswambharan  * event entries are kept for each PE forming a 2D array.
21b7cb133eSJeenu Viswambharan  */
22b142ede7SIgor Podgainõi sdei_entry_t *get_event_entry(const sdei_ev_map_t *map)
23b7cb133eSJeenu Viswambharan {
24b7cb133eSJeenu Viswambharan 	const sdei_mapping_t *mapping;
25b7cb133eSJeenu Viswambharan 	sdei_entry_t *cpu_priv_base;
26ba6e5ca6SJeenu Viswambharan 	unsigned int base_idx;
27ba6e5ca6SJeenu Viswambharan 	long int idx;
28b7cb133eSJeenu Viswambharan 
29b142ede7SIgor Podgainõi 	if ((map->map_flags & BIT_32(SDEI_MAPF_PRIVATE_SHIFT_)) != 0U) {
30b7cb133eSJeenu Viswambharan 		/*
31b7cb133eSJeenu Viswambharan 		 * For a private map, find the index of the mapping in the
32b7cb133eSJeenu Viswambharan 		 * array.
33b7cb133eSJeenu Viswambharan 		 */
34b7cb133eSJeenu Viswambharan 		mapping = SDEI_PRIVATE_MAPPING();
35b7cb133eSJeenu Viswambharan 		idx = MAP_OFF(map, mapping);
36b7cb133eSJeenu Viswambharan 
37b7cb133eSJeenu Viswambharan 		/* Base of private mappings for this CPU */
38ba6e5ca6SJeenu Viswambharan 		base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
39b7cb133eSJeenu Viswambharan 		cpu_priv_base = &sdei_private_event_table[base_idx];
40b7cb133eSJeenu Viswambharan 
41b7cb133eSJeenu Viswambharan 		/*
42b7cb133eSJeenu Viswambharan 		 * Return the address of the entry at the same index in the
43b7cb133eSJeenu Viswambharan 		 * per-CPU event entry.
44b7cb133eSJeenu Viswambharan 		 */
45b7cb133eSJeenu Viswambharan 		return &cpu_priv_base[idx];
46b7cb133eSJeenu Viswambharan 	} else {
47b7cb133eSJeenu Viswambharan 		mapping = SDEI_SHARED_MAPPING();
48b7cb133eSJeenu Viswambharan 		idx = MAP_OFF(map, mapping);
49b7cb133eSJeenu Viswambharan 
50b7cb133eSJeenu Viswambharan 		return &sdei_shared_event_table[idx];
51b7cb133eSJeenu Viswambharan 	}
52b7cb133eSJeenu Viswambharan }
53b7cb133eSJeenu Viswambharan 
54b7cb133eSJeenu Viswambharan /*
55b142ede7SIgor Podgainõi  * Retrieve the SDEI entry for the given mapping and target PE.
56b142ede7SIgor Podgainõi  *
57b142ede7SIgor Podgainõi  * on success : Returns a pointer to the SDEI entry
58b142ede7SIgor Podgainõi  *
59b142ede7SIgor Podgainõi  * On error, returns NULL
60b142ede7SIgor Podgainõi  *
61b142ede7SIgor Podgainõi  * Both shared and private maps are stored in single-dimensional array. Private
62b142ede7SIgor Podgainõi  * event entries are kept for each PE forming a 2D array.
63b142ede7SIgor Podgainõi  */
64*9dde2cc1SMark Dykes sdei_entry_t *get_event_entry_target_pe(long int mapsub, unsigned int nm,
65*9dde2cc1SMark Dykes uint64_t target_pe)
66b142ede7SIgor Podgainõi {
67b142ede7SIgor Podgainõi 	sdei_entry_t *cpu_priv_base;
68*9dde2cc1SMark Dykes 	unsigned int base_idx = 0U;
69b142ede7SIgor Podgainõi 	long int idx;
70*9dde2cc1SMark Dykes 	int target_pos;
71b142ede7SIgor Podgainõi 
72b142ede7SIgor Podgainõi 	/*
73b142ede7SIgor Podgainõi 	 * For a private map, find the index of the mapping in the
74b142ede7SIgor Podgainõi 	 * array.
75b142ede7SIgor Podgainõi 	 */
76b142ede7SIgor Podgainõi 	idx = mapsub;
77b142ede7SIgor Podgainõi 
78b142ede7SIgor Podgainõi 	/* Base of private mappings for this CPU */
79*9dde2cc1SMark Dykes 	target_pos = plat_core_pos_by_mpidr(target_pe);
80*9dde2cc1SMark Dykes 
81*9dde2cc1SMark Dykes 	if ((target_pos < 0) || ((unsigned int)target_pos >= PLATFORM_CORE_COUNT)) {
82*9dde2cc1SMark Dykes 		return NULL;
83*9dde2cc1SMark Dykes 	}
84*9dde2cc1SMark Dykes 
85*9dde2cc1SMark Dykes 	base_idx = (unsigned int) target_pos;
86b142ede7SIgor Podgainõi 	base_idx *= nm;
87*9dde2cc1SMark Dykes 
88b142ede7SIgor Podgainõi 	cpu_priv_base = &sdei_private_event_table[base_idx];
89*9dde2cc1SMark Dykes 
90b142ede7SIgor Podgainõi 	/*
91b142ede7SIgor Podgainõi 	 * Return the address of the entry at the same index in the
92b142ede7SIgor Podgainõi 	 * per-CPU event entry.
93b142ede7SIgor Podgainõi 	 */
94b142ede7SIgor Podgainõi 	return &cpu_priv_base[idx];
95b142ede7SIgor Podgainõi }
96b142ede7SIgor Podgainõi 
97b142ede7SIgor Podgainõi /*
98b7cb133eSJeenu Viswambharan  * Find event mapping for a given interrupt number: On success, returns pointer
99b7cb133eSJeenu Viswambharan  * to the event mapping. On error, returns NULL.
100b7cb133eSJeenu Viswambharan  */
101ba6e5ca6SJeenu Viswambharan sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
102b7cb133eSJeenu Viswambharan {
103b7cb133eSJeenu Viswambharan 	const sdei_mapping_t *mapping;
104b7cb133eSJeenu Viswambharan 	sdei_ev_map_t *map;
105b7cb133eSJeenu Viswambharan 	unsigned int i;
106b7cb133eSJeenu Viswambharan 
107b7cb133eSJeenu Viswambharan 	/*
108b7cb133eSJeenu Viswambharan 	 * Look for a match in private and shared mappings, as requested. This
109b7cb133eSJeenu Viswambharan 	 * is a linear search. However, if the mappings are required to be
110b7cb133eSJeenu Viswambharan 	 * sorted, for large maps, we could consider binary search.
111b7cb133eSJeenu Viswambharan 	 */
112b7cb133eSJeenu Viswambharan 	mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
113b7cb133eSJeenu Viswambharan 	iterate_mapping(mapping, i, map) {
114b7cb133eSJeenu Viswambharan 		if (map->intr == intr_num)
115b7cb133eSJeenu Viswambharan 			return map;
116b7cb133eSJeenu Viswambharan 	}
117b7cb133eSJeenu Viswambharan 
118b7cb133eSJeenu Viswambharan 	return NULL;
119b7cb133eSJeenu Viswambharan }
120b7cb133eSJeenu Viswambharan 
121b7cb133eSJeenu Viswambharan /*
122b7cb133eSJeenu Viswambharan  * Find event mapping for a given event number: On success returns pointer to
123b7cb133eSJeenu Viswambharan  * the event mapping. On error, returns NULL.
124b7cb133eSJeenu Viswambharan  */
125b7cb133eSJeenu Viswambharan sdei_ev_map_t *find_event_map(int ev_num)
126b7cb133eSJeenu Viswambharan {
127b7cb133eSJeenu Viswambharan 	const sdei_mapping_t *mapping;
128b7cb133eSJeenu Viswambharan 	sdei_ev_map_t *map;
129b7cb133eSJeenu Viswambharan 	unsigned int i, j;
130b7cb133eSJeenu Viswambharan 
131b7cb133eSJeenu Viswambharan 	/*
132b7cb133eSJeenu Viswambharan 	 * Iterate through mappings to find a match. This is a linear search.
133b7cb133eSJeenu Viswambharan 	 * However, if the mappings are required to be sorted, for large maps,
134b7cb133eSJeenu Viswambharan 	 * we could consider binary search.
135b7cb133eSJeenu Viswambharan 	 */
136b7cb133eSJeenu Viswambharan 	for_each_mapping_type(i, mapping) {
137b7cb133eSJeenu Viswambharan 		iterate_mapping(mapping, j, map) {
138b7cb133eSJeenu Viswambharan 			if (map->ev_num == ev_num)
139b7cb133eSJeenu Viswambharan 				return map;
140b7cb133eSJeenu Viswambharan 		}
141b7cb133eSJeenu Viswambharan 	}
142b7cb133eSJeenu Viswambharan 
143b7cb133eSJeenu Viswambharan 	return NULL;
144b7cb133eSJeenu Viswambharan }
145e6381f9cSJohn Powell 
146e6381f9cSJohn Powell /*
147e6381f9cSJohn Powell  * Return the total number of currently registered SDEI events.
148e6381f9cSJohn Powell  */
149e6381f9cSJohn Powell int sdei_get_registered_event_count(void)
150e6381f9cSJohn Powell {
151e6381f9cSJohn Powell 	const sdei_mapping_t *mapping;
152e6381f9cSJohn Powell 	sdei_ev_map_t *map;
153e6381f9cSJohn Powell 	unsigned int i;
154e6381f9cSJohn Powell 	unsigned int j;
155e6381f9cSJohn Powell 	int count = 0;
156e6381f9cSJohn Powell 
157e6381f9cSJohn Powell 	/* Add up reg counts for each mapping. */
158e6381f9cSJohn Powell 	for_each_mapping_type(i, mapping) {
159e6381f9cSJohn Powell 		iterate_mapping(mapping, j, map) {
160e6381f9cSJohn Powell 			count += map->reg_count;
161e6381f9cSJohn Powell 		}
162e6381f9cSJohn Powell 	}
163e6381f9cSJohn Powell 
164e6381f9cSJohn Powell 	return count;
165e6381f9cSJohn Powell }
166