Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | /* * Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com> * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief RISC-V public interrupt handling * * RISC-V-specific kernel interrupt handling interface. */ #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ #define ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ #ifndef _ASMLANGUAGE #ifdef __cplusplus extern "C" { #endif #include <zephyr/irq.h> #include <zephyr/sw_isr_table.h> #include <stdbool.h> #include <soc.h> extern void arch_irq_enable(unsigned int irq); extern void arch_irq_disable(unsigned int irq); extern int arch_irq_is_enabled(unsigned int irq); #if defined(CONFIG_RISCV_HAS_PLIC) || defined(CONFIG_RISCV_HAS_CLIC) extern void z_riscv_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags); #else #define z_riscv_irq_priority_set(i, p, f) /* Nothing */ #endif /* CONFIG_RISCV_HAS_PLIC || CONFIG_RISCV_HAS_CLIC */ #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ { \ Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \ } #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \ } #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap) #ifdef CONFIG_TRACING_ISR extern void sys_trace_isr_enter(void); extern void sys_trace_isr_exit(void); #endif static inline void arch_isr_direct_header(void) { #ifdef CONFIG_TRACING_ISR sys_trace_isr_enter(); #endif /* We need to increment this so that arch_is_in_isr() keeps working */ ++(arch_curr_cpu()->nested); } extern void __soc_handle_irq(unsigned long mcause); static inline void arch_isr_direct_footer(int swap) { unsigned long mcause; /* Get the IRQ number */ __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); mcause &= SOC_MCAUSE_EXP_MASK; /* Clear the pending IRQ */ __soc_handle_irq(mcause); /* We are not in the ISR anymore */ --(arch_curr_cpu()->nested); #ifdef CONFIG_TRACING_ISR sys_trace_isr_exit(); #endif } /* * TODO: Add support for rescheduling */ #define ARCH_ISR_DIRECT_DECLARE(name) \ static inline int name##_body(void); \ __attribute__ ((interrupt)) void name(void) \ { \ ISR_DIRECT_HEADER(); \ name##_body(); \ ISR_DIRECT_FOOTER(0); \ } \ static inline int name##_body(void) #ifdef __cplusplus } #endif #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */ |