blob: 82dacbcc4c6aa13cff7dd1302b692ba86dcf6542 [file] [log] [blame]
/*
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief interrupt management code for riscv SOCs supporting the SiFive clic
*/
#include <zephyr/irq.h>
#include <soc.h>
#include <clic.h>
/* clang-format off */
static void clic_irq_enable(unsigned int irq)
{
*(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 1;
}
static void clic_irq_disable(unsigned int irq)
{
*(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 0;
}
void arch_irq_enable(unsigned int irq)
{
uint32_t mie;
if (irq == SOC_IRQ_MSOFT) {
/* Read mstatus & set machine software interrupt enable in mie */
__asm__ volatile("csrrs %0, mie, %1"
: "=r"(mie)
: "r"(BIT(RISCV_MACHINE_SOFT_IRQ)));
} else if (irq == SOC_IRQ_MTIMER) {
*(volatile uint8_t *)CLIC_TIMER_ENABLE_ADDRESS = 1;
/* Read mstatus & set machine timer interrupt enable in mie */
__asm__ volatile("csrrs %0, mie, %1"
: "=r"(mie)
: "r"(BIT(RISCV_MACHINE_TIMER_IRQ)
| BIT(RISCV_MACHINE_EXT_IRQ)));
} else {
clic_irq_enable(irq - SOC_IRQ_ASYNC);
}
}
void arch_irq_disable(unsigned int irq)
{
uint32_t mie;
if (irq == SOC_IRQ_MSOFT) {
/* Read mstatus & set machine software interrupt enable in mie */
__asm__ volatile("csrrc %0, mie, %1"
: "=r"(mie)
: "r"(BIT(RISCV_MACHINE_SOFT_IRQ)));
} else if (irq == SOC_IRQ_MTIMER) {
*(volatile uint8_t *)CLIC_TIMER_ENABLE_ADDRESS = 0;
/* Read mstatus & set machine timer interrupt enable in mie */
__asm__ volatile("csrrc %0, mie, %1"
: "=r"(mie)
: "r"(BIT(RISCV_MACHINE_TIMER_IRQ)
| BIT(RISCV_MACHINE_EXT_IRQ)));
} else {
clic_irq_disable(irq - SOC_IRQ_ASYNC);
}
}
void arch_irq_priority_set(unsigned int irq, unsigned int prio)
{
ARG_UNUSED(irq);
ARG_UNUSED(prio);
}
int arch_irq_is_enabled(unsigned int irq)
{
uint32_t mie;
/* Enable MEIE (machine external interrupt enable) */
__asm__ volatile("csrrs %0, mie, %1"
: "=r"(mie)
: "r"(BIT(RISCV_MACHINE_EXT_IRQ)));
/* Read mstatus & set machine interrupt enable (MIE) in mstatus */
__asm__ volatile("csrrs %0, mstatus, %1"
: "=r"(mie)
: "r"(MSTATUS_MIE));
return !!(mie & SOC_MIE_MSIE);
}
/* clang-format on */