| /* |
| * Copyright (c) 2024 Baumer Electric AG |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @brief Assembler-hooks specific to Nuclei's Extended Core Interrupt Controller |
| */ |
| |
| #include <zephyr/arch/cpu.h> |
| |
| |
| GTEXT(__soc_handle_irq) |
| /* |
| * In an ECLIC, pending interrupts don't have to be cleared by hand. |
| * In vectored mode, interrupts are cleared automatically. |
| * In non-vectored mode, interrupts are cleared when writing the mnxti register (done in |
| * __soc_handle_all_irqs). |
| * Thus this function can directly return. |
| */ |
| SECTION_FUNC(exception.other, __soc_handle_irq) |
| ret |
| |
| GTEXT(__soc_handle_all_irqs) |
| |
| #ifdef CONFIG_TRACING |
| /* imports */ |
| GTEXT(sys_trace_isr_enter) |
| GTEXT(sys_trace_isr_exit) |
| #endif |
| |
| /* |
| * This function services and clears all pending interrupts for an ECLIC in non-vectored mode. |
| */ |
| SECTION_FUNC(exception.other, __soc_handle_all_irqs) |
| addi sp, sp, -16 |
| sw ra, 0(sp) |
| |
| /* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return |
| * original interrupt if no others appear. */ |
| csrrci a0, 0x345, MSTATUS_IEN |
| beqz a0, irq_done /* Check if original interrupt vanished. */ |
| |
| irq_loop: |
| |
| #ifdef CONFIG_TRACING_ISR |
| call sys_trace_isr_enter |
| #endif |
| |
| /* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with |
| * the mtvt, sw irq table is 2-pointer wide -> shift by one. */ |
| csrr t0, 0x307 /* mtvt */ |
| sub a0, a0, t0 |
| la t0, _sw_isr_table |
| slli a0, a0, (1) |
| add t0, t0, a0 |
| |
| /* Load argument in a0 register */ |
| lw a0, 0(t0) |
| |
| /* Load ISR function address in register t1 */ |
| lw t1, RV_REGSIZE(t0) |
| |
| /* Call ISR function */ |
| jalr ra, t1, 0 |
| |
| #ifdef CONFIG_TRACING_ISR |
| call sys_trace_isr_exit |
| #endif |
| |
| /* Read and clear mnxti to get highest current interrupt and enable interrupts. */ |
| csrrci a0, 0x345, MSTATUS_IEN |
| bnez a0, irq_loop |
| |
| irq_done: |
| lw ra, 0(sp) |
| addi sp, sp, 16 |
| ret |