diff --git a/core/arch/arm/plat-stm32mp1/plat_tzc400.c b/core/arch/arm/plat-stm32mp1/plat_tzc400.c index 55f6d41d5a3..b65f6837874 100644 --- a/core/arch/arm/plat-stm32mp1/plat_tzc400.c +++ b/core/arch/arm/plat-stm32mp1/plat_tzc400.c @@ -71,6 +71,7 @@ static bool tzc_region_is_secure(unsigned int i, vaddr_t base, size_t size) static TEE_Result init_stm32mp1_tzc(void) { + TEE_Result res = TEE_ERROR_GENERIC; void *base = phys_to_virt(TZC_BASE, MEM_AREA_IO_SEC, 1); unsigned int region_index = 1; const uint64_t dram_start = DDR_BASE; @@ -108,8 +109,12 @@ static TEE_Result init_stm32mp1_tzc(void) panic("Unexpected TZC area on non-secure region"); } - itr_add(&tzc_itr_handler); - itr_enable(tzc_itr_handler.it); + res = interrupt_add_handler_with_chip(interrupt_get_main_chip(), + &tzc_itr_handler); + if (res) + panic(); + + interrupt_enable(tzc_itr_handler.chip, tzc_itr_handler.it); tzc_set_action(TZC_ACTION_INT); return TEE_SUCCESS; diff --git a/core/arch/arm/plat-stm32mp1/pm/psci.c b/core/arch/arm/plat-stm32mp1/pm/psci.c index f39c032b2f4..bb206808df1 100644 --- a/core/arch/arm/plat-stm32mp1/pm/psci.c +++ b/core/arch/arm/plat-stm32mp1/pm/psci.c @@ -132,6 +132,8 @@ static void raise_sgi0_as_secure(void) static void release_secondary_early_hpen(size_t __unused pos) { + struct itr_chip *itr_chip = interrupt_get_main_chip(); + /* Need to send SIG#0 over Group0 after individual core 1 reset */ raise_sgi0_as_secure(); udelay(20); @@ -142,7 +144,7 @@ static void release_secondary_early_hpen(size_t __unused pos) BOOT_API_A7_CORE1_MAGIC_NUMBER); dsb_ishst(); - itr_raise_sgi(GIC_SEC_SGI_0, TARGET_CPU1_GIC_MASK); + interrupt_raise_sgi(itr_chip, GIC_SEC_SGI_0, TARGET_CPU1_GIC_MASK); } /* Override default psci_cpu_on() with platform specific sequence */ diff --git a/core/arch/arm/plat-synquacer/main.c b/core/arch/arm/plat-synquacer/main.c index d94aff33175..2ba622f1edc 100644 --- a/core/arch/arm/plat-synquacer/main.c +++ b/core/arch/arm/plat-synquacer/main.c @@ -59,8 +59,11 @@ static struct itr_handler timer_itr = { static TEE_Result init_timer_itr(void) { - itr_add(&timer_itr); - itr_enable(IT_SEC_TIMER); + if (interrupt_add_handler_with_chip(interrupt_get_main_chip(), + &timer_itr)) + panic(); + + interrupt_enable(timer_itr.chip, timer_itr.it); /* Enable timer FIQ to fetch entropy required during boot */ generic_timer_start(TIMER_PERIOD_MS); diff --git a/core/arch/arm/plat-vexpress/main.c b/core/arch/arm/plat-vexpress/main.c index d2ab712d39b..4aaf10f435e 100644 --- a/core/arch/arm/plat-vexpress/main.c +++ b/core/arch/arm/plat-vexpress/main.c @@ -101,14 +101,14 @@ static void read_console(void) } } -static enum itr_return console_itr_cb(struct itr_handler *h __maybe_unused) +static enum itr_return console_itr_cb(struct itr_handler *hdl) { if (notif_async_is_started()) { /* * Asynchronous notifications are enabled, lets read from * uart in the bottom half instead. */ - itr_disable(IT_CONSOLE_UART); + interrupt_disable(hdl->chip, hdl->it); notif_send_async(NOTIF_VALUE_DO_BOTTOM_HALF); } else { read_console(); @@ -136,11 +136,11 @@ static void yielding_console_notif(struct notif_driver *ndrv __unused, switch (ev) { case NOTIF_EVENT_DO_BOTTOM_HALF: read_console(); - itr_enable(IT_CONSOLE_UART); + interrupt_enable(console_itr.chip, console_itr.it); break; case NOTIF_EVENT_STOPPED: DMSG("Asynchronous notifications stopped"); - itr_enable(IT_CONSOLE_UART); + interrupt_enable(console_itr.chip, console_itr.it); break; default: EMSG("Unknown event %d", (int)ev); @@ -154,8 +154,15 @@ struct notif_driver console_notif = { static TEE_Result init_console_itr(void) { - itr_add(&console_itr); - itr_enable(IT_CONSOLE_UART); + TEE_Result res = TEE_ERROR_GENERIC; + + res = interrupt_add_handler_with_chip(interrupt_get_main_chip(), + &console_itr); + if (res) + return res; + + interrupt_enable(console_itr.chip, console_itr.it); + if (IS_ENABLED(CFG_CORE_ASYNC_NOTIF)) notif_register_driver(&console_notif); return TEE_SUCCESS; diff --git a/core/drivers/atmel_piobu.c b/core/drivers/atmel_piobu.c index 1f6aa115f8f..e8bf9f2670f 100644 --- a/core/drivers/atmel_piobu.c +++ b/core/drivers/atmel_piobu.c @@ -267,8 +267,16 @@ static struct itr_handler secumod_itr_handler = { static void secumod_interrupt_init(void) { - itr_add_type_prio(&secumod_itr_handler, IRQ_TYPE_LEVEL_HIGH, 7); - itr_enable(secumod_itr_handler.it); + TEE_Result res = TEE_ERROR_GENERIC; + + secumod_itr_handler.chip = interrupt_get_main_chip(); + + res = interrupt_add_configure_handler(&secumod_itr_handler, + IRQ_TYPE_LEVEL_HIGH, 7); + if (res) + panic(); + + interrupt_enable(secumod_itr_handler.chip, secumod_itr_handler.it); } static void secumod_cfg_input_pio(uint8_t gpio_pin, uint32_t config) diff --git a/core/drivers/atmel_wdt.c b/core/drivers/atmel_wdt.c index b2aa5458d17..7d2a5c07e15 100644 --- a/core/drivers/atmel_wdt.c +++ b/core/drivers/atmel_wdt.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -229,7 +230,8 @@ static TEE_Result wdt_node_probe(const void *fdt, int node, uint32_t irq_type = 0; uint32_t irq_prio = 0; int it = DT_INFO_INVALID_INTERRUPT; - struct itr_handler *it_hdlr; + struct itr_handler *it_hdlr = NULL; + TEE_Result res = TEE_ERROR_GENERIC; if (fdt_get_status(fdt, node) != DT_STATUS_OK_SEC) return TEE_ERROR_BAD_PARAMETERS; @@ -244,28 +246,37 @@ static TEE_Result wdt_node_probe(const void *fdt, int node, it = dt_get_irq_type_prio(fdt, node, &irq_type, &irq_prio); if (it == DT_INFO_INVALID_INTERRUPT) - goto err_free_wdt; + goto err_free; - it_hdlr = itr_alloc_add_type_prio(it, &atmel_wdt_itr_cb, 0, wdt, - irq_type, irq_prio); - if (!it_hdlr) - goto err_free_wdt; + res = interrupt_alloc_add_conf_handler(interrupt_get_main_chip(), + it, atmel_wdt_itr_cb, 0, wdt, + irq_type, irq_prio, &it_hdlr); + if (res) + goto err_free; if (dt_map_dev(fdt, node, &wdt->base, &size, DT_MAP_AUTO) < 0) - goto err_free_itr_handler; + goto err_remove_handler; /* Get current state of the watchdog */ wdt->mr = io_read32(wdt->base + WDT_MR) & WDT_MR_WDDIS; atmel_wdt_init_hw(wdt); - itr_enable(it); + interrupt_enable(it_hdlr->chip, it_hdlr->it); + + res = watchdog_register(&wdt->chip); + if (res) + goto err_disable_unmap; + atmel_wdt_register_pm(wdt); - return watchdog_register(&wdt->chip); + return TEE_SUCCESS; -err_free_itr_handler: - itr_free(it_hdlr); -err_free_wdt: +err_disable_unmap: + interrupt_disable(it_hdlr->chip, it_hdlr->it); + core_mmu_remove_mapping(MEM_AREA_IO_SEC, (void *)wdt->base, size); +err_remove_handler: + interrupt_remove_free_handler(it_hdlr); +err_free: free(wdt); return TEE_ERROR_GENERIC; diff --git a/core/drivers/crypto/caam/caam_jr.c b/core/drivers/crypto/caam/caam_jr.c index eeb64f02f8f..a3bf68a329e 100644 --- a/core/drivers/crypto/caam/caam_jr.c +++ b/core/drivers/crypto/caam/caam_jr.c @@ -159,7 +159,7 @@ static enum caam_status do_jr_alloc(struct jr_privdata **privdata, static enum itr_return caam_jr_irqhandler(struct itr_handler *handler) { JR_TRACE("Disable the interrupt"); - itr_disable(handler->it); + interrupt_disable(handler->chip, handler->it); /* Send a signal to exit WFE loop */ sev(); @@ -582,13 +582,17 @@ enum caam_status caam_jr_init(struct caam_jrcfg *jrcfg) * Prepare the interrupt handler to secure the interrupt even * if the interrupt is not used */ + jr_privdata->it_handler.chip = interrupt_get_main_chip(); jr_privdata->it_handler.it = jrcfg->it_num; jr_privdata->it_handler.flags = ITRF_TRIGGER_LEVEL; jr_privdata->it_handler.handler = caam_jr_irqhandler; jr_privdata->it_handler.data = jr_privdata; #if defined(CFG_NXP_CAAM_RUNTIME_JR) && defined(CFG_CAAM_ITR) - itr_add(&jr_privdata->it_handler); + if (interrupt_add_handler(&jr_privdata->it_handler)) { + retstatus = CAAM_FAILURE; + goto end_init; + } #endif caam_hal_jr_enable_itr(jr_privdata->baseaddr); diff --git a/core/drivers/sp805_wdt.c b/core/drivers/sp805_wdt.c index 048620cde89..cd4624fea97 100644 --- a/core/drivers/sp805_wdt.c +++ b/core/drivers/sp805_wdt.c @@ -102,19 +102,21 @@ TEE_Result sp805_register_itr_handler(struct sp805_wdt_data *pd, uint32_t itr_num, uint32_t itr_flags, sp805_itr_handler_func_t itr_handler) { - struct itr_handler *wdt_itr; + TEE_Result res = TEE_ERROR_GENERIC; + struct itr_handler *wdt_itr = NULL; assert(!pd->chip.wdt_itr); - wdt_itr = itr_alloc_add(itr_num, wdt_itr_cb, - itr_flags, &pd->chip); - if (!wdt_itr) - return TEE_ERROR_OUT_OF_MEMORY; + res = interrupt_alloc_add_handler(interrupt_get_main_chip(), itr_num, + wdt_itr_cb, itr_flags, + &pd->chip, &wdt_itr); + if (res) + return res; pd->itr_handler = itr_handler; pd->chip.wdt_itr = wdt_itr; - itr_enable(wdt_itr->it); + interrupt_enable(wdt_itr->chip, wdt_itr->it); return TEE_SUCCESS; } diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h index c5b66a9b83a..e1942b90ab3 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -158,27 +158,6 @@ static inline int dt_get_irq(const void *fdt, int node) } #endif -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); -void itr_free(struct itr_handler *hdl); -void itr_add_type_prio(struct itr_handler *handler, uint32_t type, - uint32_t prio); -void itr_enable(size_t it); -void itr_disable(size_t it); -/* raise the Peripheral Interrupt corresponding to the interrupt ID */ -void itr_raise_pi(size_t it); -/* - * raise the Software Generated Interrupt corresponding to the interrupt ID, - * the cpu_mask represents which cpu interface to forward. - */ -void itr_raise_sgi(size_t it, uint8_t cpu_mask); -/* - * let corresponding interrupt forward to the cpu interface - * according to the cpu_mask. - */ -void itr_set_affinity(size_t it, uint8_t cpu_mask); - /* * __weak overridable function which is called when a secure interrupt is * received. The default function calls panic() immediately, platforms which @@ -186,19 +165,6 @@ void itr_set_affinity(size_t it, uint8_t cpu_mask); */ void interrupt_main_handler(void); -static inline void itr_add(struct itr_handler *handler) -{ - itr_add_type_prio(handler, IRQ_TYPE_NONE, 0); -} - -static inline struct itr_handler *itr_alloc_add(size_t it, - itr_handler_t handler, - uint32_t flags, void *data) -{ - return itr_alloc_add_type_prio(it, handler, flags, data, IRQ_TYPE_NONE, - 0); -} - /* * Interrupt controller chip API functions */ diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c index 9fbc9b2b009..a49bbf2d106 100644 --- a/core/kernel/interrupt.c +++ b/core/kernel/interrupt.c @@ -65,72 +65,6 @@ int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, } #endif -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) -{ - struct itr_handler *hdl = calloc(1, sizeof(*hdl)); - - if (hdl) { - hdl->it = it; - hdl->handler = handler; - hdl->flags = flags; - hdl->data = data; - itr_add_type_prio(hdl, type, prio); - } - - return hdl; -} - -void itr_free(struct itr_handler *hdl) -{ - if (!hdl) - return; - - itr_main_chip->ops->disable(itr_main_chip, hdl->it); - - SLIST_REMOVE(&itr_main_chip->handlers, hdl, itr_handler, link); - free(hdl); -} - -void itr_add_type_prio(struct itr_handler *h, uint32_t type, uint32_t prio) -{ - struct itr_handler __maybe_unused *hdl = NULL; - - SLIST_FOREACH(hdl, &itr_main_chip->handlers, link) - if (hdl->it == h->it) - assert((hdl->flags & ITRF_SHARED) && - (h->flags & ITRF_SHARED)); - - itr_main_chip->ops->add(itr_main_chip, h->it, type, prio); - SLIST_INSERT_HEAD(&itr_main_chip->handlers, h, link); -} - -void itr_enable(size_t it) -{ - itr_main_chip->ops->enable(itr_main_chip, it); -} - -void itr_disable(size_t it) -{ - itr_main_chip->ops->disable(itr_main_chip, it); -} - -void itr_raise_pi(size_t it) -{ - itr_main_chip->ops->raise_pi(itr_main_chip, it); -} - -void itr_raise_sgi(size_t it, uint8_t cpu_mask) -{ - itr_main_chip->ops->raise_sgi(itr_main_chip, it, cpu_mask); -} - -void itr_set_affinity(size_t it, uint8_t cpu_mask) -{ - itr_main_chip->ops->set_affinity(itr_main_chip, it, cpu_mask); -} - /* This function is supposed to be overridden in platform specific code */ void __weak __noreturn interrupt_main_handler(void) { diff --git a/core/kernel/notif.c b/core/kernel/notif.c index 7ecc246fdf5..abf9feafabf 100644 --- a/core/kernel/notif.c +++ b/core/kernel/notif.c @@ -31,6 +31,8 @@ TEE_Result notif_alloc_async_value(uint32_t *val) uint32_t old_itr_status = 0; int bit = 0; + assert(interrupt_can_raise_pi(interrupt_get_main_chip())); + old_itr_status = cpu_spin_lock_xsave(¬if_lock); if (!alloc_values_inited) { @@ -93,6 +95,7 @@ uint32_t notif_get_value(bool *value_valid, bool *value_pending) void notif_send_async(uint32_t value) { uint32_t old_itr_status = 0; + struct itr_chip *itr_chip = interrupt_get_main_chip(); static_assert(CFG_CORE_ASYNC_NOTIF_GIC_INTID >= GIC_PPI_BASE); @@ -101,7 +104,7 @@ void notif_send_async(uint32_t value) DMSG("0x%"PRIx32, value); bit_set(notif_values, value); - itr_raise_pi(CFG_CORE_ASYNC_NOTIF_GIC_INTID); + interrupt_raise_pi(itr_chip, CFG_CORE_ASYNC_NOTIF_GIC_INTID); cpu_spin_unlock_xrestore(¬if_lock, old_itr_status); } @@ -122,6 +125,8 @@ void notif_register_driver(struct notif_driver *ndrv) { uint32_t old_itr_status = 0; + assert(interrupt_can_raise_pi(interrupt_get_main_chip())); + old_itr_status = cpu_spin_lock_xsave(¬if_lock); SLIST_INSERT_HEAD(¬if_driver_head, ndrv, link);