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