From e2201da2bc0250b7aff5a76277756a516b2b912b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 17 May 2023 00:14:38 +0200 Subject: [PATCH 1/3] drivers: move to interrupt_call_handlers() Removes itr_handle() in favor to interrupt_call_handlers(). This changes updates all implemented main interrupt controller drivers that are the GIC driver, the HFIC driver and Atmel SAIC driver. Reviewed-by: Alvin Chang Acked-by: Jerome Forissier Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- core/drivers/atmel_saic.c | 14 ++++++++------ core/drivers/gic.c | 2 +- core/drivers/hfic.c | 3 ++- core/drivers/plic.c | 2 +- core/include/kernel/interrupt.h | 6 ------ core/kernel/interrupt.c | 5 ----- 6 files changed, 12 insertions(+), 20 deletions(-) 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..deb091bcdd9 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); diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c index 7d10dd4ece0..ffd52397c07 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) From 4948a341cdbc4879920a5c99278d954e0a4ccba0 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 22 Jun 2023 14:18:00 +0200 Subject: [PATCH 2/3] core: interrupt: helper function interrupt_alloc_add_conf_handler() Adds interrupt API function interrupt_alloc_add_conf_handler() to allocate, configure and register an interrupt handler, providing interrupt type and priority. Acked-by: Jerome Forissier Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- core/include/kernel/interrupt.h | 35 ++++++++++++++++++++++++++++----- core/kernel/interrupt.c | 11 +++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h index deb091bcdd9..cb02f3cfa62 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -315,6 +315,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 @@ -324,16 +342,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 ffd52397c07..9fbc9b2b009 100644 --- a/core/kernel/interrupt.c +++ b/core/kernel/interrupt.c @@ -227,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; @@ -240,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; From 0b8c5dce06bb7e0431b9faf4f91a7c12d4b4d52d Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 16 Jun 2023 14:10:50 +0200 Subject: [PATCH 3/3] core: interrupt: helper function for raise_pi, raise_sgi, set_affinity Defines helper API functions to call .raise_pi, .raise_sgi and .set_affinity handlers of a chip controller. Defines API function to query support of these handlers in the interrupt controller. Acked-by: Jerome Forissier Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- core/include/kernel/interrupt.h | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h index cb02f3cfa62..c5b66a9b83a 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -258,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