xref: /rk3399_ARM-atf/plat/qti/common/src/qti_interrupt_svc.c (revision 1c63cd61495542b0b52e1b6e484c59ce5c26e0d2)
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