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