blob: bc11d76140096e429e4a752b75ef93c3da411a1c [file] [log] [blame]
/*
* 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_ */