Skip to content

feat: update rust edition to 2024 and change asm! to naked_asm! #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[workspace]
resolver = "3"
members = ["xtask", "fast-trap", "test-app"]
default-members = ["xtask"]

[workspace.package]
edition = "2024"
2 changes: 1 addition & 1 deletion fast-trap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "fast-trap"
description = "Provide a framework for bare-metal trap handling, aiming at ensuring performance while reusing code."
version = "0.0.1"
edition = "2021"
edition.workspace = true
authors = ["YdrMaster <[email protected]>"]
repository = "https://github.com/YdrMaster/fast-trap.git"
documentation = "https://docs.rs/fast-trap"
Expand Down
4 changes: 2 additions & 2 deletions fast-trap/src/entire.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{FlowContext, TrapHandler};
use crate::{FlowContext, TrapHandler};
use core::{
marker::PhantomData,
mem::{forget, MaybeUninit},
mem::{MaybeUninit, forget},
ops::{Deref, DerefMut},
ptr::NonNull,
};
Expand Down
236 changes: 119 additions & 117 deletions fast-trap/src/hal/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,137 +111,139 @@ impl FlowContext {
#[naked]
pub unsafe extern "C" fn reuse_stack_for_trap() {
const LAYOUT: Layout = Layout::new::<TrapHandler>();
core::arch::asm!(
" addi sp, sp, {size}
unsafe {
core::arch::naked_asm!(
" addi sp, sp, {size}
andi sp, sp, {mask}
ret
",
size = const -(LAYOUT.size() as isize),
mask = const !(LAYOUT.align() as isize - 1) ,
options(noreturn)
)
size = const -(LAYOUT.size() as isize),
mask = const !(LAYOUT.align() as isize - 1) ,
)
}
}

/// # Safety
///
/// See [proto](crate::hal::doc::trap_entry).
#[naked]
pub unsafe extern "C" fn trap_entry() {
core::arch::asm!(
".align 2",
// 换栈
exchange!(),
// 加载上下文指针
save!(a0 => sp[2]),
load!(sp[0] => a0),
// 保存尽量少的寄存器
save!(ra => a0[0]),
save!(t0 => a0[1]),
save!(t1 => a0[2]),
save!(t2 => a0[3]),
save!(t3 => a0[4]),
save!(t4 => a0[5]),
save!(t5 => a0[6]),
save!(t6 => a0[7]),
// 调用快速路径函数
//
// | reg | position
// | ------ | -
// | ra | `TrapHandler.context`
// | t0-t6 | `TrapHandler.context`
// | a0 | `TrapHandler.scratch`
// | a1-a7 | 参数寄存器
// | sp | sscratch
// | gp, tp | gp, tp
// | s0-s11 | 不支持
//
// > 若要保留陷入上下文,
// > 必须在快速路径保存 a0-a7 到 `TrapHandler.context`,
// > 并进入完整路径执行后续操作。
// >
// > 若要切换上下文,在快速路径设置 gp/tp/sscratch/sepc 和 sstatus。
"mv a0, sp",
load!(sp[1] => ra),
"jalr ra",
"0:", // 加载上下文指针
load!(sp[0] => a1),
// 0:设置少量参数寄存器
" beqz a0, 0f",
// 1:设置所有参数寄存器
" addi a0, a0, -1
unsafe {
core::arch::naked_asm!(
".align 2",
// 换栈
exchange!(),
// 加载上下文指针
save!(a0 => sp[2]),
load!(sp[0] => a0),
// 保存尽量少的寄存器
save!(ra => a0[0]),
save!(t0 => a0[1]),
save!(t1 => a0[2]),
save!(t2 => a0[3]),
save!(t3 => a0[4]),
save!(t4 => a0[5]),
save!(t5 => a0[6]),
save!(t6 => a0[7]),
// 调用快速路径函数
//
// | reg | position
// | ------ | -
// | ra | `TrapHandler.context`
// | t0-t6 | `TrapHandler.context`
// | a0 | `TrapHandler.scratch`
// | a1-a7 | 参数寄存器
// | sp | sscratch
// | gp, tp | gp, tp
// | s0-s11 | 不支持
//
// > 若要保留陷入上下文,
// > 必须在快速路径保存 a0-a7 到 `TrapHandler.context`,
// > 并进入完整路径执行后续操作。
// >
// > 若要切换上下文,在快速路径设置 gp/tp/sscratch/sepc 和 sstatus。
"mv a0, sp",
load!(sp[1] => ra),
"jalr ra",
"0:", // 加载上下文指针
load!(sp[0] => a1),
// 0:设置少量参数寄存器
" beqz a0, 0f",
// 1:设置所有参数寄存器
" addi a0, a0, -1
beqz a0, 1f
",
// 2:设置所有调用者寄存器
" addi a0, a0, -1
// 2:设置所有调用者寄存器
" addi a0, a0, -1
beqz a0, 2f
",
// 3:设置所有寄存器
" addi a0, a0, -1
// 3:设置所有寄存器
" addi a0, a0, -1
beqz a0, 3f
",
// 4:完整路径
save!(s0 => a1[16]),
save!(s1 => a1[17]),
save!(s2 => a1[18]),
save!(s3 => a1[19]),
save!(s4 => a1[20]),
save!(s5 => a1[21]),
save!(s6 => a1[22]),
save!(s7 => a1[23]),
save!(s8 => a1[24]),
save!(s9 => a1[25]),
save!(s10 => a1[26]),
save!(s11 => a1[27]),
// 调用完整路径函数
//
// | reg | position
// | ------ | -
// | sp | sscratch
// | gp, tp | gp, tp
// | else | `TrapHandler.context`
//
// > 若要保留陷入上下文,
// > 在完整路径中保存 gp/tp/sp/pc 到 `TrapHandler.context`。
// >
// > 若要切换上下文,在完整路径设置 gp/tp/sscratch/sepc 和 sstatus。
"mv a0, sp",
load!(sp[2] => ra),
"jalr ra",
"j 0b",
"3:", // 设置所有寄存器
load!(a1[16] => s0),
load!(a1[17] => s1),
load!(a1[18] => s2),
load!(a1[19] => s3),
load!(a1[20] => s4),
load!(a1[21] => s5),
load!(a1[22] => s6),
load!(a1[23] => s7),
load!(a1[24] => s8),
load!(a1[25] => s9),
load!(a1[26] => s10),
load!(a1[27] => s11),
"2:", // 设置所有调用者寄存器
load!(a1[ 0] => ra),
load!(a1[ 1] => t0),
load!(a1[ 2] => t1),
load!(a1[ 3] => t2),
load!(a1[ 4] => t3),
load!(a1[ 5] => t4),
load!(a1[ 6] => t5),
load!(a1[ 7] => t6),
"1:", // 设置所有参数寄存器
load!(a1[10] => a2),
load!(a1[11] => a3),
load!(a1[12] => a4),
load!(a1[13] => a5),
load!(a1[14] => a6),
load!(a1[15] => a7),
"0:", // 设置少量参数寄存器
load!(a1[ 8] => a0),
load!(a1[ 9] => a1),
exchange!(),
r#return!(),
options(noreturn),
)
// 4:完整路径
save!(s0 => a1[16]),
save!(s1 => a1[17]),
save!(s2 => a1[18]),
save!(s3 => a1[19]),
save!(s4 => a1[20]),
save!(s5 => a1[21]),
save!(s6 => a1[22]),
save!(s7 => a1[23]),
save!(s8 => a1[24]),
save!(s9 => a1[25]),
save!(s10 => a1[26]),
save!(s11 => a1[27]),
// 调用完整路径函数
//
// | reg | position
// | ------ | -
// | sp | sscratch
// | gp, tp | gp, tp
// | else | `TrapHandler.context`
//
// > 若要保留陷入上下文,
// > 在完整路径中保存 gp/tp/sp/pc 到 `TrapHandler.context`。
// >
// > 若要切换上下文,在完整路径设置 gp/tp/sscratch/sepc 和 sstatus。
"mv a0, sp",
load!(sp[2] => ra),
"jalr ra",
"j 0b",
"3:", // 设置所有寄存器
load!(a1[16] => s0),
load!(a1[17] => s1),
load!(a1[18] => s2),
load!(a1[19] => s3),
load!(a1[20] => s4),
load!(a1[21] => s5),
load!(a1[22] => s6),
load!(a1[23] => s7),
load!(a1[24] => s8),
load!(a1[25] => s9),
load!(a1[26] => s10),
load!(a1[27] => s11),
"2:", // 设置所有调用者寄存器
load!(a1[ 0] => ra),
load!(a1[ 1] => t0),
load!(a1[ 2] => t1),
load!(a1[ 3] => t2),
load!(a1[ 4] => t3),
load!(a1[ 5] => t4),
load!(a1[ 6] => t5),
load!(a1[ 7] => t6),
"1:", // 设置所有参数寄存器
load!(a1[10] => a2),
load!(a1[11] => a3),
load!(a1[12] => a4),
load!(a1[13] => a5),
load!(a1[14] => a6),
load!(a1[15] => a7),
"0:", // 设置少量参数寄存器
load!(a1[ 8] => a0),
load!(a1[ 9] => a1),
exchange!(),
r#return!(),
)
}
}
34 changes: 19 additions & 15 deletions fast-trap/src/hal/riscv/riscv_m.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{trap_entry, FlowContext};
use super::{FlowContext, trap_entry};
use core::arch::asm;

macro_rules! exchange {
Expand All @@ -23,17 +23,19 @@ impl FlowContext {
/// 从上下文向硬件加载非调用规范约定的寄存器。
#[inline]
pub(crate) unsafe fn load_others(&self) {
asm!(
" mv gp, {gp}
unsafe {
asm!(
" mv gp, {gp}
mv tp, {tp}
csrw mscratch, {sp}
csrw mepc, {pc}
",
gp = in(reg) self.gp,
tp = in(reg) self.tp,
sp = in(reg) self.sp,
pc = in(reg) self.pc,
);
gp = in(reg) self.gp,
tp = in(reg) self.tp,
sp = in(reg) self.sp,
pc = in(reg) self.pc,
);
}
}
}

Expand All @@ -49,23 +51,25 @@ pub(crate) fn exchange_scratch(mut val: usize) -> usize {
/// See [proto](crate::hal::doc::soft_trap).
#[inline]
pub unsafe fn soft_trap(cause: usize) {
asm!(
" la {0}, 1f
unsafe {
asm!(
" la {0}, 1f
csrw mepc, {0}
csrw mcause, {cause}
j {trap}
1:
",
out(reg) _,
cause = in(reg) cause,
trap = sym trap_entry,
);
out(reg) _,
cause = in(reg) cause,
trap = sym trap_entry,
);
}
}

/// # Safety
///
/// See [proto](crate::hal::doc::load_direct_trap_entry).
#[inline]
pub unsafe fn load_direct_trap_entry() {
asm!("csrw mtvec, {0}", in(reg) trap_entry, options(nomem))
unsafe { asm!("csrw mtvec, {0}", in(reg) trap_entry, options(nomem)) }
}
Loading
Loading