1 /* 2 * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef SDEI_H 8 #define SDEI_H 9 10 #include <lib/spinlock.h> 11 #include <lib/utils_def.h> 12 #include <services/sdei_flags.h> 13 14 /* Range 0xC4000020 - 0xC400003F reserved for SDE 64bit smc calls */ 15 #define SDEI_VERSION 0xC4000020U 16 #define SDEI_EVENT_REGISTER 0xC4000021U 17 #define SDEI_EVENT_ENABLE 0xC4000022U 18 #define SDEI_EVENT_DISABLE 0xC4000023U 19 #define SDEI_EVENT_CONTEXT 0xC4000024U 20 #define SDEI_EVENT_COMPLETE 0xC4000025U 21 #define SDEI_EVENT_COMPLETE_AND_RESUME 0xC4000026U 22 23 #define SDEI_EVENT_UNREGISTER 0xC4000027U 24 #define SDEI_EVENT_STATUS 0xC4000028U 25 #define SDEI_EVENT_GET_INFO 0xC4000029U 26 #define SDEI_EVENT_ROUTING_SET 0xC400002AU 27 #define SDEI_PE_MASK 0xC400002BU 28 #define SDEI_PE_UNMASK 0xC400002CU 29 30 #define SDEI_INTERRUPT_BIND 0xC400002DU 31 #define SDEI_INTERRUPT_RELEASE 0xC400002EU 32 #define SDEI_EVENT_SIGNAL 0xC400002FU 33 #define SDEI_FEATURES 0xC4000030U 34 #define SDEI_PRIVATE_RESET 0xC4000031U 35 #define SDEI_SHARED_RESET 0xC4000032U 36 37 /* SDEI_EVENT_REGISTER flags */ 38 #define SDEI_REGF_RM_ANY 0ULL 39 #define SDEI_REGF_RM_PE 1ULL 40 41 /* SDEI_EVENT_COMPLETE status flags */ 42 #define SDEI_EV_HANDLED 0U 43 #define SDEI_EV_FAILED 1U 44 45 /* Indices of private and shared mappings */ 46 #define SDEI_MAP_IDX_PRIV_ 0U 47 #define SDEI_MAP_IDX_SHRD_ 1U 48 #define SDEI_MAP_IDX_MAX_ 2U 49 50 /* The macros below are used to identify SDEI calls from the SMC function ID */ 51 #define SDEI_FID_MASK U(0xffe0) 52 #define SDEI_FID_VALUE U(0x20) 53 #define is_sdei_fid(_fid) \ 54 ((((_fid) & SDEI_FID_MASK) == SDEI_FID_VALUE) && \ 55 (((_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_64)) 56 57 #define SDEI_EVENT_MAP(_event, _intr, _flags) \ 58 { \ 59 .ev_num = (_event), \ 60 .intr = (_intr), \ 61 .map_flags = (_flags) \ 62 } 63 64 #define SDEI_SHARED_EVENT(_event, _intr, _flags) \ 65 SDEI_EVENT_MAP(_event, _intr, _flags) 66 67 #define SDEI_PRIVATE_EVENT(_event, _intr, _flags) \ 68 SDEI_EVENT_MAP(_event, _intr, (_flags) | SDEI_MAPF_PRIVATE) 69 70 #define SDEI_DEFINE_EVENT_0(_intr) \ 71 SDEI_PRIVATE_EVENT(SDEI_EVENT_0, (_intr), SDEI_MAPF_SIGNALABLE) 72 73 #define SDEI_EXPLICIT_EVENT(_event, _pri) \ 74 SDEI_EVENT_MAP((_event), 0, (_pri) | SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE) 75 76 /* 77 * Declare shared and private entries for each core. Also declare a global 78 * structure containing private and share entries. 79 * 80 * This macro must be used in the same file as the platform SDEI mappings are 81 * declared. Only then would ARRAY_SIZE() yield a meaningful value. 82 */ 83 #define REGISTER_SDEI_MAP(_private, _shared) \ 84 sdei_entry_t sdei_private_event_table \ 85 [PLATFORM_CORE_COUNT * ARRAY_SIZE(_private)]; \ 86 sdei_entry_t sdei_shared_event_table[ARRAY_SIZE(_shared)]; \ 87 const sdei_mapping_t sdei_global_mappings[] = { \ 88 [SDEI_MAP_IDX_PRIV_] = { \ 89 .map = (_private), \ 90 .num_maps = ARRAY_SIZE(_private) \ 91 }, \ 92 [SDEI_MAP_IDX_SHRD_] = { \ 93 .map = (_shared), \ 94 .num_maps = ARRAY_SIZE(_shared) \ 95 }, \ 96 } 97 98 typedef uint8_t sdei_state_t; 99 100 /* Runtime data of SDEI event */ 101 typedef struct sdei_entry { 102 uint64_t ep; /* Entry point */ 103 uint64_t arg; /* Entry point argument */ 104 uint64_t affinity; /* Affinity of shared event */ 105 unsigned int reg_flags; /* Registration flags */ 106 107 /* Event handler states: registered, enabled, running */ 108 sdei_state_t state; 109 } sdei_entry_t; 110 111 /* Mapping of SDEI events to interrupts, and associated data */ 112 typedef struct sdei_ev_map { 113 int32_t ev_num; /* Event number */ 114 unsigned int intr; /* Physical interrupt number for a bound map */ 115 unsigned int map_flags; /* Mapping flags, see SDEI_MAPF_* */ 116 int reg_count; /* Registration count */ 117 spinlock_t lock; /* Per-event lock */ 118 } sdei_ev_map_t; 119 120 typedef struct sdei_mapping { 121 sdei_ev_map_t *map; 122 size_t num_maps; 123 } sdei_mapping_t; 124 125 /* Handler to be called to handle SDEI smc calls */ 126 uint64_t sdei_smc_handler(uint32_t smc_fid, 127 uint64_t x1, 128 uint64_t x2, 129 uint64_t x3, 130 uint64_t x4, 131 void *cookie, 132 void *handle, 133 uint64_t flags); 134 135 void sdei_init(void); 136 137 /* Public API to dispatch an event to Normal world */ 138 int sdei_dispatch_event(int ev_num); 139 140 /* Public API to check how many SDEI events are registered. */ 141 int sdei_get_registered_event_count(void); 142 143 #endif /* SDEI_H */ 144