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 10 /* 11 * NOTE! 12 * 13 * We're assuming that there's no concurrent use of this interface, except 14 * delivery of interrupts in parallel. Synchronization will be needed when 15 * we begin to modify settings after boot initialization. 16 */ 17 18 static struct itr_chip *itr_chip; 19 static SLIST_HEAD(, itr_handler) handlers = SLIST_HEAD_INITIALIZER(handlers); 20 21 void itr_init(struct itr_chip *chip) 22 { 23 itr_chip = chip; 24 } 25 26 static struct itr_handler *find_handler(size_t it) 27 { 28 struct itr_handler *h; 29 30 SLIST_FOREACH(h, &handlers, link) 31 if (h->it == it) 32 return h; 33 return NULL; 34 } 35 36 void itr_handle(size_t it) 37 { 38 struct itr_handler *h = find_handler(it); 39 40 if (!h) { 41 EMSG("Disabling unhandled interrupt %zu", it); 42 itr_chip->ops->disable(itr_chip, it); 43 return; 44 } 45 46 if (h->handler(h) != ITRR_HANDLED) { 47 EMSG("Disabling interrupt %zu not handled by handler", it); 48 itr_chip->ops->disable(itr_chip, it); 49 } 50 } 51 52 void itr_add(struct itr_handler *h) 53 { 54 itr_chip->ops->add(itr_chip, h->it, h->flags); 55 SLIST_INSERT_HEAD(&handlers, h, link); 56 } 57 58 void itr_enable(size_t it) 59 { 60 itr_chip->ops->enable(itr_chip, it); 61 } 62 63 void itr_disable(size_t it) 64 { 65 itr_chip->ops->disable(itr_chip, it); 66 } 67 68 void itr_raise_pi(size_t it) 69 { 70 itr_chip->ops->raise_pi(itr_chip, it); 71 } 72 73 void itr_raise_sgi(size_t it, uint8_t cpu_mask) 74 { 75 itr_chip->ops->raise_sgi(itr_chip, it, cpu_mask); 76 } 77 78 void itr_set_affinity(size_t it, uint8_t cpu_mask) 79 { 80 itr_chip->ops->set_affinity(itr_chip, it, cpu_mask); 81 } 82 83 /* This function is supposed to be overridden in platform specific code */ 84 void __weak __noreturn itr_core_handler(void) 85 { 86 panic("Secure interrupt handler not defined"); 87 } 88