feat(la64): 实现了较为早期的la64的异常处理的注册 (#1138)

* feat(la64): 实现了较为早期的la64的异常处理的注册

- 栈保存&恢复
- 开机时临时设置异常处理程序,并验证可进入异常处理程序

Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
LoGin
2025-05-07 13:14:54 +08:00
committed by GitHub
parent ed0561424e
commit 4cc267146a
11 changed files with 567 additions and 11 deletions

View File

@ -1,2 +1,44 @@
use crate::process::KernelStack;
pub mod bitops;
pub mod boot;
/* KSave registers */
pub const LOONGARCH_CSR_KS0: usize = 0x30;
pub const LOONGARCH_CSR_KS1: usize = 0x31;
pub const LOONGARCH_CSR_KS2: usize = 0x32;
pub const LOONGARCH_CSR_KS3: usize = 0x33;
pub const LOONGARCH_CSR_KS4: usize = 0x34;
pub const LOONGARCH_CSR_KS5: usize = 0x35;
pub const LOONGARCH_CSR_KS6: usize = 0x36;
pub const LOONGARCH_CSR_KS7: usize = 0x37;
pub const LOONGARCH_CSR_KS8: usize = 0x38;
/// Current mode info
pub const LOONGARCH_CSR_CRMD: usize = 0x0;
/// Prev-exception mode info
pub const LOONGARCH_CSR_PRMD: usize = 0x1;
/// Extended unit enable
pub const LOONGARCH_CSR_EUEN: usize = 0x2;
/// Exception config
pub const LOONGARCH_CSR_ECFG: usize = 0x4;
/// Exception status
pub const LOONGARCH_CSR_ESTAT: usize = 0x5;
/// Exception return address.
pub const LOONGARCH_CSR_ERA: usize = 0x6;
/// Bad virtual address.
pub const LOONGARCH_CSR_BADV: usize = 0x7;
/* Exception allocated KS0, KS1 and KS2 statically */
pub const EXCEPTION_KS0: usize = LOONGARCH_CSR_KS0;
pub const EXCEPTION_KS1: usize = LOONGARCH_CSR_KS1;
/* Percpu-data base allocated KS3 statically */
pub const PERCPU_BASE_KS: usize = LOONGARCH_CSR_KS3;
pub const PERCPU_KSAVE_MASK: usize = 1 << 3;
pub const _THREAD_MASK: usize = KernelStack::SIZE - 1;

View File

@ -1,4 +1,4 @@
use crate::smp::cpu::ProcessorId;
use crate::{mm::percpu::PerCpu, smp::cpu::ProcessorId};
/// 重置cpu
pub unsafe fn cpu_reset() -> ! {
@ -13,3 +13,6 @@ pub unsafe fn cpu_reset() -> ! {
pub fn current_cpu_id() -> ProcessorId {
ProcessorId::new(loongArch64::register::cpuid::read().core_id() as u32)
}
#[no_mangle]
pub static mut KERNEL_SP: [usize; PerCpu::MAX_CPU_NUM as usize] = [0; PerCpu::MAX_CPU_NUM as usize];

View File

@ -1,6 +1,6 @@
use loongArch64::register::{ecfg, eentry};
use crate::{init::init::start_kernel, mm::PhysAddr};
use crate::{arch::interrupt::entry::handle_reserved_, init::init::start_kernel, mm::PhysAddr};
static mut BOOT_HARTID: u32 = 0;
static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
@ -15,16 +15,19 @@ pub unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
BOOT_HARTID = hartid as u32;
BOOT_FDT_PADDR = fdt_paddr;
}
setup_trap_vector();
boot_tmp_setup_trap_vector();
start_kernel();
}
/// 设置中断、异常处理函数
fn setup_trap_vector() {
// todo!();
// let ptr = handle_exception as *const () as usize;
// ecfg::set_vs(0);
// eentry::set_eentry(handle_exception as usize);
/// 临时设置中断、异常处理函数
///
/// 后续需要通过 https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#1085
/// 这里的这个函数来重新设置中断、异常处理函数
fn boot_tmp_setup_trap_vector() {
let ptr = handle_reserved_ as *const () as usize;
ecfg::set_vs(0);
eentry::set_eentry(ptr);
}
/// Clear the bss section

View File

@ -1,4 +1,6 @@
use system_error::SystemError;
use crate::driver::serial::serial8250::send_to_default_serial8250_port;
pub mod boot;
#[derive(Debug)]
@ -10,6 +12,8 @@ impl ArchBootParams {
#[inline(never)]
pub fn early_setup_arch() -> Result<(), SystemError> {
send_to_default_serial8250_port(b"la64:early_setup_arch");
loop {}
todo!("la64:early_setup_arch");
}

View File

@ -0,0 +1,132 @@
use asm_macros::*;
use kdepends::memoffset::offset_of;
use crate::arch::{asm::*, interrupt::TrapFrame};
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/genex.S#55
macro_rules! build_prep_badv_ {
() => {
concat!(
"
csrrd $t0, {loongarch_csr_badv}
st.d $t0, $sp, {off_csr_badvaddr}
"
)
};
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/genex.S#60
macro_rules! build_prep_fcsr_ {
() => {
concat!(
"
movfcsr2gr $a1, $fcsr0
"
)
};
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/genex.S#64
macro_rules! build_prep_none_ {
() => {
""
};
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/genex.S#67
macro_rules! build_handler {
($exception:expr, $handler:expr, $prep:ident) => {
paste::paste! {
/// handle exception的实现请参考 https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/genex.S#69
#[naked]
#[no_mangle]
#[repr(align(8))]
pub unsafe extern "C" fn [<handle_ $exception _>]() -> ! {
core::arch::naked_asm!(concat!(
backup_t0t1!(),
save_all!(),
[<build_prep_ $prep _>]!(),
"
move $a0, $sp
la.abs $t0, ", stringify!([<do_ $handler _>]),
"
jirl $ra, $t0, 0
",
restore_all_and_ret!(),
"
// 以下是为了编译器不报错说变量未使用,才保留的代码
/* {off_csr_badvaddr} */
/* {loongarch_csr_badv} */
"
),
exception_ks0 = const EXCEPTION_KS0,
exception_ks1 = const EXCEPTION_KS1,
loongarch_csr_prmd = const LOONGARCH_CSR_PRMD,
loongarch_csr_crmd = const LOONGARCH_CSR_CRMD,
loongarch_csr_euen = const LOONGARCH_CSR_EUEN,
loongarch_csr_ecfg = const LOONGARCH_CSR_ECFG,
loongarch_csr_estat = const LOONGARCH_CSR_ESTAT,
loongarch_csr_era = const LOONGARCH_CSR_ERA,
loongarch_csr_badv = const LOONGARCH_CSR_BADV,
percpu_base_ks = const PERCPU_BASE_KS,
thread_mask = const _THREAD_MASK,
pt_size = const core::mem::size_of::<TrapFrame>(),
off_r0 = const offset_of!(TrapFrame, r0),
off_ra = const offset_of!(TrapFrame, ra),
off_tp = const offset_of!(TrapFrame, tp),
off_usp = const offset_of!(TrapFrame, usp),
off_a0 = const offset_of!(TrapFrame, a0),
off_a1 = const offset_of!(TrapFrame, a1),
off_a2 = const offset_of!(TrapFrame, a2),
off_a3 = const offset_of!(TrapFrame, a3),
off_a4 = const offset_of!(TrapFrame, a4),
off_a5 = const offset_of!(TrapFrame, a5),
off_a6 = const offset_of!(TrapFrame, a6),
off_a7 = const offset_of!(TrapFrame, a7),
off_t0 = const offset_of!(TrapFrame, t0),
off_t1 = const offset_of!(TrapFrame, t1),
off_t2 = const offset_of!(TrapFrame, t2),
off_t3 = const offset_of!(TrapFrame, t3),
off_t4 = const offset_of!(TrapFrame, t4),
off_t5 = const offset_of!(TrapFrame, t5),
off_t6 = const offset_of!(TrapFrame, t6),
off_t7 = const offset_of!(TrapFrame, t7),
off_t8 = const offset_of!(TrapFrame, t8),
off_r21 = const offset_of!(TrapFrame, r21),
off_fp = const offset_of!(TrapFrame, fp),
off_s0 = const offset_of!(TrapFrame, s0),
off_s1 = const offset_of!(TrapFrame, s1),
off_s2 = const offset_of!(TrapFrame, s2),
off_s3 = const offset_of!(TrapFrame, s3),
off_s4 = const offset_of!(TrapFrame, s4),
off_s5 = const offset_of!(TrapFrame, s5),
off_s6 = const offset_of!(TrapFrame, s6),
off_s7 = const offset_of!(TrapFrame, s7),
off_s8 = const offset_of!(TrapFrame, s8),
// off_orig_a0 = const offset_of!(TrapFrame, orig_a0),
off_csr_era = const offset_of!(TrapFrame, csr_era),
off_csr_badvaddr = const offset_of!(TrapFrame, csr_badvaddr),
off_csr_crmd = const offset_of!(TrapFrame, csr_crmd),
off_csr_prmd = const offset_of!(TrapFrame, csr_prmd),
off_csr_euen = const offset_of!(TrapFrame, csr_euen),
off_csr_ecfg = const offset_of!(TrapFrame, csr_ecfg),
off_csr_estat = const offset_of!(TrapFrame, csr_estat),
)
}
}
};
}
build_handler!(ade, ade, badv);
build_handler!(ale, ale, badv);
build_handler!(bce, bce, none);
build_handler!(bp, bp, none);
build_handler!(fpe, fpe, fcsr);
build_handler!(fpu, fpu, none);
build_handler!(lsx, lsx, none);
build_handler!(lasx, lasx, none);
build_handler!(lbt, lbt, none);
build_handler!(ri, ri, none);
build_handler!(watch, watch, none);
build_handler!(reserved, reserved, none); /* others */

View File

@ -0,0 +1,87 @@
use crate::driver::serial::serial8250::send_to_default_serial8250_port;
use super::TrapFrame;
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#508
#[no_mangle]
unsafe extern "C" fn do_ade_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_ade_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#522
#[no_mangle]
unsafe extern "C" fn do_ale_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_ale_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#583
#[no_mangle]
unsafe extern "C" fn do_bce_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_bce_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#672
#[no_mangle]
unsafe extern "C" fn do_bp_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_bp_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#481
#[no_mangle]
unsafe extern "C" fn do_fpe_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_fpe_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#904
#[no_mangle]
unsafe extern "C" fn do_fpu_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_fpu_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#921
#[no_mangle]
unsafe extern "C" fn do_lsx_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_lsx_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#943
#[no_mangle]
unsafe extern "C" fn do_lasx_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_lasx_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#978
#[no_mangle]
unsafe extern "C" fn do_lbt_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_lbt_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#809
#[no_mangle]
unsafe extern "C" fn do_ri_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_ri_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#756
#[no_mangle]
unsafe extern "C" fn do_watch_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_watch_()\n");
loop {}
}
/// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/loongarch/kernel/traps.c#1009
#[no_mangle]
unsafe extern "C" fn do_reserved_(frame: *mut TrapFrame) {
send_to_default_serial8250_port(b"la64: do_reserved_()\n");
// loop {}
}

View File

@ -1,3 +1,5 @@
pub mod entry;
mod handle;
pub mod ipi;
use core::any::Any;

View File

@ -21,7 +21,6 @@ SECTIONS
*(.bootstrap.*)
. = ALIGN(4096);
*(.initial_pgtable_section)
. = ALIGN(4096);
}
@ -68,7 +67,7 @@ SECTIONS
. = ALIGN(32768);
trace_point_start_pa = .;
.tracepoint (trace_point_start_pa): AT(trace_point_start_pa - KERNEL_VMA)
.tracepoint (trace_point_start_pa):
{
_tracepoint = .;
*(.tracepoint)