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