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