mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
189 lines
5.0 KiB
Rust
189 lines
5.0 KiB
Rust
//! 处理中断和异常
|
|
//!
|
|
//! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c
|
|
use core::hint::spin_loop;
|
|
|
|
use system_error::SystemError;
|
|
|
|
use crate::{
|
|
arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq,
|
|
exception::HardwareIrqNumber, kdebug, kerror,
|
|
};
|
|
|
|
use super::TrapFrame;
|
|
|
|
type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>;
|
|
|
|
static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [
|
|
do_trap_insn_misaligned, // 0
|
|
do_trap_insn_access_fault, // 1
|
|
do_trap_insn_illegal, // 2
|
|
do_trap_break, // 3
|
|
do_trap_load_misaligned, // 4
|
|
do_trap_load_access_fault, // 5
|
|
do_trap_store_misaligned, // 6
|
|
do_trap_store_access_fault, // 7
|
|
do_trap_user_env_call, // 8
|
|
default_handler, // 9
|
|
default_handler, // 10
|
|
default_handler, // 11
|
|
do_trap_insn_page_fault, // 12
|
|
do_trap_load_page_fault, // 13
|
|
default_handler, // 14
|
|
do_trap_store_page_fault, // 15
|
|
];
|
|
|
|
#[no_mangle]
|
|
unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) {
|
|
if trap_frame.cause.is_interrupt() {
|
|
riscv64_do_interrupt(trap_frame);
|
|
} else if trap_frame.cause.is_exception() {
|
|
riscv64_do_exception(trap_frame);
|
|
}
|
|
}
|
|
|
|
/// 处理中断
|
|
fn riscv64_do_interrupt(trap_frame: &mut TrapFrame) {
|
|
riscv_intc_irq(trap_frame);
|
|
}
|
|
|
|
/// 处理异常
|
|
fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
|
|
kdebug!(
|
|
"riscv64_do_exception: from_user: {}",
|
|
trap_frame.is_from_user()
|
|
);
|
|
let code = trap_frame.cause.code();
|
|
|
|
if code < EXCEPTION_HANDLERS.len() {
|
|
let handler = EXCEPTION_HANDLERS[code];
|
|
handler(trap_frame).ok();
|
|
} else {
|
|
kerror!("riscv64_do_irq: exception code out of range");
|
|
loop {
|
|
// kernel die
|
|
spin_loop();
|
|
}
|
|
};
|
|
}
|
|
|
|
fn default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: handler not found");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理指令地址不对齐异常 #0
|
|
fn do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_insn_misaligned");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理指令访问异常 #1
|
|
fn do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_insn_access_fault");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理非法指令异常 #2
|
|
fn do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_insn_illegal");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理断点异常 #3
|
|
fn do_trap_break(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_break");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理加载地址不对齐异常 #4
|
|
fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_load_misaligned");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理加载访问异常 #5
|
|
fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_load_access_fault");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理存储地址不对齐异常 #6
|
|
fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_store_misaligned");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理存储访问异常 #7
|
|
fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_store_access_fault");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理环境调用异常 #8
|
|
fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
if trap_frame.is_from_user() {
|
|
let syscall_num = trap_frame.a7;
|
|
trap_frame.epc += 4;
|
|
trap_frame.origin_a0 = trap_frame.a0;
|
|
syscall_handler(syscall_num, trap_frame);
|
|
} else {
|
|
panic!("do_trap_user_env_call: not from user mode")
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
// 9-11 reserved
|
|
|
|
/// 处理指令页错误异常 #12
|
|
fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_insn_page_fault");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
/// 处理页加载错误异常 #13
|
|
fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
let vaddr = trap_frame.badaddr;
|
|
let cause = trap_frame.cause;
|
|
let epc = trap_frame.epc;
|
|
kerror!(
|
|
"riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
|
|
vaddr,
|
|
cause
|
|
);
|
|
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|
|
|
|
// 14 reserved
|
|
|
|
/// 处理页存储错误异常 #15
|
|
fn do_trap_store_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
|
kerror!("riscv64_do_irq: do_trap_store_page_fault");
|
|
loop {
|
|
spin_loop();
|
|
}
|
|
}
|