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