Enable RV32 IPI.

master
WangRunji 6 years ago
parent ff18852c56
commit 5bc392f388

@ -36,20 +36,20 @@ pub fn clear_ipi() {
sbi_call(SBI_CLEAR_IPI, 0, 0, 0);
}
pub fn send_ipi(hart_mask: *const usize) {
sbi_call(SBI_SEND_IPI, hart_mask as usize, 0, 0);
pub fn send_ipi(hart_mask: usize) {
sbi_call(SBI_SEND_IPI, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_fence_i(hart_mask: *const usize) {
sbi_call(SBI_REMOTE_FENCE_I, hart_mask as usize, 0, 0);
pub fn remote_fence_i(hart_mask: usize) {
sbi_call(SBI_REMOTE_FENCE_I, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_sfence_vma(hart_mask: *const usize, _start: usize, _size: usize) {
sbi_call(SBI_REMOTE_SFENCE_VMA, hart_mask as usize, 0, 0);
pub fn remote_sfence_vma(hart_mask: usize, _start: usize, _size: usize) {
sbi_call(SBI_REMOTE_SFENCE_VMA, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_sfence_vma_asid(hart_mask: *const usize, _start: usize, _size: usize, _asid: usize) {
sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask as usize, 0, 0);
pub fn remote_sfence_vma_asid(hart_mask: usize, _start: usize, _size: usize, _asid: usize) {
sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, &hart_mask as *const _ as usize, 0, 0);
}
const SBI_SET_TIMER: usize = 0;

@ -33,12 +33,16 @@ ifeq ($(arch), x86_64)
qemu_opts := \
-drive format=raw,file=$(bootimage) \
-drive format=raw,file=$(SFSIMG),media=disk,cache=writeback \
-smp $(smp) \
-smp cores=$(smp) \
-serial mon:stdio \
-device isa-debug-exit
endif
ifeq ($(arch), riscv32)
qemu_opts := -machine virt -kernel $(bin) -nographic -smp cpus=$(smp)
qemu_opts := \
-machine virt \
-kernel $(bin) \
-nographic \
-smp cores=$(smp)
endif
ifdef board

@ -5,19 +5,19 @@ use memory::*;
static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM];
pub unsafe fn set_cpu_id(cpu_id: usize) {
unsafe {
asm!("mv tp, $0" : : "r"(cpu_id));
}
asm!("mv tp, $0" : : "r"(cpu_id));
}
pub unsafe fn get_cpu_id() -> usize {
let mut cpu_id = 0;
unsafe {
asm!("mv $0, tp" : : "r" (cpu_id));
}
pub fn id() -> usize {
let cpu_id;
unsafe { asm!("mv $0, tp" : "=r"(cpu_id)); }
cpu_id
}
pub fn send_ipi(cpu_id: usize) {
super::bbl::sbi::send_ipi(1 << cpu_id);
}
pub unsafe fn has_started(cpu_id: usize) -> bool {
read_volatile(&STARTED[cpu_id])
}

@ -14,6 +14,8 @@ pub fn init() {
sscratch::write(0);
// Set the exception vector address
stvec::write(__alltraps as usize, stvec::TrapMode::Direct);
// Enable IPI
sie::set_ssoft();
}
info!("interrupt: init end");
}
@ -42,6 +44,7 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E};
trace!("Interrupt: {:?}", tf.scause.cause());
match tf.scause.cause() {
Trap::Interrupt(I::SupervisorSoft) => ipi(),
Trap::Interrupt(I::SupervisorTimer) => timer(),
Trap::Exception(E::IllegalInstruction) => illegal_inst(tf),
Trap::Exception(E::UserEnvCall) => syscall(tf),
@ -51,6 +54,11 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
trace!("Interrupt end");
}
fn ipi() {
debug!("IPI");
super::bbl::sbi::clear_ipi();
}
fn timer() {
::trap::timer();
super::timer::set_next();

@ -8,36 +8,35 @@ pub mod paging;
pub mod memory;
pub mod compiler_rt;
pub mod consts;
pub mod smp;
use self::smp::*;
fn others_main(hartid: usize) -> ! {
println!("hart {} is booting", hartid);
loop { }
}
pub mod cpu;
#[no_mangle]
pub extern fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! {
unsafe { set_cpu_id(hartid); }
unsafe { cpu::set_cpu_id(hartid); }
println!("Hello RISCV! in hart {}, {}, {}", hartid, dtb, hart_mask);
if hartid != 0 {
while unsafe { !has_started(hartid) } { }
others_main(hartid);
// others_main should not return
while unsafe { !cpu::has_started(hartid) } { }
others_main();
unreachable!();
}
println!("Hello RISCV! in hart {}, {}, {}", hartid, dtb, hart_mask);
::logging::init();
interrupt::init();
memory::init();
timer::init();
unsafe { start_others(hart_mask); }
unsafe { cpu::start_others(hart_mask); }
::kmain();
}
fn others_main() -> ! {
interrupt::init();
timer::init();
cpu::send_ipi(0);
loop { }
}
#[cfg(feature = "no_bbl")]
global_asm!(include_str!("boot/boot.asm"));
global_asm!(include_str!("boot/entry.asm"));

@ -16,9 +16,9 @@ pub fn id() -> usize {
CpuId::new().get_feature_info().unwrap().initial_local_apic_id() as usize
}
pub fn send_ipi(cpu_id: u8) {
pub fn send_ipi(cpu_id: usize) {
let mut lapic = unsafe { XApic::new(0xffffff00_fee00000) };
unsafe { lapic.send_ipi(cpu_id, 0x30); } // TODO: Find a IPI trap num
unsafe { lapic.send_ipi(cpu_id as u8, 0x30); } // TODO: Find a IPI trap num
}
pub fn init() {

Loading…
Cancel
Save