1/* 2 * Copyright (c) 2024 Baumer Electric AG 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @brief Assembler-hooks specific to Nuclei's Extended Core Interrupt Controller 9 */ 10 11#include <zephyr/arch/cpu.h> 12 13 14GTEXT(__soc_handle_irq) 15/* 16 * In an ECLIC, pending interrupts don't have to be cleared by hand. 17 * In vectored mode, interrupts are cleared automatically. 18 * In non-vectored mode, interrupts are cleared when writing the mnxti register (done in 19 * __soc_handle_all_irqs). 20 * Thus this function can directly return. 21 */ 22SECTION_FUNC(exception.other, __soc_handle_irq) 23 ret 24 25GTEXT(__soc_handle_all_irqs) 26 27#ifdef CONFIG_TRACING 28/* imports */ 29GTEXT(sys_trace_isr_enter) 30GTEXT(sys_trace_isr_exit) 31#endif 32 33/* 34 * This function services and clears all pending interrupts for an ECLIC in non-vectored mode. 35 */ 36SECTION_FUNC(exception.other, __soc_handle_all_irqs) 37 addi sp, sp, -16 38 sw ra, 0(sp) 39 40 /* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return 41 * original interrupt if no others appear. */ 42 csrrci a0, 0x345, MSTATUS_IEN 43 beqz a0, irq_done /* Check if original interrupt vanished. */ 44 45irq_loop: 46 47#ifdef CONFIG_TRACING_ISR 48 call sys_trace_isr_enter 49#endif 50 51 /* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with 52 * the mtvt, sw irq table is 2-pointer wide -> shift by one. */ 53 csrr t0, 0x307 /* mtvt */ 54 sub a0, a0, t0 55 la t0, _sw_isr_table 56 slli a0, a0, (1) 57 add t0, t0, a0 58 59 /* Load argument in a0 register */ 60 lw a0, 0(t0) 61 62 /* Load ISR function address in register t1 */ 63 lw t1, RV_REGSIZE(t0) 64 65 /* Call ISR function */ 66 jalr ra, t1, 0 67 68#ifdef CONFIG_TRACING_ISR 69 call sys_trace_isr_exit 70#endif 71 72 /* Read and clear mnxti to get highest current interrupt and enable interrupts. */ 73 csrrci a0, 0x345, MSTATUS_IEN 74 bnez a0, irq_loop 75 76irq_done: 77 lw ra, 0(sp) 78 addi sp, sp, 16 79 ret 80