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_ */
|