Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 1 | /* |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 2 | * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 7 | #ifndef SDEI_H |
| 8 | #define SDEI_H |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 9 | |
Antonio Nino Diaz | e0f9063 | 2018-12-14 00:18:21 +0000 | [diff] [blame] | 10 | #include <lib/spinlock.h> |
| 11 | #include <lib/utils_def.h> |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 12 | |
| 13 | /* Range 0xC4000020 - 0xC400003F reserved for SDE 64bit smc calls */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 14 | #define SDEI_VERSION 0xC4000020U |
| 15 | #define SDEI_EVENT_REGISTER 0xC4000021U |
| 16 | #define SDEI_EVENT_ENABLE 0xC4000022U |
| 17 | #define SDEI_EVENT_DISABLE 0xC4000023U |
| 18 | #define SDEI_EVENT_CONTEXT 0xC4000024U |
| 19 | #define SDEI_EVENT_COMPLETE 0xC4000025U |
| 20 | #define SDEI_EVENT_COMPLETE_AND_RESUME 0xC4000026U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 21 | |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 22 | #define SDEI_EVENT_UNREGISTER 0xC4000027U |
| 23 | #define SDEI_EVENT_STATUS 0xC4000028U |
| 24 | #define SDEI_EVENT_GET_INFO 0xC4000029U |
| 25 | #define SDEI_EVENT_ROUTING_SET 0xC400002AU |
| 26 | #define SDEI_PE_MASK 0xC400002BU |
| 27 | #define SDEI_PE_UNMASK 0xC400002CU |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 28 | |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 29 | #define SDEI_INTERRUPT_BIND 0xC400002DU |
| 30 | #define SDEI_INTERRUPT_RELEASE 0xC400002EU |
| 31 | #define SDEI_EVENT_SIGNAL 0xC400002FU |
| 32 | #define SDEI_FEATURES 0xC4000030U |
| 33 | #define SDEI_PRIVATE_RESET 0xC4000031U |
| 34 | #define SDEI_SHARED_RESET 0xC4000032U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 35 | |
| 36 | /* SDEI_EVENT_REGISTER flags */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 37 | #define SDEI_REGF_RM_ANY 0ULL |
| 38 | #define SDEI_REGF_RM_PE 1ULL |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 39 | |
| 40 | /* SDEI_EVENT_COMPLETE status flags */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 41 | #define SDEI_EV_HANDLED 0U |
| 42 | #define SDEI_EV_FAILED 1U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 43 | |
| 44 | /* Internal: SDEI flag bit positions */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 45 | #define SDEI_MAPF_DYNAMIC_SHIFT_ 1U |
| 46 | #define SDEI_MAPF_BOUND_SHIFT_ 2U |
| 47 | #define SDEI_MAPF_SIGNALABLE_SHIFT_ 3U |
| 48 | #define SDEI_MAPF_PRIVATE_SHIFT_ 4U |
| 49 | #define SDEI_MAPF_CRITICAL_SHIFT_ 5U |
| 50 | #define SDEI_MAPF_EXPLICIT_SHIFT_ 6U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 51 | |
| 52 | /* SDEI event 0 */ |
| 53 | #define SDEI_EVENT_0 0 |
| 54 | |
| 55 | /* Placeholder interrupt for dynamic mapping */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 56 | #define SDEI_DYN_IRQ 0U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 57 | |
| 58 | /* SDEI flags */ |
| 59 | |
| 60 | /* |
| 61 | * These flags determine whether or not an event can be associated with an |
| 62 | * interrupt. Static events are permanently associated with an interrupt, and |
| 63 | * can't be changed at runtime. Association of dynamic events with interrupts |
| 64 | * can be changed at run time using the SDEI_INTERRUPT_BIND and |
| 65 | * SDEI_INTERRUPT_RELEASE calls. |
| 66 | * |
| 67 | * SDEI_MAPF_DYNAMIC only indicates run time configurability, where as |
| 68 | * SDEI_MAPF_BOUND indicates interrupt association. For example: |
| 69 | * |
| 70 | * - Calling SDEI_INTERRUPT_BIND on a dynamic event will have both |
| 71 | * SDEI_MAPF_DYNAMIC and SDEI_MAPF_BOUND set. |
| 72 | * |
| 73 | * - Statically-bound events will always have SDEI_MAPF_BOUND set, and neither |
| 74 | * SDEI_INTERRUPT_BIND nor SDEI_INTERRUPT_RELEASE can be called on them. |
| 75 | * |
| 76 | * See also the is_map_bound() macro. |
| 77 | */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 78 | #define SDEI_MAPF_DYNAMIC BIT(SDEI_MAPF_DYNAMIC_SHIFT_) |
| 79 | #define SDEI_MAPF_BOUND BIT(SDEI_MAPF_BOUND_SHIFT_) |
| 80 | #define SDEI_MAPF_EXPLICIT BIT(SDEI_MAPF_EXPLICIT_SHIFT_) |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 81 | |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 82 | #define SDEI_MAPF_SIGNALABLE BIT(SDEI_MAPF_SIGNALABLE_SHIFT_) |
| 83 | #define SDEI_MAPF_PRIVATE BIT(SDEI_MAPF_PRIVATE_SHIFT_) |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 84 | |
| 85 | #define SDEI_MAPF_NORMAL 0 |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 86 | #define SDEI_MAPF_CRITICAL BIT(SDEI_MAPF_CRITICAL_SHIFT_) |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 87 | |
| 88 | /* Indices of private and shared mappings */ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 89 | #define SDEI_MAP_IDX_PRIV_ 0U |
| 90 | #define SDEI_MAP_IDX_SHRD_ 1U |
| 91 | #define SDEI_MAP_IDX_MAX_ 2U |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 92 | |
| 93 | /* The macros below are used to identify SDEI calls from the SMC function ID */ |
| 94 | #define SDEI_FID_MASK U(0xffe0) |
| 95 | #define SDEI_FID_VALUE U(0x20) |
| 96 | #define is_sdei_fid(_fid) \ |
| 97 | ((((_fid) & SDEI_FID_MASK) == SDEI_FID_VALUE) && \ |
| 98 | (((_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_64)) |
| 99 | |
| 100 | #define SDEI_EVENT_MAP(_event, _intr, _flags) \ |
| 101 | { \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 102 | .ev_num = (_event), \ |
| 103 | .intr = (_intr), \ |
| 104 | .map_flags = (_flags) \ |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | #define SDEI_SHARED_EVENT(_event, _intr, _flags) \ |
| 108 | SDEI_EVENT_MAP(_event, _intr, _flags) |
| 109 | |
| 110 | #define SDEI_PRIVATE_EVENT(_event, _intr, _flags) \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 111 | SDEI_EVENT_MAP(_event, _intr, (_flags) | SDEI_MAPF_PRIVATE) |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 112 | |
| 113 | #define SDEI_DEFINE_EVENT_0(_intr) \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 114 | SDEI_PRIVATE_EVENT(SDEI_EVENT_0, (_intr), SDEI_MAPF_SIGNALABLE) |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 115 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 116 | #define SDEI_EXPLICIT_EVENT(_event, _pri) \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 117 | SDEI_EVENT_MAP((_event), 0, (_pri) | SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE) |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 118 | |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 119 | /* |
| 120 | * Declare shared and private entries for each core. Also declare a global |
| 121 | * structure containing private and share entries. |
| 122 | * |
| 123 | * This macro must be used in the same file as the platform SDEI mappings are |
| 124 | * declared. Only then would ARRAY_SIZE() yield a meaningful value. |
| 125 | */ |
| 126 | #define REGISTER_SDEI_MAP(_private, _shared) \ |
| 127 | sdei_entry_t sdei_private_event_table \ |
| 128 | [PLATFORM_CORE_COUNT * ARRAY_SIZE(_private)]; \ |
| 129 | sdei_entry_t sdei_shared_event_table[ARRAY_SIZE(_shared)]; \ |
| 130 | const sdei_mapping_t sdei_global_mappings[] = { \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 131 | [SDEI_MAP_IDX_PRIV_] = { \ |
| 132 | .map = (_private), \ |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 133 | .num_maps = ARRAY_SIZE(_private) \ |
| 134 | }, \ |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 135 | [SDEI_MAP_IDX_SHRD_] = { \ |
| 136 | .map = (_shared), \ |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 137 | .num_maps = ARRAY_SIZE(_shared) \ |
| 138 | }, \ |
| 139 | } |
| 140 | |
| 141 | typedef uint8_t sdei_state_t; |
| 142 | |
| 143 | /* Runtime data of SDEI event */ |
| 144 | typedef struct sdei_entry { |
| 145 | uint64_t ep; /* Entry point */ |
| 146 | uint64_t arg; /* Entry point argument */ |
| 147 | uint64_t affinity; /* Affinity of shared event */ |
| 148 | unsigned int reg_flags; /* Registration flags */ |
| 149 | |
| 150 | /* Event handler states: registered, enabled, running */ |
| 151 | sdei_state_t state; |
| 152 | } sdei_entry_t; |
| 153 | |
| 154 | /* Mapping of SDEI events to interrupts, and associated data */ |
| 155 | typedef struct sdei_ev_map { |
| 156 | int32_t ev_num; /* Event number */ |
| 157 | unsigned int intr; /* Physical interrupt number for a bound map */ |
| 158 | unsigned int map_flags; /* Mapping flags, see SDEI_MAPF_* */ |
Jeenu Viswambharan | 2b4054d | 2017-11-14 15:35:41 +0000 | [diff] [blame] | 159 | int reg_count; /* Registration count */ |
Jeenu Viswambharan | 04e3a7f | 2017-10-16 08:43:14 +0100 | [diff] [blame] | 160 | spinlock_t lock; /* Per-event lock */ |
| 161 | } sdei_ev_map_t; |
| 162 | |
| 163 | typedef struct sdei_mapping { |
| 164 | sdei_ev_map_t *map; |
| 165 | size_t num_maps; |
| 166 | } sdei_mapping_t; |
| 167 | |
| 168 | /* Handler to be called to handle SDEI smc calls */ |
| 169 | uint64_t sdei_smc_handler(uint32_t smc_fid, |
| 170 | uint64_t x1, |
| 171 | uint64_t x2, |
| 172 | uint64_t x3, |
| 173 | uint64_t x4, |
| 174 | void *cookie, |
| 175 | void *handle, |
| 176 | uint64_t flags); |
| 177 | |
| 178 | void sdei_init(void); |
| 179 | |
Jeenu Viswambharan | cf1f221 | 2017-10-02 12:10:54 +0100 | [diff] [blame] | 180 | /* Public API to dispatch an event to Normal world */ |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 181 | int sdei_dispatch_event(int ev_num); |
Jeenu Viswambharan | cf1f221 | 2017-10-02 12:10:54 +0100 | [diff] [blame] | 182 | |
Jeenu Viswambharan | 32ceef5 | 2018-08-02 10:14:12 +0100 | [diff] [blame] | 183 | #endif /* SDEI_H */ |