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