mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-25 22:35:42 +00:00

This patch adds a public API to return the total number of registered events. The purpose of this is primarily for DRTM to ensure that no SDEI event can interfere with a dynamic launch. Signed-off-by: John Powell <john.powell@arm.com> Change-Id: I1d1cba2da7d5566cc340620ee1ce7d7844740b86
122 lines
2.8 KiB
C
122 lines
2.8 KiB
C
/*
|
|
* Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
|
|
#include <lib/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;
|
|
unsigned int base_idx;
|
|
long int idx;
|
|
|
|
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 */
|
|
base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
|
|
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.
|
|
*/
|
|
sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
|
|
{
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* Return the total number of currently registered SDEI events.
|
|
*/
|
|
int sdei_get_registered_event_count(void)
|
|
{
|
|
const sdei_mapping_t *mapping;
|
|
sdei_ev_map_t *map;
|
|
unsigned int i;
|
|
unsigned int j;
|
|
int count = 0;
|
|
|
|
/* Add up reg counts for each mapping. */
|
|
for_each_mapping_type(i, mapping) {
|
|
iterate_mapping(mapping, j, map) {
|
|
count += map->reg_count;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|