xref: /rk3399_ARM-atf/services/std_svc/sdei/sdei_main.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
1 /*
2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 #include <assert.h>
9 #include <bl31.h>
10 #include <bl_common.h>
11 #include <cassert.h>
12 #include <context.h>
13 #include <context_mgmt.h>
14 #include <debug.h>
15 #include <ehf.h>
16 #include <interrupt_mgmt.h>
17 #include <platform.h>
18 #include <pubsub.h>
19 #include <runtime_svc.h>
20 #include <sdei.h>
21 #include <stddef.h>
22 #include <string.h>
23 #include <utils.h>
24 #include "sdei_private.h"
25 
26 #define MAJOR_VERSION	1
27 #define MINOR_VERSION	0
28 #define VENDOR_VERSION	0
29 
30 #define MAKE_SDEI_VERSION(_major, _minor, _vendor) \
31 	((((unsigned long long)(_major)) << 48) | \
32 	 (((unsigned long long)(_minor)) << 32) | \
33 	 (_vendor))
34 
35 #define LOWEST_INTR_PRIORITY		0xff
36 
37 #define is_valid_affinity(_mpidr)	(plat_core_pos_by_mpidr(_mpidr) >= 0)
38 
39 CASSERT(PLAT_SDEI_CRITICAL_PRI < PLAT_SDEI_NORMAL_PRI,
40 		sdei_critical_must_have_higher_priority);
41 
42 static unsigned int num_dyn_priv_slots, num_dyn_shrd_slots;
43 
44 /* Initialise SDEI map entries */
45 static void init_map(sdei_ev_map_t *map)
46 {
47 	map->reg_count = 0;
48 }
49 
50 /* Convert mapping to SDEI class */
51 sdei_class_t map_to_class(sdei_ev_map_t *map)
52 {
53 	return is_event_critical(map) ? SDEI_CRITICAL : SDEI_NORMAL;
54 }
55 
56 /* Clear SDEI event entries except state */
57 static void clear_event_entries(sdei_entry_t *se)
58 {
59 	se->ep = 0;
60 	se->arg = 0;
61 	se->affinity = 0;
62 	se->reg_flags = 0;
63 }
64 
65 /* Perform CPU-specific state initialisation */
66 static void *sdei_cpu_on_init(const void *arg)
67 {
68 	int i;
69 	sdei_ev_map_t *map;
70 	sdei_entry_t *se;
71 
72 	/* Initialize private mappings on this CPU */
73 	for_each_private_map(i, map) {
74 		se = get_event_entry(map);
75 		clear_event_entries(se);
76 		se->state = 0;
77 	}
78 
79 	SDEI_LOG("Private events initialized on %lx\n", read_mpidr_el1());
80 
81 	/* All PEs start with SDEI events masked */
82 	sdei_pe_mask();
83 
84 	return 0;
85 }
86 
87 /* Initialise an SDEI class */
88 void sdei_class_init(sdei_class_t class)
89 {
90 	unsigned int i, zero_found __unused = 0;
91 	int ev_num_so_far __unused;
92 	sdei_ev_map_t *map;
93 
94 	/* Sanity check and configuration of shared events */
95 	ev_num_so_far = -1;
96 	for_each_shared_map(i, map) {
97 #if ENABLE_ASSERTIONS
98 		/* Ensure mappings are sorted */
99 		assert((ev_num_so_far < 0) || (map->ev_num > ev_num_so_far));
100 
101 		ev_num_so_far = map->ev_num;
102 
103 		/* Event 0 must not be shared */
104 		assert(map->ev_num != SDEI_EVENT_0);
105 
106 		/* Check for valid event */
107 		assert(map->ev_num >= 0);
108 
109 		/* Make sure it's a shared event */
110 		assert(is_event_shared(map));
111 
112 		/* No shared mapping should have signalable property */
113 		assert(!is_event_signalable(map));
114 #endif
115 
116 		/* Skip initializing the wrong priority */
117 		if (map_to_class(map) != class)
118 			continue;
119 
120 		/* Platform events are always bound, so set the bound flag */
121 		if (is_map_dynamic(map)) {
122 			assert(map->intr == SDEI_DYN_IRQ);
123 			assert(is_event_normal(map));
124 			num_dyn_shrd_slots++;
125 		} else {
126 			/* Shared mappings must be bound to shared interrupt */
127 			assert(plat_ic_is_spi(map->intr));
128 			set_map_bound(map);
129 		}
130 
131 		init_map(map);
132 	}
133 
134 	/* Sanity check and configuration of private events for this CPU */
135 	ev_num_so_far = -1;
136 	for_each_private_map(i, map) {
137 #if ENABLE_ASSERTIONS
138 		/* Ensure mappings are sorted */
139 		assert((ev_num_so_far < 0) || (map->ev_num > ev_num_so_far));
140 
141 		ev_num_so_far = map->ev_num;
142 
143 		if (map->ev_num == SDEI_EVENT_0) {
144 			zero_found = 1;
145 
146 			/* Event 0 must be a Secure SGI */
147 			assert(is_secure_sgi(map->intr));
148 
149 			/*
150 			 * Event 0 can have only have signalable flag (apart
151 			 * from being private
152 			 */
153 			assert(map->map_flags == (SDEI_MAPF_SIGNALABLE |
154 						SDEI_MAPF_PRIVATE));
155 		} else {
156 			/* No other mapping should have signalable property */
157 			assert(!is_event_signalable(map));
158 		}
159 
160 		/* Check for valid event */
161 		assert(map->ev_num >= 0);
162 
163 		/* Make sure it's a private event */
164 		assert(is_event_private(map));
165 #endif
166 
167 		/* Skip initializing the wrong priority */
168 		if (map_to_class(map) != class)
169 			continue;
170 
171 		/* Platform events are always bound, so set the bound flag */
172 		if (map->ev_num != SDEI_EVENT_0) {
173 			if (is_map_dynamic(map)) {
174 				assert(map->intr == SDEI_DYN_IRQ);
175 				assert(is_event_normal(map));
176 				num_dyn_priv_slots++;
177 			} else {
178 				/*
179 				 * Private mappings must be bound to private
180 				 * interrupt.
181 				 */
182 				assert(plat_ic_is_ppi(map->intr));
183 				set_map_bound(map);
184 			}
185 		}
186 
187 		init_map(map);
188 	}
189 
190 	/* Ensure event 0 is in the mapping */
191 	assert(zero_found);
192 
193 	sdei_cpu_on_init(NULL);
194 }
195 
196 /* SDEI dispatcher initialisation */
197 void sdei_init(void)
198 {
199 	sdei_class_init(SDEI_CRITICAL);
200 	sdei_class_init(SDEI_NORMAL);
201 
202 	/* Register priority level handlers */
203 	ehf_register_priority_handler(PLAT_SDEI_CRITICAL_PRI,
204 			sdei_intr_handler);
205 	ehf_register_priority_handler(PLAT_SDEI_NORMAL_PRI,
206 			sdei_intr_handler);
207 }
208 
209 /* Populate SDEI event entry */
210 static void set_sdei_entry(sdei_entry_t *se, uint64_t ep, uint64_t arg,
211 		unsigned int flags, uint64_t affinity)
212 {
213 	assert(se != NULL);
214 
215 	se->ep = ep;
216 	se->arg = arg;
217 	se->affinity = (affinity & MPIDR_AFFINITY_MASK);
218 	se->reg_flags = flags;
219 }
220 
221 static unsigned long long sdei_version(void)
222 {
223 	return MAKE_SDEI_VERSION(MAJOR_VERSION, MINOR_VERSION, VENDOR_VERSION);
224 }
225 
226 /* Validate flags and MPIDR values for REGISTER and ROUTING_SET calls */
227 static int validate_flags(uint64_t flags, uint64_t mpidr)
228 {
229 	/* Validate flags */
230 	switch (flags) {
231 	case SDEI_REGF_RM_PE:
232 		if (!is_valid_affinity(mpidr))
233 			return SDEI_EINVAL;
234 		break;
235 	case SDEI_REGF_RM_ANY:
236 		break;
237 	default:
238 		/* Unknown flags */
239 		return SDEI_EINVAL;
240 	}
241 
242 	return 0;
243 }
244 
245 /* Set routing of an SDEI event */
246 static int sdei_event_routing_set(int ev_num, uint64_t flags, uint64_t mpidr)
247 {
248 	int ret, routing;
249 	sdei_ev_map_t *map;
250 	sdei_entry_t *se;
251 
252 	ret = validate_flags(flags, mpidr);
253 	if (ret)
254 		return ret;
255 
256 	/* Check if valid event number */
257 	map = find_event_map(ev_num);
258 	if (!map)
259 		return SDEI_EINVAL;
260 
261 	/* The event must not be private */
262 	if (is_event_private(map))
263 		return SDEI_EINVAL;
264 
265 	se = get_event_entry(map);
266 
267 	sdei_map_lock(map);
268 
269 	if (!is_map_bound(map) || is_event_private(map)) {
270 		ret = SDEI_EINVAL;
271 		goto finish;
272 	}
273 
274 	if (!can_sdei_state_trans(se, DO_ROUTING)) {
275 		ret = SDEI_EDENY;
276 		goto finish;
277 	}
278 
279 	/* Choose appropriate routing */
280 	routing = (flags == SDEI_REGF_RM_ANY) ? INTR_ROUTING_MODE_ANY :
281 		INTR_ROUTING_MODE_PE;
282 
283 	/* Update event registration flag */
284 	se->reg_flags = flags;
285 
286 	/*
287 	 * ROUTING_SET is permissible only when event composite state is
288 	 * 'registered, disabled, and not running'. This means that the
289 	 * interrupt is currently disabled, and not active.
290 	 */
291 	plat_ic_set_spi_routing(map->intr, routing, (u_register_t) mpidr);
292 
293 finish:
294 	sdei_map_unlock(map);
295 
296 	return ret;
297 }
298 
299 /* Register handler and argument for an SDEI event */
300 static int sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
301 		uint64_t flags, uint64_t mpidr)
302 {
303 	int ret;
304 	sdei_entry_t *se;
305 	sdei_ev_map_t *map;
306 	sdei_state_t backup_state;
307 
308 	if (!ep || (plat_sdei_validate_entry_point(ep, sdei_client_el()) != 0))
309 		return SDEI_EINVAL;
310 
311 	ret = validate_flags(flags, mpidr);
312 	if (ret)
313 		return ret;
314 
315 	/* Check if valid event number */
316 	map = find_event_map(ev_num);
317 	if (!map)
318 		return SDEI_EINVAL;
319 
320 	/* Private events always target the PE */
321 	if (is_event_private(map))
322 		flags = SDEI_REGF_RM_PE;
323 
324 	se = get_event_entry(map);
325 
326 	/*
327 	 * Even though register operation is per-event (additionally for private
328 	 * events, registration is required individually), it has to be
329 	 * serialised with respect to bind/release, which are global operations.
330 	 * So we hold the lock throughout, unconditionally.
331 	 */
332 	sdei_map_lock(map);
333 
334 	backup_state = se->state;
335 	if (!can_sdei_state_trans(se, DO_REGISTER))
336 		goto fallback;
337 
338 	/*
339 	 * When registering for dynamic events, make sure it's been bound
340 	 * already. This has to be the case as, without binding, the client
341 	 * can't know about the event number to register for.
342 	 */
343 	if (is_map_dynamic(map) && !is_map_bound(map))
344 		goto fallback;
345 
346 	if (is_event_private(map)) {
347 		/* Multiple calls to register are possible for private events */
348 		assert(map->reg_count >= 0);
349 	} else {
350 		/* Only single call to register is possible for shared events */
351 		assert(map->reg_count == 0);
352 	}
353 
354 	if (is_map_bound(map)) {
355 		/* Meanwhile, did any PE ACK the interrupt? */
356 		if (plat_ic_get_interrupt_active(map->intr))
357 			goto fallback;
358 
359 		/* The interrupt must currently owned by Non-secure */
360 		if (plat_ic_get_interrupt_type(map->intr) != INTR_TYPE_NS)
361 			goto fallback;
362 
363 		/*
364 		 * Disable forwarding of new interrupt triggers to CPU
365 		 * interface.
366 		 */
367 		plat_ic_disable_interrupt(map->intr);
368 
369 		/*
370 		 * Any events that are triggered after register and before
371 		 * enable should remain pending. Clear any previous interrupt
372 		 * triggers which are pending (except for SGIs). This has no
373 		 * affect on level-triggered interrupts.
374 		 */
375 		if (ev_num != SDEI_EVENT_0)
376 			plat_ic_clear_interrupt_pending(map->intr);
377 
378 		/* Map interrupt to EL3 and program the correct priority */
379 		plat_ic_set_interrupt_type(map->intr, INTR_TYPE_EL3);
380 
381 		/* Program the appropriate interrupt priority */
382 		plat_ic_set_interrupt_priority(map->intr, sdei_event_priority(map));
383 
384 		/*
385 		 * Set the routing mode for shared event as requested. We
386 		 * already ensure that shared events get bound to SPIs.
387 		 */
388 		if (is_event_shared(map)) {
389 			plat_ic_set_spi_routing(map->intr,
390 					((flags == SDEI_REGF_RM_ANY) ?
391 					 INTR_ROUTING_MODE_ANY :
392 					 INTR_ROUTING_MODE_PE),
393 					(u_register_t) mpidr);
394 		}
395 	}
396 
397 	/* Populate event entries */
398 	set_sdei_entry(se, ep, arg, flags, mpidr);
399 
400 	/* Increment register count */
401 	map->reg_count++;
402 
403 	sdei_map_unlock(map);
404 
405 	return 0;
406 
407 fallback:
408 	/* Reinstate previous state */
409 	se->state = backup_state;
410 
411 	sdei_map_unlock(map);
412 
413 	return SDEI_EDENY;
414 }
415 
416 /* Enable SDEI event */
417 static int sdei_event_enable(int ev_num)
418 {
419 	sdei_ev_map_t *map;
420 	sdei_entry_t *se;
421 	int ret, before, after;
422 
423 	/* Check if valid event number */
424 	map = find_event_map(ev_num);
425 	if (!map)
426 		return SDEI_EINVAL;
427 
428 	se = get_event_entry(map);
429 	ret = SDEI_EDENY;
430 
431 	if (is_event_shared(map))
432 		sdei_map_lock(map);
433 
434 	before = GET_EV_STATE(se, ENABLED);
435 	if (!can_sdei_state_trans(se, DO_ENABLE))
436 		goto finish;
437 	after = GET_EV_STATE(se, ENABLED);
438 
439 	/*
440 	 * Enable interrupt for bound events only if there's a change in enabled
441 	 * state.
442 	 */
443 	if (is_map_bound(map) && (!before && after))
444 		plat_ic_enable_interrupt(map->intr);
445 
446 	ret = 0;
447 
448 finish:
449 	if (is_event_shared(map))
450 		sdei_map_unlock(map);
451 
452 	return ret;
453 }
454 
455 /* Disable SDEI event */
456 static int sdei_event_disable(int ev_num)
457 {
458 	sdei_ev_map_t *map;
459 	sdei_entry_t *se;
460 	int ret, before, after;
461 
462 	/* Check if valid event number */
463 	map = find_event_map(ev_num);
464 	if (!map)
465 		return SDEI_EINVAL;
466 
467 	se = get_event_entry(map);
468 	ret = SDEI_EDENY;
469 
470 	if (is_event_shared(map))
471 		sdei_map_lock(map);
472 
473 	before = GET_EV_STATE(se, ENABLED);
474 	if (!can_sdei_state_trans(se, DO_DISABLE))
475 		goto finish;
476 	after = GET_EV_STATE(se, ENABLED);
477 
478 	/*
479 	 * Disable interrupt for bound events only if there's a change in
480 	 * enabled state.
481 	 */
482 	if (is_map_bound(map) && (before && !after))
483 		plat_ic_disable_interrupt(map->intr);
484 
485 	ret = 0;
486 
487 finish:
488 	if (is_event_shared(map))
489 		sdei_map_unlock(map);
490 
491 	return ret;
492 }
493 
494 /* Query SDEI event information */
495 static uint64_t sdei_event_get_info(int ev_num, int info)
496 {
497 	sdei_entry_t *se;
498 	sdei_ev_map_t *map;
499 
500 	unsigned int flags, registered;
501 	uint64_t affinity;
502 
503 	/* Check if valid event number */
504 	map = find_event_map(ev_num);
505 	if (!map)
506 		return SDEI_EINVAL;
507 
508 	se = get_event_entry(map);
509 
510 	if (is_event_shared(map))
511 		sdei_map_lock(map);
512 
513 	/* Sample state under lock */
514 	registered = GET_EV_STATE(se, REGISTERED);
515 	flags = se->reg_flags;
516 	affinity = se->affinity;
517 
518 	if (is_event_shared(map))
519 		sdei_map_unlock(map);
520 
521 	switch (info) {
522 	case SDEI_INFO_EV_TYPE:
523 		return is_event_shared(map);
524 
525 	case SDEI_INFO_EV_NOT_SIGNALED:
526 		return !is_event_signalable(map);
527 
528 	case SDEI_INFO_EV_PRIORITY:
529 		return is_event_critical(map);
530 
531 	case SDEI_INFO_EV_ROUTING_MODE:
532 		if (!is_event_shared(map))
533 			return SDEI_EINVAL;
534 		if (!registered)
535 			return SDEI_EDENY;
536 		return (flags == SDEI_REGF_RM_PE);
537 
538 	case SDEI_INFO_EV_ROUTING_AFF:
539 		if (!is_event_shared(map))
540 			return SDEI_EINVAL;
541 		if (!registered)
542 			return SDEI_EDENY;
543 		if (flags != SDEI_REGF_RM_PE)
544 			return SDEI_EINVAL;
545 		return affinity;
546 
547 	default:
548 		return SDEI_EINVAL;
549 	}
550 }
551 
552 /* Unregister an SDEI event */
553 static int sdei_event_unregister(int ev_num)
554 {
555 	int ret = 0;
556 	sdei_entry_t *se;
557 	sdei_ev_map_t *map;
558 
559 	/* Check if valid event number */
560 	map = find_event_map(ev_num);
561 	if (!map)
562 		return SDEI_EINVAL;
563 
564 	se = get_event_entry(map);
565 
566 	/*
567 	 * Even though unregister operation is per-event (additionally for
568 	 * private events, unregistration is required individually), it has to
569 	 * be serialised with respect to bind/release, which are global
570 	 * operations.  So we hold the lock throughout, unconditionally.
571 	 */
572 	sdei_map_lock(map);
573 
574 	if (!can_sdei_state_trans(se, DO_UNREGISTER)) {
575 		/*
576 		 * Even if the call is invalid, and the handler is running (for
577 		 * example, having unregistered from a running handler earlier),
578 		 * return pending error code; otherwise, return deny.
579 		 */
580 		ret = GET_EV_STATE(se, RUNNING) ? SDEI_EPEND : SDEI_EDENY;
581 
582 		goto finish;
583 	}
584 
585 	map->reg_count--;
586 	if (is_event_private(map)) {
587 		/* Multiple calls to register are possible for private events */
588 		assert(map->reg_count >= 0);
589 	} else {
590 		/* Only single call to register is possible for shared events */
591 		assert(map->reg_count == 0);
592 	}
593 
594 	if (is_map_bound(map)) {
595 		plat_ic_disable_interrupt(map->intr);
596 
597 		/*
598 		 * Clear pending interrupt. Skip for SGIs as they may not be
599 		 * cleared on interrupt controllers.
600 		 */
601 		if (ev_num != SDEI_EVENT_0)
602 			plat_ic_clear_interrupt_pending(map->intr);
603 
604 		assert(plat_ic_get_interrupt_type(map->intr) == INTR_TYPE_EL3);
605 		plat_ic_set_interrupt_type(map->intr, INTR_TYPE_NS);
606 		plat_ic_set_interrupt_priority(map->intr, LOWEST_INTR_PRIORITY);
607 	}
608 
609 	clear_event_entries(se);
610 
611 	/*
612 	 * If the handler is running at the time of unregister, return the
613 	 * pending error code.
614 	 */
615 	if (GET_EV_STATE(se, RUNNING))
616 		ret = SDEI_EPEND;
617 
618 finish:
619 	sdei_map_unlock(map);
620 
621 	return ret;
622 }
623 
624 /* Query status of an SDEI event */
625 static int sdei_event_status(int ev_num)
626 {
627 	sdei_ev_map_t *map;
628 	sdei_entry_t *se;
629 	sdei_state_t state;
630 
631 	/* Check if valid event number */
632 	map = find_event_map(ev_num);
633 	if (!map)
634 		return SDEI_EINVAL;
635 
636 	se = get_event_entry(map);
637 
638 	if (is_event_shared(map))
639 		sdei_map_lock(map);
640 
641 	/* State value directly maps to the expected return format */
642 	state = se->state;
643 
644 	if (is_event_shared(map))
645 		sdei_map_unlock(map);
646 
647 	return state;
648 }
649 
650 /* Bind an SDEI event to an interrupt */
651 static int sdei_interrupt_bind(int intr_num)
652 {
653 	sdei_ev_map_t *map;
654 	int retry = 1, shared_mapping;
655 
656 	/* SGIs are not allowed to be bound */
657 	if (plat_ic_is_sgi(intr_num))
658 		return SDEI_EINVAL;
659 
660 	shared_mapping = plat_ic_is_spi(intr_num);
661 	do {
662 		/*
663 		 * Bail out if there is already an event for this interrupt,
664 		 * either platform-defined or dynamic.
665 		 */
666 		map = find_event_map_by_intr(intr_num, shared_mapping);
667 		if (map) {
668 			if (is_map_dynamic(map)) {
669 				if (is_map_bound(map)) {
670 					/*
671 					 * Dynamic event, already bound. Return
672 					 * event number.
673 					 */
674 					return map->ev_num;
675 				}
676 			} else {
677 				/* Binding non-dynamic event */
678 				return SDEI_EINVAL;
679 			}
680 		}
681 
682 		/*
683 		 * The interrupt is not bound yet. Try to find a free slot to
684 		 * bind it. Free dynamic mappings have their interrupt set as
685 		 * SDEI_DYN_IRQ.
686 		 */
687 		map = find_event_map_by_intr(SDEI_DYN_IRQ, shared_mapping);
688 		if (!map)
689 			return SDEI_ENOMEM;
690 
691 		/* The returned mapping must be dynamic */
692 		assert(is_map_dynamic(map));
693 
694 		/*
695 		 * We cannot assert for bound maps here, as we might be racing
696 		 * with another bind.
697 		 */
698 
699 		/* The requested interrupt must already belong to NS */
700 		if (plat_ic_get_interrupt_type(intr_num) != INTR_TYPE_NS)
701 			return SDEI_EDENY;
702 
703 		/*
704 		 * Interrupt programming and ownership transfer are deferred
705 		 * until register.
706 		 */
707 
708 		sdei_map_lock(map);
709 		if (!is_map_bound(map)) {
710 			map->intr = intr_num;
711 			set_map_bound(map);
712 			retry = 0;
713 		}
714 		sdei_map_unlock(map);
715 	} while (retry);
716 
717 	return map->ev_num;
718 }
719 
720 /* Release a bound SDEI event previously to an interrupt */
721 static int sdei_interrupt_release(int ev_num)
722 {
723 	int ret = 0;
724 	sdei_ev_map_t *map;
725 	sdei_entry_t *se;
726 
727 	/* Check if valid event number */
728 	map = find_event_map(ev_num);
729 	if (!map)
730 		return SDEI_EINVAL;
731 
732 	if (!is_map_dynamic(map))
733 		return SDEI_EINVAL;
734 
735 	se = get_event_entry(map);
736 
737 	sdei_map_lock(map);
738 
739 	/* Event must have been unregistered before release */
740 	if (map->reg_count != 0) {
741 		ret = SDEI_EDENY;
742 		goto finish;
743 	}
744 
745 	/*
746 	 * Interrupt release never causes the state to change. We only check
747 	 * whether it's permissible or not.
748 	 */
749 	if (!can_sdei_state_trans(se, DO_RELEASE)) {
750 		ret = SDEI_EDENY;
751 		goto finish;
752 	}
753 
754 	if (is_map_bound(map)) {
755 		/*
756 		 * Deny release if the interrupt is active, which means it's
757 		 * probably being acknowledged and handled elsewhere.
758 		 */
759 		if (plat_ic_get_interrupt_active(map->intr)) {
760 			ret = SDEI_EDENY;
761 			goto finish;
762 		}
763 
764 		/*
765 		 * Interrupt programming and ownership transfer are already done
766 		 * during unregister.
767 		 */
768 
769 		map->intr = SDEI_DYN_IRQ;
770 		clr_map_bound(map);
771 	} else {
772 		SDEI_LOG("Error release bound:%d cnt:%d\n", is_map_bound(map),
773 				map->reg_count);
774 		ret = SDEI_EINVAL;
775 	}
776 
777 finish:
778 	sdei_map_unlock(map);
779 
780 	return ret;
781 }
782 
783 /* Perform reset of private SDEI events */
784 static int sdei_private_reset(void)
785 {
786 	sdei_ev_map_t *map;
787 	int ret = 0, final_ret = 0, i;
788 
789 	/* Unregister all private events */
790 	for_each_private_map(i, map) {
791 		/*
792 		 * The unregister can fail if the event is not registered, which
793 		 * is allowed, and a deny will be returned. But if the event is
794 		 * running or unregister pending, the call fails.
795 		 */
796 		ret = sdei_event_unregister(map->ev_num);
797 		if ((ret == SDEI_EPEND) && (final_ret == 0))
798 			final_ret = SDEI_EDENY;
799 	}
800 
801 	return final_ret;
802 }
803 
804 /* Perform reset of shared SDEI events */
805 static int sdei_shared_reset(void)
806 {
807 	const sdei_mapping_t *mapping;
808 	sdei_ev_map_t *map;
809 	int ret = 0, final_ret = 0, i, j;
810 
811 	/* Unregister all shared events */
812 	for_each_shared_map(i, map) {
813 		/*
814 		 * The unregister can fail if the event is not registered, which
815 		 * is allowed, and a deny will be returned. But if the event is
816 		 * running or unregister pending, the call fails.
817 		 */
818 		ret = sdei_event_unregister(map->ev_num);
819 		if ((ret == SDEI_EPEND) && (final_ret == 0))
820 			final_ret = SDEI_EDENY;
821 	}
822 
823 	if (final_ret != 0)
824 		return final_ret;
825 
826 	/*
827 	 * Loop through both private and shared mappings, and release all
828 	 * bindings.
829 	 */
830 	for_each_mapping_type(i, mapping) {
831 		iterate_mapping(mapping, j, map) {
832 			/*
833 			 * Release bindings for mappings that are dynamic and
834 			 * bound.
835 			 */
836 			if (is_map_dynamic(map) && is_map_bound(map)) {
837 				/*
838 				 * Any failure to release would mean there is at
839 				 * least a PE registered for the event.
840 				 */
841 				ret = sdei_interrupt_release(map->ev_num);
842 				if ((ret != 0) && (final_ret == 0))
843 					final_ret = ret;
844 			}
845 		}
846 	}
847 
848 	return final_ret;
849 }
850 
851 /* Send a signal to another SDEI client PE */
852 int sdei_signal(int event, uint64_t target_pe)
853 {
854 	sdei_ev_map_t *map;
855 
856 	/* Only event 0 can be signalled */
857 	if (event != SDEI_EVENT_0)
858 		return SDEI_EINVAL;
859 
860 	/* Find mapping for event 0 */
861 	map = find_event_map(SDEI_EVENT_0);
862 	if (!map)
863 		return SDEI_EINVAL;
864 
865 	/* The event must be signalable */
866 	if (!is_event_signalable(map))
867 		return SDEI_EINVAL;
868 
869 	/* Validate target */
870 	if (plat_core_pos_by_mpidr(target_pe) < 0)
871 		return SDEI_EINVAL;
872 
873 	/* Raise SGI. Platform will validate target_pe */
874 	plat_ic_raise_el3_sgi(map->intr, (u_register_t) target_pe);
875 
876 	return 0;
877 }
878 
879 /* Query SDEI dispatcher features */
880 uint64_t sdei_features(unsigned int feature)
881 {
882 	if (feature == SDEI_FEATURE_BIND_SLOTS) {
883 		return FEATURE_BIND_SLOTS(num_dyn_priv_slots,
884 				num_dyn_shrd_slots);
885 	}
886 
887 	return SDEI_EINVAL;
888 }
889 
890 /* SDEI top level handler for servicing SMCs */
891 uint64_t sdei_smc_handler(uint32_t smc_fid,
892 			  uint64_t x1,
893 			  uint64_t x2,
894 			  uint64_t x3,
895 			  uint64_t x4,
896 			  void *cookie,
897 			  void *handle,
898 			  uint64_t flags)
899 {
900 
901 	uint64_t x5;
902 	int ss = get_interrupt_src_ss(flags);
903 	int64_t ret;
904 	unsigned int resume = 0;
905 
906 	if (ss != NON_SECURE)
907 		SMC_RET1(handle, SMC_UNK);
908 
909 	/* Verify the caller EL */
910 	if (GET_EL(read_spsr_el3()) != sdei_client_el())
911 		SMC_RET1(handle, SMC_UNK);
912 
913 	switch (smc_fid) {
914 	case SDEI_VERSION:
915 		SDEI_LOG("> VER\n");
916 		ret = sdei_version();
917 		SDEI_LOG("< VER:%lx\n", ret);
918 		SMC_RET1(handle, ret);
919 
920 	case SDEI_EVENT_REGISTER:
921 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
922 		SDEI_LOG("> REG(n:%d e:%lx a:%lx f:%x m:%lx)\n", (int) x1,
923 				x2, x3, (int) x4, x5);
924 		ret = sdei_event_register(x1, x2, x3, x4, x5);
925 		SDEI_LOG("< REG:%ld\n", ret);
926 		SMC_RET1(handle, ret);
927 
928 	case SDEI_EVENT_ENABLE:
929 		SDEI_LOG("> ENABLE(n:%d)\n", (int) x1);
930 		ret = sdei_event_enable(x1);
931 		SDEI_LOG("< ENABLE:%ld\n", ret);
932 		SMC_RET1(handle, ret);
933 
934 	case SDEI_EVENT_DISABLE:
935 		SDEI_LOG("> DISABLE(n:%d)\n", (int) x1);
936 		ret = sdei_event_disable(x1);
937 		SDEI_LOG("< DISABLE:%ld\n", ret);
938 		SMC_RET1(handle, ret);
939 
940 	case SDEI_EVENT_CONTEXT:
941 		SDEI_LOG("> CTX(p:%d):%lx\n", (int) x1, read_mpidr_el1());
942 		ret = sdei_event_context(handle, x1);
943 		SDEI_LOG("< CTX:%ld\n", ret);
944 		SMC_RET1(handle, ret);
945 
946 	case SDEI_EVENT_COMPLETE_AND_RESUME:
947 		resume = 1;
948 
949 	case SDEI_EVENT_COMPLETE:
950 		SDEI_LOG("> COMPLETE(r:%d sta/ep:%lx):%lx\n", resume, x1,
951 				read_mpidr_el1());
952 		ret = sdei_event_complete(resume, x1);
953 		SDEI_LOG("< COMPLETE:%lx\n", ret);
954 
955 		/*
956 		 * Set error code only if the call failed. If the call
957 		 * succeeded, we discard the dispatched context, and restore the
958 		 * interrupted context to a pristine condition, and therefore
959 		 * shouldn't be modified. We don't return to the caller in this
960 		 * case anyway.
961 		 */
962 		if (ret)
963 			SMC_RET1(handle, ret);
964 
965 		SMC_RET0(handle);
966 
967 	case SDEI_EVENT_STATUS:
968 		SDEI_LOG("> STAT(n:%d)\n", (int) x1);
969 		ret = sdei_event_status(x1);
970 		SDEI_LOG("< STAT:%ld\n", ret);
971 		SMC_RET1(handle, ret);
972 
973 	case SDEI_EVENT_GET_INFO:
974 		SDEI_LOG("> INFO(n:%d, %d)\n", (int) x1, (int) x2);
975 		ret = sdei_event_get_info(x1, x2);
976 		SDEI_LOG("< INFO:%ld\n", ret);
977 		SMC_RET1(handle, ret);
978 
979 	case SDEI_EVENT_UNREGISTER:
980 		SDEI_LOG("> UNREG(n:%d)\n", (int) x1);
981 		ret = sdei_event_unregister(x1);
982 		SDEI_LOG("< UNREG:%ld\n", ret);
983 		SMC_RET1(handle, ret);
984 
985 	case SDEI_PE_UNMASK:
986 		SDEI_LOG("> UNMASK:%lx\n", read_mpidr_el1());
987 		sdei_pe_unmask();
988 		SDEI_LOG("< UNMASK:%d\n", 0);
989 		SMC_RET1(handle, 0);
990 
991 	case SDEI_PE_MASK:
992 		SDEI_LOG("> MASK:%lx\n", read_mpidr_el1());
993 		ret = sdei_pe_mask();
994 		SDEI_LOG("< MASK:%ld\n", ret);
995 		SMC_RET1(handle, ret);
996 
997 	case SDEI_INTERRUPT_BIND:
998 		SDEI_LOG("> BIND(%d)\n", (int) x1);
999 		ret = sdei_interrupt_bind(x1);
1000 		SDEI_LOG("< BIND:%ld\n", ret);
1001 		SMC_RET1(handle, ret);
1002 
1003 	case SDEI_INTERRUPT_RELEASE:
1004 		SDEI_LOG("> REL(%d)\n", (int) x1);
1005 		ret = sdei_interrupt_release(x1);
1006 		SDEI_LOG("< REL:%ld\n", ret);
1007 		SMC_RET1(handle, ret);
1008 
1009 	case SDEI_SHARED_RESET:
1010 		SDEI_LOG("> S_RESET():%lx\n", read_mpidr_el1());
1011 		ret = sdei_shared_reset();
1012 		SDEI_LOG("< S_RESET:%ld\n", ret);
1013 		SMC_RET1(handle, ret);
1014 
1015 	case SDEI_PRIVATE_RESET:
1016 		SDEI_LOG("> P_RESET():%lx\n", read_mpidr_el1());
1017 		ret = sdei_private_reset();
1018 		SDEI_LOG("< P_RESET:%ld\n", ret);
1019 		SMC_RET1(handle, ret);
1020 
1021 	case SDEI_EVENT_ROUTING_SET:
1022 		SDEI_LOG("> ROUTE_SET(n:%d f:%lx aff:%lx)\n", (int) x1, x2, x3);
1023 		ret = sdei_event_routing_set(x1, x2, x3);
1024 		SDEI_LOG("< ROUTE_SET:%ld\n", ret);
1025 		SMC_RET1(handle, ret);
1026 
1027 	case SDEI_FEATURES:
1028 		SDEI_LOG("> FTRS(f:%lx)\n", x1);
1029 		ret = sdei_features(x1);
1030 		SDEI_LOG("< FTRS:%lx\n", ret);
1031 		SMC_RET1(handle, ret);
1032 
1033 	case SDEI_EVENT_SIGNAL:
1034 		SDEI_LOG("> SIGNAL(e:%lx t:%lx)\n", x1, x2);
1035 		ret = sdei_signal(x1, x2);
1036 		SDEI_LOG("< SIGNAL:%ld\n", ret);
1037 		SMC_RET1(handle, ret);
1038 
1039 	default:
1040 		/* Do nothing in default case */
1041 		break;
1042 	}
1043 
1044 	WARN("Unimplemented SDEI Call: 0x%x\n", smc_fid);
1045 	SMC_RET1(handle, SMC_UNK);
1046 }
1047 
1048 /* Subscribe to PSCI CPU on to initialize per-CPU SDEI configuration */
1049 SUBSCRIBE_TO_EVENT(psci_cpu_on_finish, sdei_cpu_on_init);
1050