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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /* * 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_ #ifdef __cplusplus extern "C" { #endif #include <zephyr/sys/util_macro.h> #ifndef _ASMLANGUAGE #include <zephyr/irq.h> #include <zephyr/sw_isr_table.h> #include <stdbool.h> #endif /* !_ASMLANGUAGE */ /* Exceptions 0-15 (MCAUSE interrupt=0) */ /* Environment Call from U-mode */ #define RISCV_EXC_ECALLU 8 /** Environment Call from M-mode */ #define RISCV_EXC_ECALLM 11 /* IRQs 0-15 (MCAUSE interrupt=1) */ /** Machine Software Interrupt */ #define RISCV_IRQ_MSOFT 3 /** Machine External Interrupt */ #define RISCV_IRQ_MEXT 11 #ifdef CONFIG_64BIT #define RISCV_MCAUSE_IRQ_POS 63U #define RISCV_MCAUSE_IRQ_BIT BIT64(RISCV_MCAUSE_IRQ_POS) #else #define RISCV_MCAUSE_IRQ_POS 31U #define RISCV_MCAUSE_IRQ_BIT BIT(RISCV_MCAUSE_IRQ_POS) #endif #ifndef _ASMLANGUAGE 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 + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ 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_DIRECT(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ ISR_FLAG_DIRECT, isr_p); \ z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \ } #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) { ARG_UNUSED(swap); unsigned long mcause; /* Get the IRQ number */ __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_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) #endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */ |