Skip to content

Commit b428030

Browse files
authored
Merge pull request #9 from duskmoon314/multicore
fix: clint send_soft max_hart_id times
2 parents ab6b260 + 31d7e41 commit b428030

File tree

8 files changed

+80
-50
lines changed

8 files changed

+80
-50
lines changed

rustsbi-qemu/src/execute.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
use crate::feature;
2-
use crate::qemu_hsm::{QemuHsm, HsmCommand, pause};
2+
use crate::qemu_hsm::{pause, HsmCommand, QemuHsm};
33
use crate::runtime::{MachineTrap, Runtime, SupervisorContext};
44
use core::{
55
ops::{Generator, GeneratorState},
66
pin::Pin,
77
};
8-
use riscv::register::{mie, mip, scause::{Trap, Exception}};
8+
use riscv::register::{
9+
mie, mip,
10+
scause::{Exception, Trap},
11+
};
912

1013
pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize, hsm: QemuHsm) -> ! {
1114
let mut rt = Runtime::new_sbi_supervisor(supervisor_mepc, a0, a1);
@@ -40,7 +43,10 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize, hsm: Qem
4043
if !emulate_illegal_instruction(ctx, ins) {
4144
unsafe {
4245
if feature::should_transfer_trap(ctx) {
43-
feature::do_transfer_trap(ctx, Trap::Exception(Exception::IllegalInstruction))
46+
feature::do_transfer_trap(
47+
ctx,
48+
Trap::Exception(Exception::IllegalInstruction),
49+
)
4450
} else {
4551
fail_illegal_instruction(ctx, ins)
4652
}

rustsbi-qemu/src/feature.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ mod emulate_rdtime;
22
mod transfer_trap;
33

44
pub use emulate_rdtime::emulate_rdtime;
5-
pub use transfer_trap::{should_transfer_trap, do_transfer_trap};
5+
pub use transfer_trap::{do_transfer_trap, should_transfer_trap};

rustsbi-qemu/src/feature/transfer_trap.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::runtime::SupervisorContext;
22
use riscv::register::{
3-
scause, stval, mtval, sepc, mstatus::{self, MPP, SPP}, stvec
3+
mstatus::{self, MPP, SPP},
4+
mtval, scause, sepc, stval, stvec,
45
};
56

67
#[inline]

rustsbi-qemu/src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ mod execute;
1616
mod feature;
1717
mod hart_csr_utils;
1818
mod ns16550a;
19+
mod qemu_hsm;
1920
mod runtime;
2021
mod test_device;
21-
mod qemu_hsm;
2222

2323
use buddy_system_allocator::LockedHeap;
2424
use core::panic::PanicInfo;
@@ -74,16 +74,17 @@ extern "C" fn rust_main(hartid: usize, opqaue: usize) -> ! {
7474
}
7575
delegate_interrupt_exception();
7676
set_pmp();
77-
unsafe { // enable wake by ipi
77+
unsafe {
78+
// enable wake by ipi
7879
riscv::register::mstatus::set_mie();
7980
}
8081
if hartid == 0 {
8182
// print hart csr configuration
8283
hart_csr_utils::print_hart_csrs();
8384
// start other harts
8485
let clint = clint::Clint::new(0x2000000 as *mut u8);
85-
let max_hart_id = * { count_harts::MAX_HART_ID.lock() };
86-
for target_hart_id in 0..=max_hart_id {
86+
let max_hart_id = *{ count_harts::MAX_HART_ID.lock() };
87+
for target_hart_id in 0..max_hart_id {
8788
if target_hart_id != 0 {
8889
clint.send_soft(target_hart_id);
8990
}

rustsbi-qemu/src/qemu_hsm.rs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! Hart state monitor designed for QEMU
22
3-
use hashbrown::HashMap;
4-
use rustsbi::SbiRet;
5-
use core::sync::atomic::{AtomicU8, Ordering};
63
use alloc::sync::Arc;
4+
use core::sync::atomic::{AtomicU8, Ordering};
5+
use hashbrown::HashMap;
76
use riscv::register::mstatus::{self, MPP};
7+
use rustsbi::SbiRet;
88

99
// RISC-V SBI Hart State Monitor states
1010
#[allow(unused)]
@@ -13,22 +13,22 @@ use riscv::register::mstatus::{self, MPP};
1313
enum HsmState {
1414
/// The hart is physically powered-up and executing normally.
1515
Started = 0,
16-
/// The hart is not executing in supervisor-mode or any lower privilege mode.
17-
/// It is probably powered-down by the SBI implementation if the underlying platform has a mechanism
16+
/// The hart is not executing in supervisor-mode or any lower privilege mode.
17+
/// It is probably powered-down by the SBI implementation if the underlying platform has a mechanism
1818
/// to physically power-down harts.
1919
Stopped = 1,
20-
/// Some other hart has requested to start (or power-up) the hart from the STOPPED state
20+
/// Some other hart has requested to start (or power-up) the hart from the STOPPED state
2121
/// and the SBI implementation is still working to get the hart in the STARTED state.
2222
StartPending = 2,
23-
/// The hart has requested to stop (or power-down) itself from the STARTED state
23+
/// The hart has requested to stop (or power-down) itself from the STARTED state
2424
/// and the SBI implementation is still working to get the hart in the STOPPED state.
2525
StopPending = 3,
2626
/// This hart is in a platform specific suspend (or low power) state.
2727
Suspended = 4,
28-
/// The hart has requested to put itself in a platform specific low power state from the STARTED state
28+
/// The hart has requested to put itself in a platform specific low power state from the STARTED state
2929
/// and the SBI implementation is still working to get the hart in the platform specific SUSPENDED state.
3030
SuspendPending = 5,
31-
/// An interrupt or platform specific hardware event has caused the hart to resume normal execution from
31+
/// An interrupt or platform specific hardware event has caused the hart to resume normal execution from
3232
/// the SUSPENDED state and the SBI implementation is still working to get the hart in the STARTED state.
3333
ResumePending = 6,
3434
}
@@ -91,7 +91,9 @@ impl QemuHsm {
9191
// this function is called.
9292
pub(crate) fn record_current_stop_finished(&self) {
9393
let hart_id = riscv::register::mhartid::read();
94-
self.state.lock().entry(hart_id)
94+
self.state
95+
.lock()
96+
.entry(hart_id)
9597
.insert(AtomicU8::new(HsmState::Stopped as u8));
9698
}
9799
// Record that current hart id is marked as `Started` state.
@@ -100,7 +102,9 @@ impl QemuHsm {
100102
// and should jump to target address right away.
101103
pub(crate) fn record_current_start_finished(&self) {
102104
let hart_id = riscv::register::mhartid::read();
103-
self.state.lock().entry(hart_id)
105+
self.state
106+
.lock()
107+
.entry(hart_id)
104108
.insert(AtomicU8::new(HsmState::Started as u8));
105109
}
106110
}
@@ -113,11 +117,12 @@ impl rustsbi::Hsm for QemuHsm {
113117
// previous privileged mode should be user or supervisor; start from machine mode is not supported
114118
let mpp = mstatus::read().mpp();
115119
if mpp != MPP::Supervisor && mpp != MPP::User {
116-
return SbiRet::invalid_param()
117-
}
120+
return SbiRet::invalid_param();
121+
}
118122
// try to modify state to start hart
119123
let mut state_lock = self.state.lock();
120-
let current_state = state_lock.entry(hart_id)
124+
let current_state = state_lock
125+
.entry(hart_id)
121126
.or_insert(AtomicU8::new(HsmState::Stopped as u8))
122127
.compare_exchange(
123128
HsmState::Stopped as u8,
@@ -133,15 +138,17 @@ impl rustsbi::Hsm for QemuHsm {
133138
}
134139
// - otherwise return invalid parameter, this may be caused for hart is already transitioning from started state
135140
if current_state != Ok(HsmState::Stopped as u8) {
136-
return SbiRet::invalid_param()
141+
return SbiRet::invalid_param();
137142
}
138143
// todo: check start address
139144
/* SBI_ERR_INVALID_ADDRESS: start_addr is not valid possibly due to following reasons:
140145
* It is not a valid physical address.
141146
* The address is prohibited by PMP to run in supervisor mode. */
142147
// fill in the parameter
143148
let mut config_lock = self.last_command.lock();
144-
config_lock.entry(hart_id).insert(HsmCommand::Start(start_addr, opaque));
149+
config_lock
150+
.entry(hart_id)
151+
.insert(HsmCommand::Start(start_addr, opaque));
145152
drop(config_lock);
146153
drop(state_lock);
147154
// now, start the target hart
@@ -154,14 +161,15 @@ impl rustsbi::Hsm for QemuHsm {
154161
fn hart_stop(&self, hart_id: usize) -> SbiRet {
155162
// try to set current target hart state to stop pending
156163
let mut state_lock = self.state.lock();
157-
let current_state = state_lock.entry(hart_id)
164+
let current_state = state_lock
165+
.entry(hart_id)
158166
.or_insert(AtomicU8::new(HsmState::Stopped as u8))
159167
.compare_exchange(
160168
HsmState::Started as u8,
161169
HsmState::StopPending as u8,
162170
Ordering::AcqRel,
163171
Ordering::Acquire,
164-
);
172+
);
165173
// check current hart state
166174
if current_state.is_err() {
167175
return SbiRet::failed() // illegal state
@@ -170,7 +178,7 @@ impl rustsbi::Hsm for QemuHsm {
170178
let mut config_lock = self.last_command.lock();
171179
config_lock.entry(hart_id).insert(HsmCommand::Stop);
172180
drop(config_lock);
173-
drop(state_lock);
181+
drop(state_lock);
174182
// stop the target hart
175183
let clint = crate::clint::Clint::new(0x2000000 as *mut u8);
176184
clint.send_soft(hart_id);
@@ -189,8 +197,8 @@ impl rustsbi::Hsm for QemuHsm {
189197
// Otherwise, the current hart discards current supervisor context, and returns to another
190198
// `resume_addr` with parameter `opaque`.
191199
fn hart_suspend(&self, suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
192-
match suspend_type {
193-
// Resuming from a retentive suspend state is straight forward and the supervisor-mode software
200+
match suspend_type {
201+
// Resuming from a retentive suspend state is straight forward and the supervisor-mode software
194202
// will see SBI suspend call return without any failures.
195203
SUSPEND_RETENTIVE => {
196204
// try to set current target hart state to stop pending
@@ -216,10 +224,10 @@ impl rustsbi::Hsm for QemuHsm {
216224
state_lock.entry(hart_id).insert(AtomicU8::new(HsmState::Started as u8));
217225
drop(state_lock);
218226
SbiRet::ok(0)
219-
},
220-
// Resuming from a non-retentive suspend state is relatively more involved and requires software
221-
// to restore various hart registers and CSRs for all privilege modes.
222-
// Upon resuming from non-retentive suspend state, the hart will jump to supervisor-mode at address
227+
}
228+
// Resuming from a non-retentive suspend state is relatively more involved and requires software
229+
// to restore various hart registers and CSRs for all privilege modes.
230+
// Upon resuming from non-retentive suspend state, the hart will jump to supervisor-mode at address
223231
// specified by `resume_addr` with specific registers values described in the table below:
224232
//
225233
// | Register Name | Register Value
@@ -299,10 +307,10 @@ pub fn suspend_current_hart(hsm: &QemuHsm) {
299307

300308
// Pause current hart, wake through inter-processor interrupt
301309
pub fn pause() {
302-
use riscv::asm::wfi;
303-
use riscv::register::{mie, mip, mhartid};
304310
use crate::clint::Clint;
305-
unsafe {
311+
use riscv::asm::wfi;
312+
use riscv::register::{mhartid, mie, mip};
313+
unsafe {
306314
let hartid = mhartid::read();
307315
let clint = Clint::new(0x2000000 as *mut u8);
308316
clint.clear_soft(hartid); // Clear IPI
@@ -319,5 +327,5 @@ pub fn pause() {
319327
mie::clear_msoft(); // Stop listening for software interrupts
320328
}
321329
clint.clear_soft(hartid); // Clear IPI
322-
}
323-
}
330+
}
331+
}

test-kernel/src/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
#[macro_use]
88
mod console;
9-
mod sbi;
109
mod mm;
10+
mod sbi;
1111

1212
use riscv::register::{
1313
scause::{self, Exception, Trap},
@@ -16,7 +16,8 @@ use riscv::register::{
1616
};
1717

1818
pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
19-
if hartid == 0 { // initialization
19+
if hartid == 0 {
20+
// initialization
2021
mm::init_heap();
2122
}
2223
if hartid == 0 {
@@ -169,7 +170,7 @@ unsafe extern "C" fn entry() -> ! {
169170
addi t0, t0, %pcrel_lo(1b)
170171
jr t0
171172
",
172-
boot_stack = sym BOOT_STACK,
173+
boot_stack = sym BOOT_STACK,
173174
rust_main = sym rust_main,
174175
options(noreturn))
175176
}

test-kernel/src/mm.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,5 @@ static mut HEAP_SPACE: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
77
static HEAP: LockedHeap<32> = LockedHeap::empty();
88

99
pub fn init_heap() {
10-
unsafe {
11-
HEAP
12-
.lock()
13-
.init(HEAP_SPACE.as_ptr() as usize, HEAP_SIZE)
14-
}
10+
unsafe { HEAP.lock().init(HEAP_SPACE.as_ptr() as usize, HEAP_SIZE) }
1511
}

test-kernel/src/sbi.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ pub fn set_timer(time: usize) {
138138
const FUNCTION_IPI_SEND_IPI: usize = 0x0;
139139

140140
pub fn send_ipi(hart_mask: usize, hart_mask_base: usize) -> SbiRet {
141-
sbi_call_2(EXTENSION_IPI, FUNCTION_IPI_SEND_IPI, hart_mask, hart_mask_base)
141+
sbi_call_2(
142+
EXTENSION_IPI,
143+
FUNCTION_IPI_SEND_IPI,
144+
hart_mask,
145+
hart_mask_base,
146+
)
142147
}
143148

144149
const FUNCTION_HSM_HART_START: usize = 0x0;
@@ -147,7 +152,13 @@ const FUNCTION_HSM_HART_GET_STATUS: usize = 0x2;
147152
const FUNCTION_HSM_HART_SUSPEND: usize = 0x3;
148153

149154
pub fn hart_start(hartid: usize, start_addr: usize, opaque: usize) -> SbiRet {
150-
sbi_call_3(EXTENSION_HSM, FUNCTION_HSM_HART_START, hartid, start_addr, opaque)
155+
sbi_call_3(
156+
EXTENSION_HSM,
157+
FUNCTION_HSM_HART_START,
158+
hartid,
159+
start_addr,
160+
opaque,
161+
)
151162
}
152163

153164
pub fn hart_stop(hartid: usize) -> SbiRet {
@@ -159,7 +170,13 @@ pub fn hart_get_status(hartid: usize) -> SbiRet {
159170
}
160171

161172
pub fn hart_suspend(suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
162-
sbi_call_3(EXTENSION_HSM, FUNCTION_HSM_HART_SUSPEND, suspend_type as usize, resume_addr, opaque)
173+
sbi_call_3(
174+
EXTENSION_HSM,
175+
FUNCTION_HSM_HART_SUSPEND,
176+
suspend_type as usize,
177+
resume_addr,
178+
opaque,
179+
)
163180
}
164181

165182
#[inline(always)]

0 commit comments

Comments
 (0)