1/*
2 * Copyright (C) 2025 Andrew Featherstone
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#include <zephyr/toolchain.h>
7
8#include "hardware/platform_defs.h"
9#include "hardware/regs/rvcsr.h"
10
11/* imports */
12#ifdef CONFIG_TRACING
13GTEXT(sys_trace_isr_enter)
14GTEXT(sys_trace_isr_exit)
15#endif
16
17/* exports */
18GTEXT(__soc_handle_all_irqs)
19
20/*
21 * This function services and clears all pending interrupts.
22 */
23SECTION_FUNC(exception.other, __soc_handle_all_irqs)
24	/* Get the highest-priority external interrupt. */
25	csrr a0, RVCSR_MEINEXT_OFFSET
26	bltz a0, irq_done
27
28	addi sp, sp, -16
29	sw ra, 0(sp)
30irq_loop:
31
32#ifdef CONFIG_TRACING_ISR
33	call sys_trace_isr_enter
34#endif
35	/*
36	 * Call corresponding registered function in _sw_isr_table.
37	 * Value from MEINEXT is index left shifted by 2, so shift
38	 * by one to get offset into 2-word wide table.
39	 */
40	la t0, _sw_isr_table
41	slli a0, a0, (1)
42	add t0, t0, a0
43
44	/* Load argument in a0 register */
45	lw a0, 0(t0)
46
47	/* Load ISR function address in register t1 */
48	lw t1, 4(t0)
49
50	/* Call ISR function */
51	jalr ra, t1, 0
52
53#ifdef CONFIG_TRACING_ISR
54	call sys_trace_isr_exit
55#endif
56
57	/* Get the next highest interrupt, and process that, or continue to done. */
58	csrr a0, RVCSR_MEINEXT_OFFSET
59	bgez a0, irq_loop
60
61	lw ra, 0(sp)
62	addi sp, sp, 16
63irq_done:
64	ret
65