Skip to content

Commit 07e7d3e

Browse files
committed
refactor: 依赖 aclint 获得 sifive clint 操作
Signed-off-by: YdrMaster <[email protected]>
1 parent 16f2b6c commit 07e7d3e

File tree

5 files changed

+84
-135
lines changed

5 files changed

+84
-135
lines changed

Cargo.lock

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustsbi-qemu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dtb-walker = "=0.2.0-alpha.3"
2828
qemu-exit = "3.0"
2929

3030
hsm-cell = { path = "../hsm-cell" }
31+
riscv-aclint = { git = "https://github.com/YdrMaster/riscv-aclint" }
3132
fast-trap = { git = "https://github.com/YdrMaster/fast-trap", rev = "ffb40e2", features = [
3233
"riscv-m",
3334
] }

rustsbi-qemu/src/clint.rs

Lines changed: 26 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
#![allow(unused)]
22

3-
use crate::trap_stack::remote_hsm;
4-
use core::cell::UnsafeCell;
3+
use crate::{hart_id, trap_stack::remote_hsm};
4+
use core::{cell::UnsafeCell, mem::MaybeUninit, ptr::NonNull};
5+
use riscv_aclint::SifiveClint;
56
use rustsbi::{spec::binary::SbiRet, HartMask, Ipi, Timer};
7+
use spin::Once;
68

79
pub(crate) struct Clint;
810

