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