diff --git a/core/drivers/atmel_saic.c b/core/drivers/atmel_saic.c index fa45cdf0c44..adf2af7fa78 100644 --- a/core/drivers/atmel_saic.c +++ b/core/drivers/atmel_saic.c @@ -29,7 +29,7 @@ struct saic_data { uint32_t external[SAMA5D2_AIC_MAX_IRQS32]; }; -static struct saic_data saic = {0}; +static struct saic_data saic; static void saic_register_pm(void); @@ -47,7 +47,7 @@ void interrupt_main_handler(void) { uint32_t irqnr = saic_read_reg(AT91_AIC_IVR); - itr_handle(irqnr); + interrupt_call_handlers(&saic.chip, irqnr); saic_write_reg(AT91_AIC_EOICR, 0); } @@ -192,9 +192,11 @@ static int saic_dt_get_irq(const uint32_t *properties, int len, return it; } -struct itr_chip saic_chip = { - .ops = &saic_ops, - .dt_get_irq = &saic_dt_get_irq, +static struct saic_data saic = { + .chip = { + .ops = &saic_ops, + .dt_get_irq = &saic_dt_get_irq, + }, }; static void saic_clear_aicredir(void) @@ -297,7 +299,7 @@ TEE_Result atmel_saic_setup(void) saic_init_external(fdt, node); saic_init_hw(); - interrupt_main_init(&saic_chip); + interrupt_main_init(&saic.chip); saic_register_pm(); return TEE_SUCCESS; diff --git a/core/drivers/gic.c b/core/drivers/gic.c index 3b1c1101759..6d5b7777c52 100644 --- a/core/drivers/gic.c +++ b/core/drivers/gic.c @@ -505,7 +505,7 @@ static void __maybe_unused gic_native_itr_handler(void) id = iar & GICC_IAR_IT_ID_MASK; if (id <= gd->max_it) - itr_handle(id); + interrupt_call_handlers(&gd->chip, id); else DMSG("ignoring interrupt %" PRIu32, id); diff --git a/core/drivers/hfic.c b/core/drivers/hfic.c index b6b862bb191..cd308576a1e 100644 --- a/core/drivers/hfic.c +++ b/core/drivers/hfic.c @@ -87,7 +87,8 @@ void interrupt_main_handler(void) return; } - itr_handle(id); + interrupt_call_handlers(&hfic_data.chip, id); + res = thread_hvc(HF_INTERRUPT_DEACTIVATE, id, id, 0); assert(!res); } diff --git a/core/drivers/plic.c b/core/drivers/plic.c index 8335fad7335..be14656f08c 100644 --- a/core/drivers/plic.c +++ b/core/drivers/plic.c @@ -276,7 +276,7 @@ void plic_it_handle(void) uint32_t id = plic_claim_interrupt(pd); if (id <= pd->max_it) - itr_handle(id); + interrupt_call_handlers(&pd->chip, id); else DMSG("ignoring interrupt %" PRIu32, id); diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h index 89fe8572486..c5b66a9b83a 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -128,12 +128,6 @@ TEE_Result itr_chip_init(struct itr_chip *chip); */ void interrupt_main_init(struct itr_chip *data); -/* - * Call handlers registered for that interrupt in core interrupt controller - * @it Interrupt line number - */ -void itr_handle(size_t it); - /* Retrieve main interrupt controller reference */ struct itr_chip *interrupt_get_main_chip(void); @@ -264,6 +258,70 @@ static inline void interrupt_disable(struct itr_chip *chip, size_t itr_num) chip->ops->disable(chip, itr_num); } +/* + * interrupt_can_raise_pi() - Return whether controller embeds raise_pi + * @chip Interrupt controller + */ +static inline bool interrupt_can_raise_pi(struct itr_chip *chip) +{ + return chip->ops->raise_pi; +} + +/* + * interrupt_can_raise_sgi() - Return whether controller embeds raise_sgi + * @chip Interrupt controller + */ +static inline bool interrupt_can_raise_sgi(struct itr_chip *chip) +{ + return chip->ops->raise_sgi; +} + +/* + * interrupt_can_set_affinity() - Return whether controller embeds set_affinity + * @chip Interrupt controller + */ +static inline bool interrupt_can_set_affinity(struct itr_chip *chip) +{ + return chip->ops->set_affinity; +} + +/* + * interrupt_raise_pi() - Raise a peripheral interrupt of a controller + * @chip Interrupt controller + * @itr_num Interrupt number to raise + */ +static inline void interrupt_raise_pi(struct itr_chip *chip, size_t itr_num) +{ + assert(interrupt_can_raise_pi(chip)); + chip->ops->raise_pi(chip, itr_num); +} + +/* + * interrupt_raise_sgi() - Raise a software generiated interrupt of a controller + * @chip Interrupt controller + * @itr_num Interrupt number to raise + * @cpu_mask Mask of the CPUs targeted by the interrupt + */ +static inline void interrupt_raise_sgi(struct itr_chip *chip, size_t itr_num, + uint8_t cpu_mask) +{ + assert(interrupt_can_raise_sgi(chip)); + chip->ops->raise_sgi(chip, itr_num, cpu_mask); +} + +/* + * interrupt_set_affinity() - Set CPU affinity for a controller interrupt + * @chip Interrupt controller + * @itr_num Interrupt number to raise + * @cpu_mask Mask of the CPUs targeted by the interrupt + */ +static inline void interrupt_set_affinity(struct itr_chip *chip, size_t itr_num, + uint8_t cpu_mask) +{ + assert(interrupt_can_set_affinity(chip)); + chip->ops->set_affinity(chip, itr_num, cpu_mask); +} + /* * interrupt_configure() - Configure an interrupt in an interrupt controller * @chip Interrupt controller @@ -321,6 +379,24 @@ static inline TEE_Result interrupt_add_handler_with_chip(struct itr_chip *chip, */ void interrupt_remove_handler(struct itr_handler *hdl); +/* + * interrupt_alloc_add_conf_handler() - Allocate, configure, register a handler + * @chip Interrupt controller + * @itr_num Interrupt number + * @handler Interrupt handler to register + * @flags Bitmask flag ITRF_* + * @data Private data reference passed to @handler + * @type Interrupt trigger type (IRQ_TYPE_* defines) or IRQ_TYPE_NONE + * @prio Interrupt priority or 0 + * @out_hdl NULL or output pointer to allocated struct itr_handler + */ +TEE_Result interrupt_alloc_add_conf_handler(struct itr_chip *chip, + size_t it_num, + itr_handler_t handler, + uint32_t flags, void *data, + uint32_t type, uint32_t prio, + struct itr_handler **out_hdl); + /* * interrupt_alloc_add_handler() - Allocate and register an interrupt handler * @chip Interrupt controller @@ -330,16 +406,23 @@ void interrupt_remove_handler(struct itr_handler *hdl); * @data Private data reference passed to @handler * @out_hdl NULL or output pointer to allocated struct itr_handler */ -TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t it_num, - itr_handler_t handler, uint32_t flags, - void *data, - struct itr_handler **out_hdl); +static inline TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, + size_t it_num, + itr_handler_t handler, + uint32_t flags, + void *data, + struct itr_handler **hdl) +{ + return interrupt_alloc_add_conf_handler(chip, it_num, handler, flags, + data, IRQ_TYPE_NONE, 0, hdl); +} /* * interrupt_remove_free_handler() - Remove/free a registered interrupt handler * @hdl Interrupt handler to remove and free * - * This function is the counterpart of interrupt_alloc_add_handler(). + * This function is the counterpart of interrupt_alloc_add_handler() + * and interrupt_alloc_add_conf_handler(). * This function may panic on non-NULL invalid @hdl reference. */ void interrupt_remove_free_handler(struct itr_handler *hdl); diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c index 7d10dd4ece0..9fbc9b2b009 100644 --- a/core/kernel/interrupt.c +++ b/core/kernel/interrupt.c @@ -65,11 +65,6 @@ int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, } #endif -void itr_handle(size_t it) -{ - interrupt_call_handlers(itr_main_chip, it); -} - struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler, uint32_t flags, void *data, uint32_t type, uint32_t prio) @@ -232,9 +227,12 @@ void interrupt_remove_handler(struct itr_handler *hdl) SLIST_REMOVE(&hdl->chip->handlers, hdl, itr_handler, link); } -TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t itr_num, - itr_handler_t handler, uint32_t flags, - void *data, struct itr_handler **out_hdl) +TEE_Result interrupt_alloc_add_conf_handler(struct itr_chip *chip, + size_t itr_num, + itr_handler_t handler, + uint32_t flags, void *data, + uint32_t type, uint32_t prio, + struct itr_handler **out_hdl) { TEE_Result res = TEE_ERROR_GENERIC; struct itr_handler *hdl = NULL; @@ -245,7 +243,7 @@ TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, size_t itr_num, *hdl = ITR_HANDLER(chip, itr_num, flags, handler, data); - res = interrupt_add_handler(hdl); + res = interrupt_add_configure_handler(hdl, type, prio); if (res) { free(hdl); return res;