Skip to content

Commit 67beb76

Browse files
authored
Merge branch 'main' into main
2 parents e217db1 + 9885e74 commit 67beb76

File tree

17 files changed

+582
-107
lines changed

17 files changed

+582
-107
lines changed

Cargo.lock

Lines changed: 81 additions & 8 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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
[package]
22
name = "rustsbi-qemu"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
edition = "2018"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
rustsbi = "0.2.0-alpha.4"
9+
rustsbi = { version = "0.2.0-alpha.6" }
1010
buddy_system_allocator = "0.8"
1111
lazy_static = { version = "1", features = ["spin_no_std"] }
1212
spin = "0.9"
1313
riscv = { git = "https://github.com/rust-embedded/riscv", rev = "7e9d2e5b", features = ["inline-asm"] }
1414
device_tree = { git = "https://github.com/rcore-os/device_tree-rs/" }
15-
embedded-hal = "1.0.0-alpha.1"
15+
embedded-hal = "0.2.6"
1616
nb = "1"
1717
bitflags = "1"
1818
bit_field = "0.10"
19+
hashbrown = "0.11"

rustsbi-qemu/src/clint.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ impl Clint {
2121
}
2222
}
2323

24-
pub fn set_timer(&mut self, hart_id: usize, instant: u64) {
24+
pub fn set_timer(&self, hart_id: usize, instant: u64) {
2525
unsafe {
2626
let base = self.base as *mut u8;
2727
core::ptr::write_volatile((base.offset(0x4000) as *mut u64).add(hart_id), instant);
2828
}
2929
}
3030

31-
pub fn send_soft(&mut self, hart_id: usize) {
31+
pub fn send_soft(&self, hart_id: usize) {
3232
unsafe {
3333
let base = self.base as *mut u8;
3434
core::ptr::write_volatile((base as *mut u32).add(hart_id), 1);
3535
}
3636
}
3737

38-
pub fn clear_soft(&mut self, hart_id: usize) {
38+
pub fn clear_soft(&self, hart_id: usize) {
3939
unsafe {
4040
let base = self.base as *mut u8;
4141
core::ptr::write_volatile((base as *mut u32).add(hart_id), 0);
@@ -51,7 +51,8 @@ impl Ipi for Clint {
5151
*crate::count_harts::MAX_HART_ID.lock()
5252
}
5353

54-
fn send_ipi_many(&mut self, hart_mask: HartMask) -> SbiRet {
54+
fn send_ipi_many(&self, hart_mask: HartMask) -> SbiRet {
55+
// println!("[rustsbi] send ipi many, {:?}", hart_mask);
5556
for i in 0..=self.max_hart_id() {
5657
if hart_mask.has_bit(i) {
5758
self.send_soft(i);
@@ -62,7 +63,7 @@ impl Ipi for Clint {
6263
}
6364

6465
impl Timer for Clint {
65-
fn set_timer(&mut self, time_value: u64) {
66+
fn set_timer(&self, time_value: u64) {
6667
let this_mhartid = riscv::register::mhartid::read();
6768
self.set_timer(this_mhartid, time_value);
6869
}

rustsbi-qemu/src/count_harts.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use device_tree::{DeviceTree, Node};
2-
use rustsbi::println;
32
const DEVICE_TREE_MAGIC: u32 = 0xD00DFEED;
43

54
lazy_static::lazy_static! {

rustsbi-qemu/src/execute.rs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
use crate::feature;
2+
use crate::qemu_hsm::{QemuHsm, HsmCommand, pause};
23
use crate::runtime::{MachineTrap, Runtime, SupervisorContext};
34
use core::{
45
ops::{Generator, GeneratorState},
56
pin::Pin,
67
};
7-
use riscv::register::{mie, mip};
8+
use riscv::register::{mie, mip, scause::{Trap, Exception}};
89

9-
pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> ! {
10+
pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize, hsm: QemuHsm) -> ! {
1011
let mut rt = Runtime::new_sbi_supervisor(supervisor_mepc, a0, a1);
12+
hsm.record_current_start_finished();
1113
loop {
1214
match Pin::new(&mut rt).resume(()) {
1315
GeneratorState::Yielded(MachineTrap::SbiCall()) => {
1416
let ctx = rt.context_mut();
15-
let param = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4];
17+
let param = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
1618
let ans = rustsbi::ecall(ctx.a7, ctx.a6, param);
1719
ctx.a0 = ans.error;
1820
ctx.a1 = ans.value;
@@ -24,8 +26,8 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> ! {
2426
let ins = unsafe { get_vaddr_u32(ctx.mepc) } as usize;
2527
if !emulate_illegal_instruction(ctx, ins) {
2628
unsafe {
27-
if should_transfer_illegal_instruction(ctx) {
28-
do_transfer_illegal_instruction(ctx)
29+
if feature::should_transfer_trap(ctx) {
30+
feature::do_transfer_trap(ctx, Trap::Exception(Exception::IllegalInstruction))
2931
} else {
3032
fail_illegal_instruction(ctx, ins)
3133
}
@@ -36,6 +38,38 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> ! {
3638
mip::set_stimer();
3739
mie::clear_mtimer();
3840
},
41+
GeneratorState::Yielded(MachineTrap::MachineSoft()) => match hsm.last_command() {
42+
Some(HsmCommand::Start(start_addr, opaque)) => {
43+
unsafe {
44+
riscv::register::satp::write(0);
45+
riscv::register::sstatus::clear_sie();
46+
}
47+
hsm.record_current_start_finished();
48+
match () {
49+
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
50+
() => unsafe {
51+
asm!(
52+
"csrr a0, mhartid",
53+
"jr {start_addr}",
54+
start_addr = in(reg) start_addr,
55+
in("a1") opaque,
56+
options(noreturn)
57+
)
58+
},
59+
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
60+
() => {
61+
drop((start_addr, opaque));
62+
unimplemented!("not RISC-V instruction set architecture")
63+
}
64+
};
65+
},
66+
Some(HsmCommand::Stop) => {
67+
// no hart stop command in qemu, record stop state and pause
68+
hsm.record_current_stop_finished();
69+
pause();
70+
},
71+
None => panic!("rustsbi-qemu: machine soft interrupt with no hart state monitor command"),
72+
},
3973
GeneratorState::Complete(()) => {
4074
use rustsbi::Reset;
4175
crate::test_device::Reset.system_reset(
@@ -70,37 +104,6 @@ fn emulate_illegal_instruction(ctx: &mut SupervisorContext, ins: usize) -> bool
70104
false
71105
}
72106

73-
unsafe fn should_transfer_illegal_instruction(ctx: &mut SupervisorContext) -> bool {
74-
use riscv::register::mstatus::MPP;
75-
ctx.mstatus.mpp() != MPP::Machine
76-
}
77-
78-
unsafe fn do_transfer_illegal_instruction(ctx: &mut SupervisorContext) {
79-
use riscv::register::{
80-
mstatus::{self, MPP, SPP},
81-
mtval, scause, sepc, stval, stvec,
82-
};
83-
// 设置S层异常原因为:非法指令
84-
scause::set(scause::Trap::Exception(
85-
scause::Exception::IllegalInstruction,
86-
));
87-
// 填写异常指令的指令内容
88-
stval::write(mtval::read());
89-
// 填写S层需要返回到的地址,这里的mepc会被随后的代码覆盖掉
90-
sepc::write(ctx.mepc);
91-
// 设置中断位
92-
mstatus::set_mpp(MPP::Supervisor);
93-
mstatus::set_spp(SPP::Supervisor);
94-
if mstatus::read().sie() {
95-
mstatus::set_spie()
96-
}
97-
mstatus::clear_sie();
98-
ctx.mstatus = mstatus::read();
99-
// 设置返回地址,返回到S层
100-
// 注意,无论是Direct还是Vectored模式,所有异常的向量偏移都是0,不需要处理中断向量,跳转到入口地址即可
101-
ctx.mepc = stvec::read().address();
102-
}
103-
104107
// 真·非法指令异常,是M层出现的
105108
fn fail_illegal_instruction(ctx: &mut SupervisorContext, ins: usize) -> ! {
106109
#[cfg(target_pointer_width = "64")]

rustsbi-qemu/src/feature.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
mod emulate_rdtime;
2+
mod transfer_trap;
23

34
pub use emulate_rdtime::emulate_rdtime;
5+
pub use transfer_trap::{should_transfer_trap, do_transfer_trap};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::runtime::SupervisorContext;
2+
use riscv::register::{
3+
scause, stval, mtval, sepc, mstatus::{self, MPP, SPP}, stvec
4+
};
5+
6+
#[inline]
7+
pub unsafe fn should_transfer_trap(ctx: &mut SupervisorContext) -> bool {
8+
ctx.mstatus.mpp() != MPP::Machine
9+
}
10+
11+
#[inline]
12+
pub unsafe fn do_transfer_trap(ctx: &mut SupervisorContext, cause: scause::Trap) {
13+
// 设置S层异常原因为:非法指令
14+
scause::set(cause);
15+
// 填写异常指令的指令内容
16+
stval::write(mtval::read());
17+
// 填写S层需要返回到的地址,这里的mepc会被随后的代码覆盖掉
18+
sepc::write(ctx.mepc);
19+
// 设置中断位
20+
mstatus::set_mpp(MPP::Supervisor);
21+
mstatus::set_spp(SPP::Supervisor);
22+
if mstatus::read().sie() {
23+
mstatus::set_spie()
24+
}
25+
mstatus::clear_sie();
26+
ctx.mstatus = mstatus::read();
27+
// 设置返回地址,返回到S层
28+
// 注意,无论是Direct还是Vectored模式,所有异常的向量偏移都是0,不需要处理中断向量,跳转到入口地址即可
29+
ctx.mepc = stvec::read().address();
30+
}

rustsbi-qemu/src/hart_csr_utils.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use riscv::register::{
55
medeleg, mideleg,
66
misa::{self, MXL},
77
};
8-
use rustsbi::{print, println};
98

109
pub fn print_hart_csrs() {
1110
print_misa();

0 commit comments

Comments
 (0)