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