mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-11-14 19:02:02 +00:00
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>
78 lines
1.8 KiB
C
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);
|
|
}
|
|
}
|