sdei_event.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <lib/utils.h>
  8. #include "sdei_private.h"
  9. #define MAP_OFF(_map, _mapping) ((_map) - (_mapping)->map)
  10. /*
  11. * Get SDEI entry with the given mapping: on success, returns pointer to SDEI
  12. * entry. On error, returns NULL.
  13. *
  14. * Both shared and private maps are stored in single-dimensional array. Private
  15. * event entries are kept for each PE forming a 2D array.
  16. */
  17. sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
  18. {
  19. const sdei_mapping_t *mapping;
  20. sdei_entry_t *cpu_priv_base;
  21. unsigned int base_idx;
  22. long int idx;
  23. if (is_event_private(map)) {
  24. /*
  25. * For a private map, find the index of the mapping in the
  26. * array.
  27. */
  28. mapping = SDEI_PRIVATE_MAPPING();
  29. idx = MAP_OFF(map, mapping);
  30. /* Base of private mappings for this CPU */
  31. base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
  32. cpu_priv_base = &sdei_private_event_table[base_idx];
  33. /*
  34. * Return the address of the entry at the same index in the
  35. * per-CPU event entry.
  36. */
  37. return &cpu_priv_base[idx];
  38. } else {
  39. mapping = SDEI_SHARED_MAPPING();
  40. idx = MAP_OFF(map, mapping);
  41. return &sdei_shared_event_table[idx];
  42. }
  43. }
  44. /*
  45. * Find event mapping for a given interrupt number: On success, returns pointer
  46. * to the event mapping. On error, returns NULL.
  47. */
  48. sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
  49. {
  50. const sdei_mapping_t *mapping;
  51. sdei_ev_map_t *map;
  52. unsigned int i;
  53. /*
  54. * Look for a match in private and shared mappings, as requested. This
  55. * is a linear search. However, if the mappings are required to be
  56. * sorted, for large maps, we could consider binary search.
  57. */
  58. mapping = shared ? SDEI_SHARED_MAPPING() : SDEI_PRIVATE_MAPPING();
  59. iterate_mapping(mapping, i, map) {
  60. if (map->intr == intr_num)
  61. return map;
  62. }
  63. return NULL;
  64. }
  65. /*
  66. * Find event mapping for a given event number: On success returns pointer to
  67. * the event mapping. On error, returns NULL.
  68. */
  69. sdei_ev_map_t *find_event_map(int ev_num)
  70. {
  71. const sdei_mapping_t *mapping;
  72. sdei_ev_map_t *map;
  73. unsigned int i, j;
  74. /*
  75. * Iterate through mappings to find a match. This is a linear search.
  76. * However, if the mappings are required to be sorted, for large maps,
  77. * we could consider binary search.
  78. */
  79. for_each_mapping_type(i, mapping) {
  80. iterate_mapping(mapping, j, map) {
  81. if (map->ev_num == ev_num)
  82. return map;
  83. }
  84. }
  85. return NULL;
  86. }
  87. /*
  88. * Return the total number of currently registered SDEI events.
  89. */
  90. int sdei_get_registered_event_count(void)
  91. {
  92. const sdei_mapping_t *mapping;
  93. sdei_ev_map_t *map;
  94. unsigned int i;
  95. unsigned int j;
  96. int count = 0;
  97. /* Add up reg counts for each mapping. */
  98. for_each_mapping_type(i, mapping) {
  99. iterate_mapping(mapping, j, map) {
  100. count += map->reg_count;
  101. }
  102. }
  103. return count;
  104. }