| /* |
| * Copyright (C) 2025 Andrew Featherstone |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/toolchain.h> |
| |
| #include "hardware/platform_defs.h" |
| #include "hardware/regs/rvcsr.h" |
| |
| /* imports */ |
| #ifdef CONFIG_TRACING |
| GTEXT(sys_trace_isr_enter) |
| GTEXT(sys_trace_isr_exit) |
| #endif |
| |
| /* exports */ |
| GTEXT(__soc_handle_all_irqs) |
| |
| /* |
| * This function services and clears all pending interrupts. |
| */ |
| SECTION_FUNC(exception.other, __soc_handle_all_irqs) |
| /* Get the highest-priority external interrupt. */ |
| csrr a0, RVCSR_MEINEXT_OFFSET |
| bltz a0, irq_done |
| |
| addi sp, sp, -16 |
| sw ra, 0(sp) |
| irq_loop: |
| |
| #ifdef CONFIG_TRACING_ISR |
| call sys_trace_isr_enter |
| #endif |
| /* |
| * Call corresponding registered function in _sw_isr_table. |
| * Value from MEINEXT is index left shifted by 2, so shift |
| * by one to get offset into 2-word wide table. |
| */ |
| 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, 4(t0) |
| |
| /* Call ISR function */ |
| jalr ra, t1, 0 |
| |
| #ifdef CONFIG_TRACING_ISR |
| call sys_trace_isr_exit |
| #endif |
| |
| /* Get the next highest interrupt, and process that, or continue to done. */ |
| csrr a0, RVCSR_MEINEXT_OFFSET |
| bgez a0, irq_loop |
| |
| lw ra, 0(sp) |
| addi sp, sp, 16 |
| irq_done: |
| ret |