blob: cc8f5575dad7e2e92573a09cebbea15c3282a4ab [file] [log] [blame]
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +01001/*
Igor Podgainõib142ede2024-10-07 15:16:29 +02002 * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +00008
9#include <lib/utils.h>
10
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010011#include "sdei_private.h"
12
13#define MAP_OFF(_map, _mapping) ((_map) - (_mapping)->map)
14
15/*
16 * Get SDEI entry with the given mapping: on success, returns pointer to SDEI
17 * entry. On error, returns NULL.
18 *
19 * Both shared and private maps are stored in single-dimensional array. Private
20 * event entries are kept for each PE forming a 2D array.
21 */
Igor Podgainõib142ede2024-10-07 15:16:29 +020022sdei_entry_t *get_event_entry(const sdei_ev_map_t *map)
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010023{
24 const sdei_mapping_t *mapping;
25 sdei_entry_t *cpu_priv_base;
Jeenu Viswambharanba6e5ca2018-08-02 10:14:12 +010026 unsigned int base_idx;
27 long int idx;
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010028
Igor Podgainõib142ede2024-10-07 15:16:29 +020029 if ((map->map_flags & BIT_32(SDEI_MAPF_PRIVATE_SHIFT_)) != 0U) {
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010030 /*
31 * For a private map, find the index of the mapping in the
32 * array.
33 */
34 mapping = SDEI_PRIVATE_MAPPING();
35 idx = MAP_OFF(map, mapping);
36
37 /* Base of private mappings for this CPU */
Jeenu Viswambharanba6e5ca2018-08-02 10:14:12 +010038 base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010039 cpu_priv_base = &sdei_private_event_table[base_idx];
40
41 /*
42 * Return the address of the entry at the same index in the
43 * per-CPU event entry.
44 */
45 return &cpu_priv_base[idx];
46 } else {
47 mapping = SDEI_SHARED_MAPPING();
48 idx = MAP_OFF(map, mapping);
49
50 return &sdei_shared_event_table[idx];
51 }
52}
53
54/*
Igor Podgainõib142ede2024-10-07 15:16:29 +020055 * Retrieve the SDEI entry for the given mapping and target PE.
56 *
57 * on success : Returns a pointer to the SDEI entry
58 *
59 * On error, returns NULL
60 *
61 * Both shared and private maps are stored in single-dimensional array. Private
62 * event entries are kept for each PE forming a 2D array.
63 */
64sdei_entry_t *get_event_entry_target_pe(long int mapsub, unsigned int nm, uint64_t target_pe)
65{
66 sdei_entry_t *cpu_priv_base;
67 unsigned int base_idx;
68 long int idx;
69
70 /*
71 * For a private map, find the index of the mapping in the
72 * array.
73 */
74 idx = mapsub;
75
76 /* Base of private mappings for this CPU */
77 base_idx = (unsigned int) plat_core_pos_by_mpidr(target_pe);
78 base_idx *= nm;
79 cpu_priv_base = &sdei_private_event_table[base_idx];
80 /*
81 * Return the address of the entry at the same index in the
82 * per-CPU event entry.
83 */
84 return &cpu_priv_base[idx];
85}
86
87/*
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010088 * Find event mapping for a given interrupt number: On success, returns pointer
89 * to the event mapping. On error, returns NULL.
90 */
Jeenu Viswambharanba6e5ca2018-08-02 10:14:12 +010091sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
Jeenu Viswambharanb7cb1332017-10-16 08:43:14 +010092{
93 const sdei_mapping_t *mapping;
94 sdei_ev_map_t *map;
95 unsigned int i;
96
97 /*
98 * Look for a match in private and shared mappings, as requested. This
99 * is a linear search. However, if the mappings are required to be
100 * sorted, for large maps, we could consider binary search.
101 */
102 mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
103 iterate_mapping(mapping, i, map) {
104 if (map->intr == intr_num)
105 return map;
106 }
107
108 return NULL;
109}
110
111/*
112 * Find event mapping for a given event number: On success returns pointer to
113 * the event mapping. On error, returns NULL.
114 */
115sdei_ev_map_t *find_event_map(int ev_num)
116{
117 const sdei_mapping_t *mapping;
118 sdei_ev_map_t *map;
119 unsigned int i, j;
120
121 /*
122 * Iterate through mappings to find a match. This is a linear search.
123 * However, if the mappings are required to be sorted, for large maps,
124 * we could consider binary search.
125 */
126 for_each_mapping_type(i, mapping) {
127 iterate_mapping(mapping, j, map) {
128 if (map->ev_num == ev_num)
129 return map;
130 }
131 }
132
133 return NULL;
134}
John Powelle6381f92022-05-12 12:49:55 -0500135
136/*
137 * Return the total number of currently registered SDEI events.
138 */
139int sdei_get_registered_event_count(void)
140{
141 const sdei_mapping_t *mapping;
142 sdei_ev_map_t *map;
143 unsigned int i;
144 unsigned int j;
145 int count = 0;
146
147 /* Add up reg counts for each mapping. */
148 for_each_mapping_type(i, mapping) {
149 iterate_mapping(mapping, j, map) {
150 count += map->reg_count;
151 }
152 }
153
154 return count;
155}