Skip to content

Commit a940605

Browse files
committed
fix: 修正可恢复挂起的实现
Signed-off-by: YdrMaster <[email protected]>
1 parent eefc0fc commit a940605

File tree

2 files changed

+95
-19
lines changed

2 files changed

+95
-19
lines changed

rustsbi-qemu/src/main.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ extern "C" fn fast_handler(
218218
) -> FastResult {
219219
use riscv::register::{
220220
mcause::{self, Exception as E, Interrupt as I, Trap as T},
221-
mepc, mstatus, mtval,
221+
mtval,
222222
};
223223

224224
let cause = mcause::read();
@@ -231,21 +231,25 @@ extern "C" fn fast_handler(
231231
match unsafe { hart_ctx.hsm.local() }.start() {
232232
Ok(supervisor) => {
233233
unsafe {
234-
load_trap_vec(true);
235-
mstatus::set_mpie();
236-
mstatus::set_mpp(mstatus::MPP::Supervisor);
234+
let mut status = mstatus::read();
235+
status &= !mstatus::MPP;
236+
status |= mstatus::MPIE | mstatus::MPP_SUPERVISOR;
237+
mstatus::write(status);
237238
mie::write(mie::MSIE | mie::MTIE | mie::MEIE);
239+
load_trap_vec(true);
238240
}
239241
hart_ctx.trap.a[0] = hart_id;
240242
hart_ctx.trap.a[1] = supervisor.opaque;
241243
hart_ctx.trap.pc = supervisor.start_addr;
242244
}
243245
Err(_state) => {
244246
unsafe {
245-
load_trap_vec(false);
246-
mstatus::set_mpie();
247-
mstatus::set_mpp(mstatus::MPP::Machine);
247+
let mut status = mstatus::read();
248+
status &= !mstatus::MPP;
249+
status |= mstatus::MPIE | mstatus::MPP_MACHINE;
250+
mstatus::write(status);
248251
mie::write(mie::MSIE);
252+
load_trap_vec(false);
249253
};
250254
hart_ctx.trap.pc = _stop as usize;
251255
}
@@ -262,27 +266,27 @@ extern "C" fn fast_handler(
262266
[ctx.a0(), a1, a2, a3, a4, a5],
263267
);
264268
if ret.is_ok() && a7 == hsm::EID_HSM {
269+
// 关闭
265270
if a6 == hsm::HART_STOP {
266271
unsafe {
267-
load_trap_vec(true);
268-
mstatus::set_mpp(mstatus::MPP::Machine);
272+
load_trap_vec(false);
269273
mie::write(mie::MSIE);
270274
ROOT_STACK[hart_id()].hart_context().trap.pc = _stop as usize;
271275
}
272276
return ctx.call(0);
273277
}
278+
// 不可恢复挂起
274279
if a6 == hsm::HART_SUSPEND
275280
&& ctx.a0() == hsm::HART_SUSPEND_TYPE_NON_RETENTIVE as usize
276281
{
277282
unsafe {
278283
load_trap_vec(false);
279-
mstatus::set_mpp(mstatus::MPP::Machine);
280284
ROOT_STACK[hart_id()].hart_context().trap.pc = _stop as usize;
281285
}
282286
return ctx.call(0);
283287
}
284288
}
285-
mepc::write(mepc::read() + 4);
289+
mepc::next();
286290
ctx.save_args(ret.value, a2, a3, a4, a5, a6, a7);
287291
ctx.write_a(0, ret.error);
288292
ctx.restore()
@@ -469,18 +473,19 @@ impl rustsbi::Hsm for Hsm {
469473
spec::HART_SUSPEND_TYPE_RETENTIVE => unsafe {
470474
ROOT_STACK[hart_id()].hart_context().hsm.local().suspend();
471475
asm!(
472-
" la {0}, 1f
473-
csrrw {0}, mtvec, {0}
474-
csrrw {1}, mepc, {1}
475-
csrrw {2}, mstatus, {2}
476+
" la {0}, 1f
477+
csrrw {0}, mtvec, {0}
478+
csrr {1}, mepc
479+
csrrsi {2}, mstatus, {mie}
476480
wfi
477-
1: csrrw {2}, mstatus, {2}
478-
csrrw {1}, mepc, {1}
479-
csrrw {0}, mtvec, {0}
481+
1: csrw mstatus, {2}
482+
csrw mepc, {1}
483+
csrw mtvec, {0}
480484
",
481485
out(reg) _,
482486
out(reg) _,
483487
out(reg) _,
488+
mie = const mstatus::MIE,
484489
);
485490
ROOT_STACK[hart_id()].hart_context().hsm.local().resume();
486491
SbiRet::success(0)

rustsbi-qemu/src/riscv_spec.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[allow(unused, missing_docs)]
1+
#![allow(unused, missing_docs)]
22

33
pub mod mie {
44
use core::arch::asm;
@@ -19,3 +19,74 @@ pub mod mie {
1919
unsafe { asm!("csrw mie, {}", in(reg) bits, options(nomem)) };
2020
}
2121
}
22+
23+
pub mod mstatus {
24+
use core::arch::asm;
25+
26+
pub const SIE: usize = 1 << 1;
27+
pub const MIE: usize = 1 << 3;
28+
pub const SPIE: usize = 1 << 5;
29+
pub const MPIE: usize = 1 << 7;
30+
pub const SPP: usize = 1 << 8;
31+
pub const VS: usize = 3 << 9;
32+
pub const MPP: usize = 3 << 11;
33+
pub const FS: usize = 3 << 13;
34+
pub const XS: usize = 3 << 15;
35+
pub const MPRV: usize = 1 << 17;
36+
pub const SUM: usize = 1 << 18;
37+
pub const MXR: usize = 1 << 19;
38+
pub const TVM: usize = 1 << 20;
39+
pub const TW: usize = 1 << 21;
40+
pub const TSR: usize = 1 << 22;
41+
pub const UXL: usize = 3 << 32;
42+
pub const SXL: usize = 3 << 34;
43+
pub const SBE: usize = 1 << 36;
44+
pub const MBE: usize = 1 << 37;
45+
pub const SD: usize = 1 << 63;
46+
47+
pub const MPP_MACHINE: usize = 3 << 11;
48+
pub const MPP_SUPERVISOR: usize = 1 << 11;
49+
pub const MPP_USER: usize = 0 << 11;
50+
51+
#[inline(always)]
52+
pub fn read() -> usize {
53+
let bits: usize;
54+
unsafe { asm!("csrr {}, mstatus", out(reg) bits, options(nomem)) };
55+
bits
56+
}
57+
58+
#[inline(always)]
59+
pub fn write(bits: usize) {
60+
unsafe { asm!("csrw mstatus, {}", in(reg) bits, options(nomem)) };
61+
}
62+
}
63+
64+
pub mod mepc {
65+
use core::arch::asm;
66+
67+
#[inline(always)]
68+
pub fn next() {
69+
unsafe {
70+
asm!(
71+
" csrr {0}, mepc
72+
addi {0}, {0}, 4
73+
csrw mepc, {0}
74+
",
75+
out(reg) _,
76+
options(nomem),
77+
)
78+
}
79+
}
80+
81+
#[inline(always)]
82+
pub fn read() -> usize {
83+
let bits: usize;
84+
unsafe { asm!("csrr {}, mepc", out(reg) bits, options(nomem)) };
85+
bits
86+
}
87+
88+
#[inline(always)]
89+
pub fn write(bits: usize) {
90+
unsafe { asm!("csrw mepc, {}", in(reg) bits, options(nomem)) };
91+
}
92+
}

0 commit comments

Comments
 (0)