The RP2350 uses the Xh3irq interrupt controller, which supports nested and prioritised interrupts. This adds initial support, configuring the controller in 'direct' (non-vectored) mode. Signed-off-by: Andrew Featherstone <andrew.featherstone@gmail.com>
65 lines
1.3 KiB
ArmAsm
65 lines
1.3 KiB
ArmAsm
/*
|
|
* 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
|