blob: bf0e779d0337173de342a4bd0b0e2899384d0211 [file] [log] [blame]
Jeenu Viswambharan04e3a7f2017-10-16 08:43:14 +01001/*
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 */
20sdei_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 */
55sdei_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 */
79sdei_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}