xref: /optee_os/core/kernel/interrupt.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2016-2019, Linaro Limited
4  */
5 
6 #include <kernel/interrupt.h>
7 #include <kernel/panic.h>
8 #include <trace.h>
9 #include <assert.h>
10 
11 /*
12  * NOTE!
13  *
14  * We're assuming that there's no concurrent use of this interface, except
15  * delivery of interrupts in parallel. Synchronization will be needed when
16  * we begin to modify settings after boot initialization.
17  */
18 
19 static struct itr_chip *itr_chip;
20 static SLIST_HEAD(, itr_handler) handlers = SLIST_HEAD_INITIALIZER(handlers);
21 
22 void itr_init(struct itr_chip *chip)
23 {
24 	itr_chip = chip;
25 }
26 
27 void itr_handle(size_t it)
28 {
29 	struct itr_handler *h = NULL;
30 	bool was_handled = false;
31 
32 	SLIST_FOREACH(h, &handlers, link) {
33 		if (h->it == it) {
34 			if (h->handler(h) == ITRR_HANDLED)
35 				was_handled = true;
36 			else if (!(h->flags & ITRF_SHARED))
37 				break;
38 		}
39 	}
40 
41 	if (!was_handled) {
42 		EMSG("Disabling unhandled interrupt %zu", it);
43 		itr_chip->ops->disable(itr_chip, it);
44 	}
45 }
46 
47 void itr_add(struct itr_handler *h)
48 {
49 	struct itr_handler __maybe_unused *hdl = NULL;
50 
51 	SLIST_FOREACH(hdl, &handlers, link)
52 		if (hdl->it == h->it)
53 			assert((hdl->flags & ITRF_SHARED) &&
54 			       (h->flags & ITRF_SHARED));
55 
56 	itr_chip->ops->add(itr_chip, h->it, h->flags);
57 	SLIST_INSERT_HEAD(&handlers, h, link);
58 }
59 
60 void itr_enable(size_t it)
61 {
62 	itr_chip->ops->enable(itr_chip, it);
63 }
64 
65 void itr_disable(size_t it)
66 {
67 	itr_chip->ops->disable(itr_chip, it);
68 }
69 
70 void itr_raise_pi(size_t it)
71 {
72 	itr_chip->ops->raise_pi(itr_chip, it);
73 }
74 
75 void itr_raise_sgi(size_t it, uint8_t cpu_mask)
76 {
77 	itr_chip->ops->raise_sgi(itr_chip, it, cpu_mask);
78 }
79 
80 void itr_set_affinity(size_t it, uint8_t cpu_mask)
81 {
82 	itr_chip->ops->set_affinity(itr_chip, it, cpu_mask);
83 }
84 
85 /* This function is supposed to be overridden in platform specific code */
86 void __weak __noreturn itr_core_handler(void)
87 {
88 	panic("Secure interrupt handler not defined");
89 }
90