Line data Source code
1 1 : /* 2 : * Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com> 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : /** 8 : * @file 9 : * @brief RISC-V public interrupt handling 10 : * 11 : * RISC-V-specific kernel interrupt handling interface. 12 : */ 13 : 14 : #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ 15 : #define ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ 16 : 17 : #ifdef __cplusplus 18 : extern "C" { 19 : #endif 20 : 21 : #include <zephyr/sys/util_macro.h> 22 : 23 : #ifndef _ASMLANGUAGE 24 : #include <zephyr/irq.h> 25 : #include <zephyr/sw_isr_table.h> 26 : #include <stdbool.h> 27 : #endif /* !_ASMLANGUAGE */ 28 : 29 : /* Exceptions 0-15 (MCAUSE interrupt=0) */ 30 : 31 : /* Environment Call from U-mode */ 32 0 : #define RISCV_EXC_ECALLU 8 33 : /** Environment Call from M-mode */ 34 1 : #define RISCV_EXC_ECALLM 11 35 : 36 : /* IRQs 0-15 (MCAUSE interrupt=1) */ 37 : 38 : /** Machine Software Interrupt */ 39 1 : #define RISCV_IRQ_MSOFT 3 40 : /** Machine External Interrupt */ 41 1 : #define RISCV_IRQ_MEXT 11 42 : 43 : #ifdef CONFIG_64BIT 44 : #define RISCV_MCAUSE_IRQ_POS 63U 45 : #define RISCV_MCAUSE_IRQ_BIT BIT64(RISCV_MCAUSE_IRQ_POS) 46 : #else 47 0 : #define RISCV_MCAUSE_IRQ_POS 31U 48 0 : #define RISCV_MCAUSE_IRQ_BIT BIT(RISCV_MCAUSE_IRQ_POS) 49 : #endif 50 : 51 : #ifndef _ASMLANGUAGE 52 : 53 0 : extern void arch_irq_enable(unsigned int irq); 54 0 : extern void arch_irq_disable(unsigned int irq); 55 0 : extern int arch_irq_is_enabled(unsigned int irq); 56 : 57 : #if defined(CONFIG_RISCV_HAS_PLIC) || defined(CONFIG_RISCV_HAS_CLIC) 58 : extern void z_riscv_irq_priority_set(unsigned int irq, 59 : unsigned int prio, 60 : uint32_t flags); 61 : #else 62 : #define z_riscv_irq_priority_set(i, p, f) /* Nothing */ 63 : #endif /* CONFIG_RISCV_HAS_PLIC || CONFIG_RISCV_HAS_CLIC */ 64 : 65 : #ifdef CONFIG_RISCV_HAS_CLIC 66 : extern void z_riscv_irq_vector_set(unsigned int irq); 67 : #else 68 : #define z_riscv_irq_vector_set(i) /* Nothing */ 69 : #endif /* CONFIG_RISCV_HAS_CLIC */ 70 : 71 0 : #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ 72 : { \ 73 : Z_ISR_DECLARE(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ 74 : 0, isr_p, isr_param_p); \ 75 : z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \ 76 : } 77 : 78 0 : #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ 79 : { \ 80 : Z_ISR_DECLARE_DIRECT(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ 81 : ISR_FLAG_DIRECT, isr_p); \ 82 : z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \ 83 : z_riscv_irq_vector_set(irq_p); \ 84 : } 85 : 86 0 : #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() 87 0 : #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap) 88 : 89 : #ifdef CONFIG_TRACING_ISR 90 : extern void sys_trace_isr_enter(void); 91 : extern void sys_trace_isr_exit(void); 92 : #endif 93 : 94 0 : static inline void arch_isr_direct_header(void) 95 : { 96 : #ifdef CONFIG_TRACING_ISR 97 : sys_trace_isr_enter(); 98 : #endif 99 : /* We need to increment this so that arch_is_in_isr() keeps working */ 100 : ++(arch_curr_cpu()->nested); 101 : } 102 : 103 : extern void __soc_handle_irq(unsigned long mcause); 104 : 105 0 : static inline void arch_isr_direct_footer(int swap) 106 : { 107 : ARG_UNUSED(swap); 108 : unsigned long mcause; 109 : 110 : /* Get the IRQ number */ 111 : __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); 112 : mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; 113 : 114 : /* Clear the pending IRQ */ 115 : __soc_handle_irq(mcause); 116 : 117 : /* We are not in the ISR anymore */ 118 : --(arch_curr_cpu()->nested); 119 : 120 : #ifdef CONFIG_TRACING_ISR 121 : sys_trace_isr_exit(); 122 : #endif 123 : } 124 : 125 : /* 126 : * TODO: Add support for rescheduling 127 : */ 128 0 : #define ARCH_ISR_DIRECT_DECLARE(name) \ 129 : static inline int name##_body(void); \ 130 : __attribute__ ((interrupt)) void name(void) \ 131 : { \ 132 : ISR_DIRECT_HEADER(); \ 133 : name##_body(); \ 134 : ISR_DIRECT_FOOTER(0); \ 135 : } \ 136 : static inline int name##_body(void) 137 : 138 : #endif /* _ASMLANGUAGE */ 139 : 140 : #ifdef __cplusplus 141 : } 142 : #endif 143 : 144 : #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */