2023-12-21 20:41:59 +08:00
|
|
|
/*
|
|
|
|
* 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)
|
2024-07-23 17:43:13 +08:00
|
|
|
addi sp, sp, -16
|
|
|
|
sw ra, 0(sp)
|
2023-12-21 20:41:59 +08:00
|
|
|
|
|
|
|
/* 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
|
|
|
|
|
2024-08-05 11:17:39 +08:00
|
|
|
/* 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
|
2023-12-21 20:41:59 +08:00
|
|
|
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
|
|
|
|
|
2024-08-05 11:17:39 +08:00
|
|
|
/* Read and clear mnxti to get highest current interrupt and enable interrupts. */
|
|
|
|
csrrci a0, 0x345, MSTATUS_IEN
|
2023-12-21 20:41:59 +08:00
|
|
|
bnez a0, irq_loop
|
|
|
|
|
|
|
|
irq_done:
|
2024-07-23 17:43:13 +08:00
|
|
|
lw ra, 0(sp)
|
|
|
|
addi sp, sp, 16
|
2023-12-21 20:41:59 +08:00
|
|
|
ret
|