Zephyr Project API 4.5.0-rc2
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
irq.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
13
14#ifndef ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_
15#define ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
23
24#ifndef _ASMLANGUAGE
25#include <zephyr/irq.h>
26#include <zephyr/sw_isr_table.h>
27#include <stdbool.h>
28#endif /* !_ASMLANGUAGE */
29
30/* Exceptions 0-15 (MCAUSE interrupt=0) */
31
33#define RISCV_EXC_BREAKPOINT 3
34/* Environment Call from U-mode */
35#define RISCV_EXC_ECALLU 8
37#define RISCV_EXC_ECALLS 9
39#define RISCV_EXC_ECALLM 11
40
41/* IRQs 0-15 (MCAUSE interrupt=1) */
42
44#define RISCV_IRQ_SSOFT 1
46#define RISCV_IRQ_MSOFT 3
48#define RISCV_IRQ_SEXT 9
50#define RISCV_IRQ_MEXT 11
51
52#ifdef CONFIG_64BIT
53#define RISCV_MCAUSE_IRQ_POS 63U
54#define RISCV_MCAUSE_IRQ_BIT BIT64(RISCV_MCAUSE_IRQ_POS)
55#else
56#define RISCV_MCAUSE_IRQ_POS 31U
57#define RISCV_MCAUSE_IRQ_BIT BIT(RISCV_MCAUSE_IRQ_POS)
58#endif
59
60#ifndef _ASMLANGUAGE
61
62extern void arch_irq_enable(unsigned int irq);
63extern void arch_irq_disable(unsigned int irq);
64extern int arch_irq_is_enabled(unsigned int irq);
65
66#if defined(CONFIG_RISCV_HAS_PLIC) || defined(CONFIG_RISCV_HAS_CLIC) || \
67 defined(CONFIG_RISCV_HAS_AIA)
68extern void z_riscv_irq_priority_set(unsigned int irq,
69 unsigned int prio,
71#else
72#define z_riscv_irq_priority_set(i, p, f) /* Nothing */
73#endif /* CONFIG_RISCV_HAS_PLIC || CONFIG_RISCV_HAS_CLIC */
74
75#ifdef CONFIG_RISCV_HAS_CLIC
76extern void z_riscv_irq_vector_set(unsigned int irq);
77#else
78#define z_riscv_irq_vector_set(i) /* Nothing */
79#endif /* CONFIG_RISCV_HAS_CLIC */
80
81#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
82{ \
83 Z_ISR_DECLARE(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \
84 0, isr_p, isr_param_p); \
85 z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \
86}
87
88#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
89{ \
90 Z_ISR_DECLARE_DIRECT(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \
91 ISR_FLAG_DIRECT, isr_p); \
92 z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \
93 z_riscv_irq_vector_set(irq_p); \
94}
95
96#ifdef CONFIG_PM
97extern void arch_isr_direct_pm(void);
98#define ARCH_ISR_DIRECT_PM() arch_isr_direct_pm()
99#else
100#define ARCH_ISR_DIRECT_PM() \
101 do { \
102 } while (false)
103#endif
104
105#define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
106#define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)
107
108#ifdef CONFIG_TRACING_ISR
109extern void sys_trace_isr_enter(void);
110extern void sys_trace_isr_exit(void);
111#endif
112
113static inline void arch_isr_direct_header(void)
114{
115#ifdef CONFIG_TRACING_ISR
117#endif
118 /* We need to increment this so that arch_is_in_isr() keeps working */
119 ++(arch_curr_cpu()->nested);
120}
121
122extern unsigned long __soc_handle_irq(unsigned long mcause);
123
124static inline void arch_isr_direct_footer(int swap)
125{
126 ARG_UNUSED(swap);
127 unsigned long cause;
128
129#ifdef CONFIG_RISCV_S_MODE
130 __asm__ volatile("csrr %0, scause" : "=r" (cause));
131#else
132 __asm__ volatile("csrr %0, mcause" : "=r" (cause));
133#endif
134 cause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK;
135
136 /* Clear the pending IRQ */
137 __soc_handle_irq(cause);
138
139 /* We are not in the ISR anymore */
140 --(arch_curr_cpu()->nested);
141
142#ifdef CONFIG_TRACING_ISR
144#endif
145}
146
147/*
148 * TODO: Add support for rescheduling
149 */
150#ifdef CONFIG_RISCV_S_MODE
151#define ARCH_ISR_DIRECT_DECLARE(name) \
152 static inline int name##_body(void); \
153 __attribute__ ((interrupt("supervisor"))) void name(void) \
154 { \
155 ISR_DIRECT_HEADER(); \
156 name##_body(); \
157 ISR_DIRECT_FOOTER(0); \
158 } \
159 static inline int name##_body(void)
160#else
161#define ARCH_ISR_DIRECT_DECLARE(name) \
162 static inline int name##_body(void); \
163 __attribute__ ((interrupt)) void name(void) \
164 { \
165 ISR_DIRECT_HEADER(); \
166 name##_body(); \
167 ISR_DIRECT_FOOTER(0); \
168 } \
169 static inline int name##_body(void)
170#endif
171
172#endif /* _ASMLANGUAGE */
173
174#ifdef __cplusplus
175}
176#endif
177
178#endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */
static ALWAYS_INLINE _cpu_t * arch_curr_cpu(void)
Definition arch_inlines.h:17
static void arch_isr_direct_header(void)
Definition irq.h:91
static void arch_isr_direct_footer(int maybe_swap)
Definition irq.h:98
#define arch_irq_disable(irq)
Definition irq.h:72
#define arch_irq_enable(irq)
Definition irq.h:71
#define arch_irq_is_enabled(irq)
Definition irq.h:73
void sys_trace_isr_enter(void)
Called when entering an ISR.
void sys_trace_isr_exit(void)
Called when exiting an ISR.
Public interface for configuring interrupts.
flags
Definition parser.h:86
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Software-managed ISR table.
Macro utilities.