xref: /rk3399_ARM-atf/services/std_svc/sdei/sdei_event.c (revision 61f72a34250d063da67f4fc2b0eb8c3fda3376be)
1 /*
2  * Copyright (c) 2017, 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 idx, base_idx;
25 
26 	if (is_event_private(map)) {
27 		/*
28 		 * For a private map, find the index of the mapping in the
29 		 * array.
30 		 */
31 		mapping = SDEI_PRIVATE_MAPPING();
32 		idx = MAP_OFF(map, mapping);
33 
34 		/* Base of private mappings for this CPU */
35 		base_idx = plat_my_core_pos() * mapping->num_maps;
36 		cpu_priv_base = &sdei_private_event_table[base_idx];
37 
38 		/*
39 		 * Return the address of the entry at the same index in the
40 		 * per-CPU event entry.
41 		 */
42 		return &cpu_priv_base[idx];
43 	} else {
44 		mapping = SDEI_SHARED_MAPPING();
45 		idx = MAP_OFF(map, mapping);
46 
47 		return &sdei_shared_event_table[idx];
48 	}
49 }
50 
51 /*
52  * Find event mapping for a given interrupt number: On success, returns pointer
53  * to the event mapping. On error, returns NULL.
54  */
55 sdei_ev_map_t *find_event_map_by_intr(int intr_num, int shared)
56 {
57 	const sdei_mapping_t *mapping;
58 	sdei_ev_map_t *map;
59 	unsigned int i;
60 
61 	/*
62 	 * Look for a match in private and shared mappings, as requested. This
63 	 * is a linear search. However, if the mappings are required to be
64 	 * sorted, for large maps, we could consider binary search.
65 	 */
66 	mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
67 	iterate_mapping(mapping, i, map) {
68 		if (map->intr == intr_num)
69 			return map;
70 	}
71 
72 	return NULL;
73 }
74 
75 /*
76  * Find event mapping for a given event number: On success returns pointer to
77  * the event mapping. On error, returns NULL.
78  */
79 sdei_ev_map_t *find_event_map(int ev_num)
80 {
81 	const sdei_mapping_t *mapping;
82 	sdei_ev_map_t *map;
83 	unsigned int i, j;
84 
85 	/*
86 	 * Iterate through mappings to find a match. This is a linear search.
87 	 * However, if the mappings are required to be sorted, for large maps,
88 	 * we could consider binary search.
89 	 */
90 	for_each_mapping_type(i, mapping) {
91 		iterate_mapping(mapping, j, map) {
92 			if (map->ev_num == ev_num)
93 				return map;
94 		}
95 	}
96 
97 	return NULL;
98 }
99