1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 #include <assert.h> 8 #include <stdint.h> 9 10 #include <arch_helpers.h> 11 #include <bl31/interrupt_mgmt.h> 12 #include <drivers/arm/gic_common.h> 13 #include <lib/el3_runtime/context_mgmt.h> 14 15 #include <platform.h> 16 #include <qti_interrupt_svc.h> 17 #include <qtiseclib_interface.h> 18 19 #define QTI_INTR_INVALID_INT_NUM 0xFFFFFFFFU 20 21 /* 22 * Top-level EL3 interrupt handler. 23 */ 24 static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags, 25 void *handle, void *cookie) 26 { 27 uint32_t irq = QTI_INTR_INVALID_INT_NUM; 28 29 /* 30 * EL3 non-interruptible. Interrupt shouldn't occur when we are at 31 * EL3 / Secure. 32 */ 33 assert(handle != cm_get_context(SECURE)); 34 35 irq = plat_ic_acknowledge_interrupt(); 36 37 qtiseclib_invoke_isr(irq, handle); 38 39 /* End of Interrupt. */ 40 if (irq < 1022U) { 41 plat_ic_end_of_interrupt(irq); 42 } 43 44 return (uint64_t) handle; 45 } 46 47 int qti_interrupt_svc_init(void) 48 { 49 int ret; 50 uint64_t flags = 0U; 51 52 /* 53 * Route EL3 interrupts to EL3 when in Non-secure. 54 * Note: EL3 won't have interrupt enable 55 * & we don't have S-EL1 support. 56 */ 57 set_interrupt_rm_flag(flags, NON_SECURE); 58 set_interrupt_rm_flag(flags, SECURE); 59 60 /* Register handler for EL3 interrupts */ 61 ret = register_interrupt_type_handler(INTR_TYPE_EL3, 62 qti_el3_interrupt_handler, flags); 63 assert(ret == 0); 64 65 return ret; 66 } 67