1/* 2 * Copyright (c) 2024 Baumer Electric AG 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @brief Assembler-hooks specific to RISC-V Core Local Interrupt Controller 9 */ 10 11#include <zephyr/arch/cpu.h> 12#include "intc_clic.h" 13 14#ifdef CONFIG_64BIT 15 /* register-wide load/store based on ld/sd (XLEN = 64) */ 16 17 .macro lr, rd, mem 18 ld \rd, \mem 19 .endm 20 21 .macro sr, rs, mem 22 sd \rs, \mem 23 .endm 24 25#else 26 /* register-wide load/store based on lw/sw (XLEN = 32) */ 27 28 .macro lr, rd, mem 29 lw \rd, \mem 30 .endm 31 32 .macro sr, rs, mem 33 sw \rs, \mem 34 .endm 35 36#endif 37 38GTEXT(__soc_handle_irq) 39/* 40 * In an CLIC, pending interrupts don't have to be cleared by hand. 41 * In vectored mode, interrupts are cleared automatically. 42 * In non-vectored mode, interrupts are cleared when writing the mnxti register (done in 43 * __soc_handle_all_irqs). 44 * Thus this function can directly return. 45 */ 46SECTION_FUNC(exception.other, __soc_handle_irq) 47 ret 48 49GTEXT(__soc_handle_all_irqs) 50 51#ifdef CONFIG_TRACING 52/* imports */ 53GTEXT(sys_trace_isr_enter) 54GTEXT(sys_trace_isr_exit) 55#endif 56 57/* 58 * This function services and clears all pending interrupts for an CLIC in non-vectored mode. 59 */ 60SECTION_FUNC(exception.other, __soc_handle_all_irqs) 61 addi sp, sp, -16 62 sr ra, 0(sp) 63 64 /* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return 65 * original interrupt if no others appear. */ 66 csrrci a0, CSR_MNXTI, MSTATUS_IEN 67 beqz a0, irq_done /* Check if original interrupt vanished. */ 68 69irq_loop: 70 71#ifdef CONFIG_TRACING_ISR 72 call sys_trace_isr_enter 73#endif 74 75 /* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with 76 * the mtvt, sw irq table is 2-pointer wide -> shift by one. */ 77 csrr t0, CSR_MTVT 78 sub a0, a0, t0 79 la t0, _sw_isr_table 80 slli a0, a0, (1) 81 add t0, t0, a0 82 83 /* Load argument in a0 register */ 84 lr a0, 0(t0) 85 86 /* Load ISR function address in register t1 */ 87 lr t1, RV_REGSIZE(t0) 88 89 /* Call ISR function */ 90 jalr ra, t1, 0 91 92#ifdef CONFIG_TRACING_ISR 93 call sys_trace_isr_exit 94#endif 95 96 /* Read and clear mnxti to get highest current interrupt and enable interrupts. */ 97 csrrci a0, CSR_MNXTI, MSTATUS_IEN 98 bnez a0, irq_loop 99 100irq_done: 101 lr ra, 0(sp) 102 addi sp, sp, 16 103 ret 104