Files
acrn-hypervisor/hypervisor/arch/riscv/trap.c
Haicheng Li fc495b946a hv: riscv: irq: add interrupt initialization and handlers
This patch implements interrupt initialization and the basic
exception/interrupt handling flow on RISC-V.

init_interrupt() needs to be invoked during CPU initialization to
set up the trap vector and enable the interrupt.

RISC-V exception and interrupt handling includes:
- Saving and restoring CPU registers around traps
- Implementing handlers for:
  - Supervisor software interrupt
  - Supervisor timer interrupt
- Halting the CPU for all other interrupts and exceptions

------
TODOs:
1. add support for registering interrupt handlers via request_irq() and
   further adoption of the common IRQ framework.
2. add support for external interrupt.

Tracked-On: #8813
Signed-off-by: Haicheng Li <haicheng.li@intel.com>
Co-developed-by: Shiqing Gao <shiqing.gao@intel.com>
Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
Reviewed-by: Yifan Liu  <yifan1.liu@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
2025-09-29 14:01:00 +08:00

78 lines
1.8 KiB
C

/*
* Copyright (C) 2023-2025 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Authors:
* Haicheng Li <haicheng.li@intel.com>
*/
#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/trap.h>
#include <cpu.h>
#include <logmsg.h>
#include <notify.h>
#include <softirq.h>
static void unexpected_trap_handler(const struct intr_excp_ctx *ctx)
{
pr_err("Unexpected S mode trap 0x%lx\n", ctx->regs.cause);
/* Halt the CPU */
cpu_dead();
}
/* IRQ 1 - Supervisor software interrupt handler */
static void s_sw_irq_handler(void)
{
cpu_csr_clear(sip, IP_IE_SSI);
handle_smp_call();
}
static void dispatch_exception(const struct intr_excp_ctx *ctx)
{
unexpected_trap_handler(ctx);
}
/*
* FIXME:
* This logic need to be refined once irq multi-arch framework refine work
* is done. Exception code 1(IPI), 5(timer) and 9(ext int) will be merged
* into irq num namespace together, and keep a same entry in the exception
* code table. Abstract PLIC/AIA as a irqchip that implement a get_irq API
* to do the mapping between irq_num and PLIC source id or AIA's MSI.
*/
/**
* TODO: add support for handler registration via request_irq() and
* further adoption of the common IRQ framework.
*/
static void dispatch_interrupt(const struct intr_excp_ctx *ctx)
{
uint64_t trap_cause = ctx->regs.cause & (~TRAP_CAUSE_INTERRUPT_BITMASK);
switch (trap_cause) {
case TRAP_CAUSE_IRQ_S_SOFT:
s_sw_irq_handler();
break;
case TRAP_CAUSE_IRQ_S_TIMER:
timer_irq_handler();
break;
/* TODO: add support for external interrupt */
default:
unexpected_trap_handler(ctx);
break;
}
do_softirq();
}
void dispatch_trap(const struct intr_excp_ctx *ctx)
{
if ((ctx->regs.cause & TRAP_CAUSE_INTERRUPT_BITMASK) == 0UL) {
dispatch_exception(ctx);
} else {
dispatch_interrupt(ctx);
}
}