11+
pub(crate) static mut CLINT: MaybeUninit<NonNull<SifiveClint>> = MaybeUninit::uninit();
12+
13+
pub(crate) fn init(base: usize) {
14+
unsafe {
15+
CLINT
16+
.as_mut_ptr()
17+
.write_volatile(NonNull::new(base as _).unwrap())
18+
}
19+
}
20+
921
impl Ipi for Clint {
1022
#[inline]
1123
fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
1224
for i in 0..crate::NUM_HART_MAX {
1325
if hart_mask.has_bit(i) && remote_hsm(i).map_or(false, |hsm| hsm.allow_ipi()) {
14-
msip::send(i);
26+
set_msip(i);
1527
}
1628
}
1729
SbiRet::success(0)
@@ -23,105 +35,24 @@ impl Timer for Clint {
2335
fn set_timer(&self, time_value: u64) {
2436
unsafe {
2537
riscv::register::mip::clear_stimer();
26-
mtimecmp::set(time_value);
38+
clint().write_mtimecmp(hart_id(), time_value);
2739
}
2840
}
2941
}
3042

31-
static mut BASE: UnsafeCell<usize> = UnsafeCell::new(0);
32-
3343
#[inline]
34-
pub(crate) fn init(base: usize) {
35-
unsafe { *BASE.get() = base };
44+
fn clint() -> &'static SifiveClint {
45+
unsafe { CLINT.as_ptr().read_volatile().as_ref() }
3646
}
3747

38-
pub mod mtime {
39-
#[inline]
40-
pub fn read() -> u64 {
41-
unsafe { ((super::BASE.get().read_volatile() + 0xbff8) as *mut u64).read_volatile() }
42-
}
43-
}
44-
45-
pub mod mtimecmp {
46-
#[naked]
47-
pub unsafe extern "C" fn set_naked(time_value: u64) {
48-
core::arch::asm!(
49-
// 保存必要寄存器
50-
" addi sp, sp, -16
51-
sd t0, 0(sp)
52-
sd t1, 8(sp)
53-
",
54-
// 定位并设置当前核的 mtimecmp
55-
" li t1, 0x4000
56-
la t0, {base}
57-
ld t0, 0(t0)
58-
add t0, t0, t1
59-
csrr t1, mhartid
60-
slli t1, t1, 3
61-
add t0, t0, t1
62-
sd a0, 0(t0)
63-
",
64-
// 恢复上下文并返回
65-
" ld t1, 8(sp)
66-
ld t0, 0(sp)
67-
addi sp, sp, 16
68-
ret
69-
",
70-
base = sym super::BASE,
71-
options(noreturn)
72-
)
73-
}
74-
75-
#[inline]
76-
pub fn set(time_value: u64) {
77-
unsafe { set_naked(time_value) };
78-
}
79-
80-
#[inline]
81-
pub fn clear() {
82-
unsafe { set_naked(u64::MAX) };
83-
}
48+
#[inline]
49+
pub fn set_msip(hart_idx: usize) {
50+
clint().set_msip(hart_idx);
8451
}
8552

86-
pub mod msip {
87-
#[naked]
88-
pub unsafe extern "C" fn clear_naked() -> usize {
89-
core::arch::asm!(
90-
// 保存必要寄存器
91-
" addi sp, sp, -16
92-
sd t0, 0(sp)
93-
sd t1, 8(sp)
94-
",
95-
// 定位并清除当前核的 msip
96-
" la t0, {base}
97-
ld t0, (t0)
98-
csrr t1, mhartid
99-
slli t1, t1, 2
100-
add t0, t0, t1
101-
sw zero, 0(t0)
102-
",
103-
// 恢复上下文并返回
104-
" ld t1, 8(sp)
105-
ld t0, 0(sp)
106-
addi sp, sp, 16
107-
ret
108-
",
109-
base = sym super::BASE,
110-
options(noreturn)
111-
)
112-
}
113-
114-
#[inline]
115-
pub fn send(hart_id: usize) {
116-
unsafe {
117-
(super::BASE.get().read_volatile() as *mut u32)
118-
.add(hart_id)
119-
.write_volatile(1)
120-
};
121-
}
122-
123-
#[inline]
124-
pub fn clear() {
125-
unsafe { clear_naked() };
126-
}
53+
#[inline]
54+
pub fn clear() {
55+
let clint = clint();
56+
clint.clear_msip(hart_id());
57+
clint.write_mtimecmp(hart_id(), u64::MAX);
12758
}

rustsbi-qemu/src/main.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ extern "C" fn rust_main(hartid: usize, opaque: usize) {
141141
}
142142
}
143143
// 清理 clint
144-
clint::msip::clear();
145-
clint::mtimecmp::clear();
144+
clint::clear();
146145
// 准备启动调度
147146
unsafe {
148147
asm!("csrw mcause, {}", in(reg) cause::BOOT);
@@ -259,15 +258,14 @@ extern "C" fn fast_handler(
259258
return ctx.call(0);
260259
}
261260
}
262-
base::EID_BASE => {
263-
if a6 == base::PROBE_EXTENSION {
264-
if matches!(
261+
base::EID_BASE
262+
if a6 == base::PROBE_EXTENSION
263+
&& matches!(
265264
ctx.a0(),
266265
legacy::LEGACY_CONSOLE_PUTCHAR | legacy::LEGACY_CONSOLE_GETCHAR
267-
) {
268-
ret.value = 1;
269-
}
270-
}
266+
) =>
267+
{
268+
ret.value = 1;
271269
}
272270
_ => {}
273271
}
@@ -366,7 +364,7 @@ impl rustsbi::Hsm for Hsm {
366364
match remote_hsm(hartid) {
367365
Some(remote) => {
368366
if remote.start(Supervisor { start_addr, opaque }) {
369-
clint::msip::send(hartid);
367+
clint::set_msip(hartid);
370368
SbiRet::success(0)
371369
} else {
372370
SbiRet::already_started()

rustsbi-qemu/src/trap_vec.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::clint;
21
use core::arch::asm;
32
use fast_trap::trap_entry;
43
use riscv::register::mtvec::{self, TrapMode::*};
4+
use riscv_aclint::SifiveClint as Clint;
55

66
/// 加载陷入向量。
77
#[inline]
@@ -52,23 +52,28 @@ unsafe extern "C" fn mtimer() {
5252
// sp : M sp
5353
// mscratch: S sp
5454
" csrrw sp, mscratch, sp",
55-
// 需要 a0 传参,保护
56-
" addi sp, sp, -16
57-
sd ra, 0(sp)
58-
sd a0, 8(sp)
55+
// 保护
56+
" sd ra, -1*8(sp)
57+
sd a0, -2*8(sp)
58+
sd a1, -3*8(sp)
59+
sd a2, -4*8(sp)
5960
",
60-
// clint::mtimecmp::clear();
61-
" li a0, {u64_max}
62-
call {set_mtimecmp}
61+
// 清除 mtimecmp
62+
" la a0, {clint_ptr}
63+
ld a0, (a0)
64+
csrr a1, mhartid
65+
li a2, {u64_max}
66+
call {set_mtimecmp}
6367
",
64-
// mip::set_stimer();
65-
" li a0, {mip_stip}
66-
csrrs zero, mip, a0
68+
// 设置 stip
69+
" li a0, {mip_stip}
70+
csrrs zero, mip, a0
6771
",
68-
// 恢复 a0
69-
" ld a0, 8(sp)
70-
ld ra, 0(sp)
71-
addi sp, sp, 16
72+
// 恢复
73+
" ld ra, -1*8(sp)
74+
ld a0, -2*8(sp)
75+
ld a1, -3*8(sp)
76+
ld a2, -4*8(sp)
7277
",
7378
// 换栈:
7479
// sp : S sp
@@ -78,7 +83,9 @@ unsafe extern "C" fn mtimer() {
7883
" mret",
7984
u64_max = const u64::MAX,
8085
mip_stip = const 1 << 5,
81-
set_mtimecmp = sym clint::mtimecmp::set_naked,
86+
clint_ptr = sym crate::clint::CLINT,
87+
// Clint::write_mtimecmp_naked(&self, hart_idx, val)
88+
set_mtimecmp = sym Clint::write_mtimecmp_naked,
8289
options(noreturn)
8390
)
8491
}
@@ -95,26 +102,32 @@ unsafe extern "C" fn msoft() {
95102
// sp : M sp
96103
// mscratch: S sp
97104
" csrrw sp, mscratch, sp",
98-
// 保护 ra
99-
" addi sp, sp, -8
100-
sd ra, 0(sp)
105+
// 保护
106+
" sd ra, -1*8(sp)
107+
sd a0, -2*8(sp)
108+
sd a1, -3*8(sp)
101109
",
102-
// clint::msip::clear();
103-
// mip::set_ssoft();
104-
" call {clear_msip}
110+
// 清除 msip 设置 ssip
111+
" la a0, {clint_ptr}
112+
ld a0, (a0)
113+
csrr a1, mhartid
114+
call {clear_msip}
105115
csrrsi zero, mip, 1 << 1
106116
",
107-
// 恢复 ra
108-
" ld ra, 0(sp)
109-
addi sp, sp, 8
117+
// 恢复
118+
" ld ra, -1*8(sp)
119+
ld a0, -2*8(sp)
120+
ld a1, -3*8(sp)
110121
",
111122
// 换栈:
112123
// sp : S sp
113124
// mscratch: M sp
114125
" csrrw sp, mscratch, sp",
115126
// 返回
116127
" mret",
117-
clear_msip = sym clint::msip::clear_naked,
128+
clint_ptr = sym crate::clint::CLINT,
129+
// Clint::clear_msip_naked(&self, hart_idx)
130+
clear_msip = sym Clint::clear_msip_naked,
118131
options(noreturn)
119132
)
120133
}

0 commit comments

Comments
 (0)