blob: e0c7971ac4fd83c3bc14d4674c65141b559fdb7b [file] [log] [blame]
Jeenu Viswambharan04e3a7f2017-10-16 08:43:14 +01001/*
John Powell67a5ee92022-05-12 12:49:55 -05002 * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
Jeenu Viswambharan04e3a7f2017-10-16 08:43:14 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <lib/utils.h>
10
Jeenu Viswambharan04e3a7f2017-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 */
22sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
23{
24 const sdei_mapping_t *mapping;
25 sdei_entry_t *cpu_priv_base;
Jeenu Viswambharan32ceef52018-08-02 10:14:12 +010026 unsigned int base_idx;
27 long int idx;
Jeenu Viswambharan04e3a7f2017-10-16 08:43:14 +010028
29 if (is_event_private(map)) {
30 /*
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 Viswambharan32ceef52018-08-02 10:14:12 +010038 base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
Jeenu Viswambharan04e3a7f2017-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/*
55 * Find event mapping for a given interrupt number: On success, returns pointer
56 * to the event mapping. On error, returns NULL.
57 */
Jeenu Viswambharan32ceef52018-08-02 10:14:12 +010058sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
Jeenu Viswambharan04e3a7f2017-10-16 08:43:14 +010059{
60 const sdei_mapping_t *mapping;
61 sdei_ev_map_t *map;
62 unsigned int i;
63
64 /*
65 * Look for a match in private and shared mappings, as requested. This
66 * is a linear search. However, if the mappings are required to be
67 * sorted, for large maps, we could consider binary search.
68 */
69 mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
70 iterate_mapping(mapping, i, map) {
71 if (map->intr == intr_num)
72 return map;
73 }
74
75 return NULL;
76}
77
78/*
79 * Find event mapping for a given event number: On success returns pointer to
80 * the event mapping. On error, returns NULL.
81 */
82sdei_ev_map_t *find_event_map(int ev_num)
83{
84 const sdei_mapping_t *mapping;
85 sdei_ev_map_t *map;
86 unsigned int i, j;
87
88 /*
89 * Iterate through mappings to find a match. This is a linear search.
90 * However, if the mappings are required to be sorted, for large maps,
91 * we could consider binary search.
92 */
93 for_each_mapping_type(i, mapping) {
94 iterate_mapping(mapping, j, map) {
95 if (map->ev_num == ev_num)
96 return map;
97 }
98 }
99
100 return NULL;
101}
John Powell67a5ee92022-05-12 12:49:55 -0500102
103/*
104 * Return the total number of currently registered SDEI events.
105 */
106int sdei_get_registered_event_count(void)
107{
108 const sdei_mapping_t *mapping;
109 sdei_ev_map_t *map;
110 unsigned int i;
111 unsigned int j;
112 int count = 0;
113
114 /* Add up reg counts for each mapping. */
115 for_each_mapping_type(i, mapping) {
116 iterate_mapping(mapping, j, map) {
117 count += map->reg_count;
118 }
119 }
120
121 return count;
122}