sdei_event.c 2.46 KB
Newer Older
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
1
/*
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
2
 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <utils.h>
#include "sdei_private.h"

#define MAP_OFF(_map, _mapping) ((_map) - (_mapping)->map)

/*
 * Get SDEI entry with the given mapping: on success, returns pointer to SDEI
 * entry. On error, returns NULL.
 *
 * Both shared and private maps are stored in single-dimensional array. Private
 * event entries are kept for each PE forming a 2D array.
 */
sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
{
	const sdei_mapping_t *mapping;
	sdei_entry_t *cpu_priv_base;
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
24
25
	unsigned int base_idx;
	long int idx;
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
26
27
28
29
30
31
32
33
34
35

	if (is_event_private(map)) {
		/*
		 * For a private map, find the index of the mapping in the
		 * array.
		 */
		mapping = SDEI_PRIVATE_MAPPING();
		idx = MAP_OFF(map, mapping);

		/* Base of private mappings for this CPU */
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
36
		base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
		cpu_priv_base = &sdei_private_event_table[base_idx];

		/*
		 * Return the address of the entry at the same index in the
		 * per-CPU event entry.
		 */
		return &cpu_priv_base[idx];
	} else {
		mapping = SDEI_SHARED_MAPPING();
		idx = MAP_OFF(map, mapping);

		return &sdei_shared_event_table[idx];
	}
}

/*
 * Find event mapping for a given interrupt number: On success, returns pointer
 * to the event mapping. On error, returns NULL.
 */
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
56
sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
	const sdei_mapping_t *mapping;
	sdei_ev_map_t *map;
	unsigned int i;

	/*
	 * Look for a match in private and shared mappings, as requested. This
	 * is a linear search. However, if the mappings are required to be
	 * sorted, for large maps, we could consider binary search.
	 */
	mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
	iterate_mapping(mapping, i, map) {
		if (map->intr == intr_num)
			return map;
	}

	return NULL;
}

/*
 * Find event mapping for a given event number: On success returns pointer to
 * the event mapping. On error, returns NULL.
 */
sdei_ev_map_t *find_event_map(int ev_num)
{
	const sdei_mapping_t *mapping;
	sdei_ev_map_t *map;
	unsigned int i, j;

	/*
	 * Iterate through mappings to find a match. This is a linear search.
	 * However, if the mappings are required to be sorted, for large maps,
	 * we could consider binary search.
	 */
	for_each_mapping_type(i, mapping) {
		iterate_mapping(mapping, j, map) {
			if (map->ev_num == ev_num)
				return map;
		}
	}

	return NULL;
}