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