xref: /optee_os/core/kernel/interrupt.c (revision 9fc2442cc66c279cb962c90c4375746fc9b28bb9)
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 __nex_bss;
20 static SLIST_HEAD(, itr_handler) handlers __nex_data =
21 	SLIST_HEAD_INITIALIZER(handlers);
22 
23 void itr_init(struct itr_chip *chip)
24 {
25 	itr_chip = chip;
26 }
27 
28 void itr_handle(size_t it)
29 {
30 	struct itr_handler *h = NULL;
31 	bool was_handled = false;
32 
33 	SLIST_FOREACH(h, &handlers, link) {
34 		if (h->it == it) {
35 			if (h->handler(h) == ITRR_HANDLED)
36 				was_handled = true;
37 			else if (!(h->flags & ITRF_SHARED))
38 				break;
39 		}
40 	}
41 
42 	if (!was_handled) {
43 		EMSG("Disabling unhandled interrupt %zu", it);
44 		itr_chip->ops->disable(itr_chip, it);
45 	}
46 }
47 
48 void itr_add(struct itr_handler *h)
49 {
50 	struct itr_handler __maybe_unused *hdl = NULL;
51 
52 	SLIST_FOREACH(hdl, &handlers, link)
53 		if (hdl->it == h->it)
54 			assert((hdl->flags & ITRF_SHARED) &&
55 			       (h->flags & ITRF_SHARED));
56 
57 	itr_chip->ops->add(itr_chip, h->it, h->flags);
58 	SLIST_INSERT_HEAD(&handlers, h, link);
59 }
60 
61 void itr_enable(size_t it)
62 {
63 	itr_chip->ops->enable(itr_chip, it);
64 }
65 
66 void itr_disable(size_t it)
67 {
68 	itr_chip->ops->disable(itr_chip, it);
69 }
70 
71 void itr_raise_pi(size_t it)
72 {
73 	itr_chip->ops->raise_pi(itr_chip, it);
74 }
75 
76 void itr_raise_sgi(size_t it, uint8_t cpu_mask)
77 {
78 	itr_chip->ops->raise_sgi(itr_chip, it, cpu_mask);
79 }
80 
81 void itr_set_affinity(size_t it, uint8_t cpu_mask)
82 {
83 	itr_chip->ops->set_affinity(itr_chip, it, cpu_mask);
84 }
85 
86 /* This function is supposed to be overridden in platform specific code */
87 void __weak __noreturn itr_core_handler(void)
88 {
89 	panic("Secure interrupt handler not defined");
90 }
91