Skip to content
9 changes: 7 additions & 2 deletions core/arch/arm/plat-stm32mp1/plat_tzc400.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion core/arch/arm/plat-stm32mp1/pm/psci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down
7 changes: 5 additions & 2 deletions core/arch/arm/plat-synquacer/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 13 additions & 6 deletions core/arch/arm/plat-vexpress/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
12 changes: 10 additions & 2 deletions core/drivers/atmel_piobu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
35 changes: 23 additions & 12 deletions core/drivers/atmel_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <kernel/dt_driver.h>
#include <kernel/pm.h>
#include <matrix.h>
#include <mm/core_mmu.h>
#include <sama5d2.h>
#include <tee_api_types.h>

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions core/drivers/crypto/caam/caam_jr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
14 changes: 8 additions & 6 deletions core/drivers/sp805_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
34 changes: 0 additions & 34 deletions core/include/kernel/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,47 +158,13 @@ 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
* expects to receive secure interrupts should override this function.
*/
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
*/
Expand Down
66 changes: 0 additions & 66 deletions core/kernel/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Loading