1/* 2 * Copyright (c) 2018 Foundries.io Ltd 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include <zephyr/offsets.h> 8#include <zephyr/toolchain.h> 9 10#include <soc.h> 11 12/* Exports */ 13GTEXT(__soc_handle_irq) 14#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE 15GTEXT(__soc_save_context) 16GTEXT(__soc_restore_context) 17#endif 18 19/* 20 * With a0 == irq_num, this is equivalent to: 21 * 22 * EVENT_UNIT->INTPTPENDCLEAR = (1U << irq_num); 23 * 24 * We could write this routine in C, but the assembly 25 * that's calling us requires that a0 still contain irq_num 26 * on return, and assuming nobody would ever change a 27 * C implementation in a way that silently clobbers it 28 * is playing with fire. Instead, we play tricks in 29 * soc_context.h so that offsets.h contains a pointer to 30 * INTPTPENDCLEAR. 31 */ 32SECTION_FUNC(exception.other, __soc_handle_irq) 33 la t0, __EVENT_INTPTPENDCLEAR 34 li t1, 1 35 sll t1, t1, a0 36 sw t1, 0x00(t0) 37 ret 38 39#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE 40/* 41 * The RI5CY core has ISA extensions for faster loop performance 42 * that use extra registers. 43 * 44 * If the toolchain generates instructions that use them, they must be saved 45 * prior to handling an interrupt/exception. This case is handled using 46 * Zephyr's generic RISC-V mechanism for soc-specific context. 47 * 48 * For details, see the Kconfig help for CONFIG_RISCV_SOC_CONTEXT_SAVE. 49 */ 50SECTION_FUNC(exception.other, __soc_save_context) 51#ifdef CONFIG_SOC_OPENISA_RV32M1_RI5CY 52 csrr t0, RI5CY_LPSTART0 53 csrr t1, RI5CY_LPEND0 54 csrr t2, RI5CY_LPCOUNT0 55 sw t0, __soc_esf_t_lpstart0_OFFSET(a0) 56 sw t1, __soc_esf_t_lpend0_OFFSET(a0) 57 sw t2, __soc_esf_t_lpcount0_OFFSET(a0) 58 csrr t0, RI5CY_LPSTART1 59 csrr t1, RI5CY_LPEND1 60 csrr t2, RI5CY_LPCOUNT1 61 sw t0, __soc_esf_t_lpstart1_OFFSET(a0) 62 sw t1, __soc_esf_t_lpend1_OFFSET(a0) 63 sw t2, __soc_esf_t_lpcount1_OFFSET(a0) 64#endif /* CONFIG_SOC_OPENISA_RV32M1_RI5CY */ 65 66 ret 67 68SECTION_FUNC(exception.other, __soc_restore_context) 69#ifdef CONFIG_SOC_OPENISA_RV32M1_RI5CY 70 lw t0, __soc_esf_t_lpstart0_OFFSET(a0) 71 lw t1, __soc_esf_t_lpend0_OFFSET(a0) 72 lw t2, __soc_esf_t_lpcount0_OFFSET(a0) 73 csrw RI5CY_LPSTART0, t0 74 csrw RI5CY_LPEND0, t1 75 csrw RI5CY_LPCOUNT0, t2 76 lw t0, __soc_esf_t_lpstart1_OFFSET(a0) 77 lw t1, __soc_esf_t_lpend1_OFFSET(a0) 78 lw t2, __soc_esf_t_lpcount1_OFFSET(a0) 79 csrw RI5CY_LPSTART1, t0 80 csrw RI5CY_LPEND1, t1 81 csrw RI5CY_LPCOUNT1, t2 82#endif /* CONFIG_SOC_OPENISA_RV32M1_RI5CY */ 83 84 ret 85#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ 86