15bd9c17dSSaurabh Gorecha /*
25bd9c17dSSaurabh Gorecha * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
35bd9c17dSSaurabh Gorecha * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
45bd9c17dSSaurabh Gorecha *
55bd9c17dSSaurabh Gorecha * SPDX-License-Identifier: BSD-3-Clause
65bd9c17dSSaurabh Gorecha */
75bd9c17dSSaurabh Gorecha #include <assert.h>
85bd9c17dSSaurabh Gorecha #include <stdint.h>
95bd9c17dSSaurabh Gorecha
105bd9c17dSSaurabh Gorecha #include <arch_helpers.h>
115bd9c17dSSaurabh Gorecha #include <bl31/interrupt_mgmt.h>
125bd9c17dSSaurabh Gorecha #include <drivers/arm/gic_common.h>
135bd9c17dSSaurabh Gorecha #include <lib/el3_runtime/context_mgmt.h>
145bd9c17dSSaurabh Gorecha
155bd9c17dSSaurabh Gorecha #include <platform.h>
165bd9c17dSSaurabh Gorecha #include <qti_interrupt_svc.h>
175bd9c17dSSaurabh Gorecha #include <qtiseclib_interface.h>
185bd9c17dSSaurabh Gorecha
195bd9c17dSSaurabh Gorecha #define QTI_INTR_INVALID_INT_NUM 0xFFFFFFFFU
205bd9c17dSSaurabh Gorecha
215bd9c17dSSaurabh Gorecha /*
225bd9c17dSSaurabh Gorecha * Top-level EL3 interrupt handler.
235bd9c17dSSaurabh Gorecha */
qti_el3_interrupt_handler(uint32_t id,uint32_t flags,void * handle,void * cookie)245bd9c17dSSaurabh Gorecha static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags,
255bd9c17dSSaurabh Gorecha void *handle, void *cookie)
265bd9c17dSSaurabh Gorecha {
275bd9c17dSSaurabh Gorecha uint32_t irq = QTI_INTR_INVALID_INT_NUM;
285bd9c17dSSaurabh Gorecha
295bd9c17dSSaurabh Gorecha /*
305bd9c17dSSaurabh Gorecha * EL3 non-interruptible. Interrupt shouldn't occur when we are at
315bd9c17dSSaurabh Gorecha * EL3 / Secure.
325bd9c17dSSaurabh Gorecha */
335bd9c17dSSaurabh Gorecha assert(handle != cm_get_context(SECURE));
345bd9c17dSSaurabh Gorecha
355bd9c17dSSaurabh Gorecha irq = plat_ic_acknowledge_interrupt();
365bd9c17dSSaurabh Gorecha
375bd9c17dSSaurabh Gorecha qtiseclib_invoke_isr(irq, handle);
385bd9c17dSSaurabh Gorecha
395bd9c17dSSaurabh Gorecha /* End of Interrupt. */
405bd9c17dSSaurabh Gorecha if (irq < 1022U) {
415bd9c17dSSaurabh Gorecha plat_ic_end_of_interrupt(irq);
425bd9c17dSSaurabh Gorecha }
435bd9c17dSSaurabh Gorecha
445bd9c17dSSaurabh Gorecha return (uint64_t) handle;
455bd9c17dSSaurabh Gorecha }
465bd9c17dSSaurabh Gorecha
qti_interrupt_svc_init(bool have_sel1)47*48897badSCasey Connolly int qti_interrupt_svc_init(bool have_sel1)
485bd9c17dSSaurabh Gorecha {
495bd9c17dSSaurabh Gorecha int ret;
505bd9c17dSSaurabh Gorecha uint64_t flags = 0U;
515bd9c17dSSaurabh Gorecha
525bd9c17dSSaurabh Gorecha /*
535bd9c17dSSaurabh Gorecha * Route EL3 interrupts to EL3 when in Non-secure.
54*48897badSCasey Connolly * Note: EL3 won't have interrupts enabled.
55*48897badSCasey Connolly * When we have a Secure EL1 interrupt handler, allow it
56*48897badSCasey Connolly * to handle Secure interrupts.
575bd9c17dSSaurabh Gorecha */
585bd9c17dSSaurabh Gorecha set_interrupt_rm_flag(flags, NON_SECURE);
59*48897badSCasey Connolly if (!have_sel1)
60b5959ab0SMuhammad Arsath K F set_interrupt_rm_flag(flags, SECURE);
615bd9c17dSSaurabh Gorecha
625bd9c17dSSaurabh Gorecha /* Register handler for EL3 interrupts */
635bd9c17dSSaurabh Gorecha ret = register_interrupt_type_handler(INTR_TYPE_EL3,
645bd9c17dSSaurabh Gorecha qti_el3_interrupt_handler, flags);
655bd9c17dSSaurabh Gorecha assert(ret == 0);
665bd9c17dSSaurabh Gorecha
675bd9c17dSSaurabh Gorecha return ret;
685bd9c17dSSaurabh Gorecha }
69