From 0ba81c6dc104628db93bea148c69cbf6a9574b32 Mon Sep 17 00:00:00 2001 From: guttatus Date: Tue, 5 Nov 2024 20:21:09 +0800 Subject: [PATCH 1/4] bump: upgrade rustsbi version to 0.4.0 --- Cargo.lock | 90 ++----- Cargo.toml | 7 +- Makefile | 1 - src/arch/riscv64/exception.rs | 24 +- src/arch/riscv64/interrupt.rs | 4 +- src/arch/riscv64/mod.rs | 6 - src/arch/riscv64/power.rs | 17 +- src/arch/riscv64/sbicall.rs | 247 +++++++++++-------- src/arch/riscv64/sbicall_legacy.rs | 379 ----------------------------- src/arch/riscv64/start.rs | 2 +- src/arch/riscv64/timer.rs | 3 +- src/utils/print.rs | 2 +- 12 files changed, 197 insertions(+), 585 deletions(-) delete mode 100644 src/arch/riscv64/sbicall_legacy.rs diff --git a/Cargo.lock b/Cargo.lock index 667dfb1..326739a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,12 +64,6 @@ dependencies = [ "which", ] -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - [[package]] name = "bitflags" version = "2.4.1" @@ -195,16 +189,6 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -[[package]] -name = "embedded-hal" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] - [[package]] name = "embedded-hal" version = "1.0.0-rc.1" @@ -442,21 +426,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.1.0", -] - -[[package]] -name = "nb" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" - [[package]] name = "nom" version = "7.1.3" @@ -517,9 +486,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -562,24 +531,13 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "riscv" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa3145d2fae3778b1e31ec2e827b228bdc6abd9b74bb5705ba46dcb82069bc4f" -dependencies = [ - "bit_field", - "critical-section", - "embedded-hal 0.2.7", -] - [[package]] name = "riscv" version = "0.10.1" source = "git+https://github.com/Zera-Algorithm/riscv#e0e9ca8d3647de8a0c9ec7980337587c584a6052" dependencies = [ "critical-section", - "embedded-hal 1.0.0-rc.1", + "embedded-hal", ] [[package]] @@ -603,10 +561,11 @@ dependencies = [ "gethostname", "log", "memoffset 0.8.0", - "riscv 0.10.1 (git+https://github.com/Zera-Algorithm/riscv)", + "riscv", "riscv-decode", "rustsbi", - "sbi", + "sbi-rt", + "sbi-spec", "smccc", "spin 0.9.8", "tock-registers", @@ -643,29 +602,40 @@ dependencies = [ [[package]] name = "rustsbi" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c74c6df5cecd1ddc81f953d100cee1111acd981535526d3e89d2854015cf93b" +checksum = "44c13763120794ed11d64bac885fb31d384ae385c3287b0697711b97affbf8ab" dependencies = [ - "riscv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustsbi-macros", "sbi-spec", ] [[package]] -name = "sbi" -version = "0.2.0" +name = "rustsbi-macros" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cb0870400aca7e4487e8ec1e93f9d4288da763cb1da2cedc5102e62b6522ad" +checksum = "a71347da9582cc6b6f3652c7d2c06516c9555690b3738ecdff7e84297f4e17fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] [[package]] -name = "sbi-spec" -version = "0.0.5" +name = "sbi-rt" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a535b1f16d5517a020539569f7e37e61fad35ed0d5352f9fd7073304e2f2dc72" +checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0" dependencies = [ - "static_assertions", + "sbi-spec", ] +[[package]] +name = "sbi-spec" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890" + [[package]] name = "scopeguard" version = "1.2.0" @@ -881,12 +851,6 @@ dependencies = [ "cstr_core", ] -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "wasm-bindgen" version = "0.2.88" diff --git a/Cargo.toml b/Cargo.toml index 0be7fec..ae12e00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,8 +53,9 @@ cortex-a = { package = "aarch64-cpu", version = "9.3.1" } smccc = "0.1.1" [target.'cfg(target_arch = "riscv64")'.dependencies] -rustsbi = { version = "0.3.2", default-features = false, features = [ "legacy", "singleton" ] } -sbi = "0.2.0" +rustsbi = "0.4.0" +sbi-spec = { version = "0.0.7", features = ["legacy"] } +sbi-rt = "0.0.3" riscv = { git = "https://github.com/Zera-Algorithm/riscv" } [dependencies.buddy_system_allocator] @@ -89,4 +90,4 @@ memrsv = [] doc = [] sbi_legacy = [] plic = [] -aia = [] \ No newline at end of file +aia = [] diff --git a/Makefile b/Makefile index 18f5883..5ac2b8d 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,6 @@ QEMU_COMMON_OPTIONS += -m 8g -smp 4 -display none -bios default \ QEMU_NETWORK_OPTIONS = -netdev user,id=n0,hostfwd=tcp::5555-:22 -device virtio-net-device,netdev=n0 QEMU_DISK_OPTIONS = -drive file=${DISK},if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 MKIMAGE_ARCH = riscv -FEATURES += ,sbi_legacy, else $(error bad qemu arch: $(ARCH)) endif diff --git a/src/arch/riscv64/exception.rs b/src/arch/riscv64/exception.rs index 7982454..37c0b90 100644 --- a/src/arch/riscv64/exception.rs +++ b/src/arch/riscv64/exception.rs @@ -5,17 +5,14 @@ use rustsbi::spec::hsm::{EID_HSM, HART_STOP}; use spin::Once; use crate::arch::{ - hypervisor_handle_ecall, ldst_guest_page_fault_handler, A0_NUM, A1_NUM, A2_NUM, A3_NUM, A4_NUM, A5_NUM, A6_NUM, + VmHart, ldst_guest_page_fault_handler, A0_NUM, A1_NUM, A2_NUM, A3_NUM, A4_NUM, A5_NUM, A6_NUM, A7_NUM, }; use crate::kernel::{current_cpu, hvc_guest_handler, interrupt_handler}; use super::interface::ContextFrame; -use super::{init_ecall_handler, riscv_get_pending_irqs}; +use super::riscv_get_pending_irqs; use riscv::register::{sstatus, vsstatus}; -#[cfg(not(feature = "sbi_legacy"))] -use super::VmHart; - pub const INTR_CAUSE: [&str; 16] = [ "Reserved", "Supervisor software interrupt", @@ -68,9 +65,7 @@ const STORE_PAGE_FAULT: usize = 15; const ECALL_FROM_VS: usize = 10; // spin::Once> = spin::Once::new(); -#[cfg(feature = "sbi_legacy")] -static SBI_VM_HART: Once = Once::new(); -#[cfg(not(feature = "sbi_legacy"))] + static SBI_VM_HART: Once = Once::new(); fn ecall_handler(ctx: &mut ContextFrame) { @@ -103,18 +98,7 @@ fn ecall_handler(ctx: &mut ContextFrame) { return; } - #[cfg(not(feature = "sbi_legacy"))] - { - ret = - SBI_VM_HART - .call_once(|| VmHart::new()) - .handle_ecall(eid as usize, fid as usize, [x0, x1, x2, x3, x4, x5]); - } - #[cfg(feature = "sbi_legacy")] - { - SBI_VM_HART.call_once(init_ecall_handler); - ret = hypervisor_handle_ecall(eid as usize, fid as usize, [x0, x1, x2, x3, x4, x5]); - } + ret = SBI_VM_HART.call_once(|| VmHart::new()).handle_ecall(eid as usize, fid as usize, [x0, x1, x2, x3, x4, x5]); if eid == EID_HSM as u64 && fid == HART_STOP as u64 { // hart_stop,no need to move elr diff --git a/src/arch/riscv64/interrupt.rs b/src/arch/riscv64/interrupt.rs index b4f960e..f622423 100644 --- a/src/arch/riscv64/interrupt.rs +++ b/src/arch/riscv64/interrupt.rs @@ -1,4 +1,4 @@ -use sbi::HartMask; +use sbi_spec::binary::HartMask; use crate::arch::psci_vcpu_on; use crate::arch::InterruptController; #[cfg(feature = "plic")] @@ -146,7 +146,7 @@ impl InterruptController for IntCtrl { #[allow(unused_variables)] fn ipi_send(cpu_id: usize, ipi_id: usize) { // TODO: can't specify ipi_id - let _ = sbi::ipi::send_ipi(HartMask::from(cpu_id)); + sbi_rt::send_ipi(HartMask::from_mask_base(1, cpu_id)); } fn vm_inject(vm: &crate::kernel::Vm, vcpu: &crate::kernel::Vcpu, int_id: usize) { diff --git a/src/arch/riscv64/mod.rs b/src/arch/riscv64/mod.rs index efba95a..a10a81b 100644 --- a/src/arch/riscv64/mod.rs +++ b/src/arch/riscv64/mod.rs @@ -15,10 +15,7 @@ mod imsic; mod plic; pub mod power; pub mod regs; -#[cfg(not(feature = "sbi_legacy"))] mod sbicall; -#[cfg(feature = "sbi_legacy")] -mod sbicall_legacy; mod smmu; mod start; pub mod timer; @@ -42,10 +39,7 @@ pub use aplic::*; #[cfg(feature = "aia")] pub use imsic::*; pub use regs::*; -#[cfg(not(feature = "sbi_legacy"))] pub use sbicall::*; -#[cfg(feature = "sbi_legacy")] -pub use sbicall_legacy::*; pub use start::*; pub use timer::*; pub use tlb::*; diff --git a/src/arch/riscv64/power.rs b/src/arch/riscv64/power.rs index 33c3225..fc55d77 100644 --- a/src/arch/riscv64/power.rs +++ b/src/arch/riscv64/power.rs @@ -3,10 +3,7 @@ use crate::{ kernel::{current_cpu, vcpu_set_vgein, CpuState, Scheduler, Vcpu, Vm}, }; use riscv::register::hstatus; -use sbi::{ - system_reset::{ResetType, ResetReason}, - hart_state_management::{hart_stop, hart_start}, -}; +use sbi_rt::{hart_start, hart_stop, system_reset, ColdReboot, NoReason, Shutdown}; use super::{A0_NUM, A1_NUM}; @@ -16,8 +13,8 @@ use super::{A0_NUM, A1_NUM}; /// 2. 'entry' must be a valid address for cpu to jump. pub unsafe fn power_arch_cpu_on(hart_id: usize, entry: usize, ctx: usize) -> usize { // a1 = ctx - if let Err(e) = hart_start(hart_id, entry, ctx) { - warn!("hart {} start failed! {}", hart_id, e); + if let Err(e) = hart_start(hart_id, entry, ctx).into_result() { + warn!("hart {} start failed! {:?}", hart_id, e); // use non-0 number when error happens 1 } else { @@ -27,10 +24,10 @@ pub unsafe fn power_arch_cpu_on(hart_id: usize, entry: usize, ctx: usize) -> usi pub fn power_arch_cpu_shutdown() { // TODO: Maybe just leave the cpu idle? - match hart_stop() { + match hart_stop().into_result() { Ok(_) => {} Err(e) => { - panic!("hart_stop failed! {}", e); + panic!("hart_stop failed! {:?}", e); } } } @@ -39,11 +36,11 @@ pub fn power_arch_cpu_shutdown() { /// # Safety: /// The platform must support reset operation. pub unsafe fn power_arch_sys_reset() { - sbi::system_reset::system_reset(ResetType::ColdReboot, ResetReason::NoReason).unwrap(); + system_reset(ColdReboot, NoReason).unwrap(); } pub fn power_arch_sys_shutdown() { - let _ = sbi::system_reset::system_reset(ResetType::Shutdown, ResetReason::NoReason); + let _ = system_reset(Shutdown, NoReason); } #[allow(unused_variables)] diff --git a/src/arch/riscv64/sbicall.rs b/src/arch/riscv64/sbicall.rs index 4a7f8a0..5c91731 100644 --- a/src/arch/riscv64/sbicall.rs +++ b/src/arch/riscv64/sbicall.rs @@ -1,40 +1,46 @@ -/// This file is temporarily abandoned and is currently in use sbicall_legacy.rs -use core::{arch::asm, panic}; - use alloc::vec::Vec; /// This file provides the interface that the VM accesses to the upper-layer SBI. /// For some SBI operations, Hypervisor emulation is required instead of /// directly invoking the M-state SBI software. -use rustsbi::{ - spec::{ - binary::SbiRet, - hsm::{HART_STATE_STARTED, HART_STATE_STOPPED}, - }, - Hsm, Ipi, MachineInfo, Pmu, Reset, RustSBI, Timer, -}; -use sbi::HartMask; +use rustsbi::{RustSBI, Console, Hsm, Ipi, Pmu, Reset, Timer, EnvInfo, HartMask}; +use sbi_spec::binary::{Physical, SbiRet}; +use sbi_spec::base::{impl_id::KVM, EID_BASE, PROBE_EXTENSION}; +use sbi_spec::hsm::{HART_START, HART_STOP}; + use spin::Mutex; use timer::timer_arch_get_counter; use crate::{ arch::{ power_arch_cpu_on, - riscv64::{cpu, vcpu}, timer, }, kernel::{ - active_vm, current_cpu, ipi_send_msg, CpuState, IpiInnerMsg, IpiIntInjectMsg, IpiMessage, IpiPowerMessage, + active_vm, current_cpu, ipi_send_msg, CpuState, IpiInnerMsg, IpiIntInjectMsg, IpiPowerMessage, IpiType, PowerEvent, StartReason, VcpuState, Vm, CPU_IF_LIST, }, }; use crate::kernel::IpiType::IpiTIntInject; use crate::kernel::IpiInnerMsg::IntInjectMsg; -use super::{IRQ_IPI, NUM_CORE}; +use super::IRQ_IPI; use crate::kernel::Scheduler; -pub struct VmHart { - pub env: Mutex>, +#[derive(Default)] +struct VConsole {} + +impl Console for VConsole { + fn write(&self, bytes: Physical<&[u8]>) -> SbiRet { + sbi_rt::console_write(bytes) + } + + fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet { + sbi_rt::console_read(bytes) + } + + fn write_byte(&self, byte: u8) -> SbiRet { + sbi_rt::console_write_byte(byte) + } } #[derive(Default)] @@ -69,11 +75,11 @@ impl Timer for VTimer { struct VIpi {} impl Ipi for VIpi { - fn send_ipi(&self, hart_mask: rustsbi::HartMask) -> rustsbi::spec::binary::SbiRet { + fn send_ipi(&self, hart_mask: HartMask) -> SbiRet { info!("sbi_send_ipi: {:?}", hart_mask); let vm = current_cpu().active_vcpu.as_ref().unwrap().vm().unwrap(); let vm_id = vm.id(); - let (pcpu_ids, valid) = get_pcpu_ids(vm, hart_mask); + let (pcpu_ids, valid) = get_pcpu_ids(&vm, hart_mask); if !valid { SbiRet::invalid_param() @@ -96,9 +102,10 @@ impl Ipi for VIpi { } #[inline(always)] -fn get_pcpu_ids(vm: Vm, hart_mask: rustsbi::HartMask) -> (Vec, bool) { +fn get_pcpu_ids(vm: &Vm, hart_mask: HartMask) -> (Vec, bool) { let mut ret: Vec = Vec::new(); - let nvcpu = vm.inner().lock().vcpu_list.len(); + // let nvcpu = vm.inner().lock().vcpu_list.len(); + let nvcpu = vm.cpu_num(); let mut valid = true; for i in 0..64 { @@ -117,72 +124,56 @@ fn get_pcpu_ids(vm: Vm, hart_mask: rustsbi::HartMask) -> (Vec, bool) { (ret, valid) } -#[derive(Default)] -struct VRfnc {} - +// Converts the vCPU-based hart mask to the hart mask of the pcpu corresponding to the vcpu of the current vm +// If an error occurs (for example, the vcpu core number exceeds the number of Vcpus on the vm), return an empty HartMask #[inline(always)] -fn rustsbi_hart_mask_to_sbi(hart_mask: rustsbi::HartMask) -> sbi::HartMask { - let mut base: usize = 0; - for i in 0..64 { - if hart_mask.has_bit(i) { - base = i; - break; +fn vcpu_hart_mask_to_pcpu_mask(hart_mask: HartMask) -> HartMask { + let (pcpus, valid) = get_pcpu_ids(&active_vm().unwrap(), hart_mask.clone()); + if valid { + let mut mask: usize = 0; + for pcpu in pcpus { + mask |= 1 << pcpu; } + HartMask::from_mask_base(mask, 0) + } else { + // no core selected + warn!( + "vcpu_hart_mask_to_pcpu_mask: no core selected since invalid hart_mask: {:?}!", + hart_mask + ); + HartMask::from_mask_base(0,0) } +} - let mask = sbi::HartMask::new(base); - for i in 0..64 { - if hart_mask.has_bit(i) { - mask.with(i); - } - } +#[derive(Default)] +struct VRfnc {} - mask -} impl rustsbi::Fence for VRfnc { - fn remote_fence_i(&self, hart_mask: rustsbi::HartMask) -> rustsbi::spec::binary::SbiRet { - sbi::rfence::remote_fence_i(rustsbi_hart_mask_to_sbi(hart_mask)).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |x| SbiRet { error: 0, value: 0 }, - ) + fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet { + sbi_rt::remote_fence_i(vcpu_hart_mask_to_pcpu_mask(hart_mask)) } fn remote_sfence_vma( &self, - hart_mask: rustsbi::HartMask, + hart_mask: HartMask, start_addr: usize, size: usize, - ) -> rustsbi::spec::binary::SbiRet { - let sbi_mask = rustsbi_hart_mask_to_sbi(hart_mask); + ) -> SbiRet { + let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); // On harts specified by hart_mask,execute hfence.vvma(vmid, start_addr, size) (vmid is from current cpu's hgatp) - sbi::rfence::remote_hfence_vvma(sbi_mask, start_addr, size).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |x| SbiRet { error: 0, value: 0 }, - ) + sbi_rt::remote_hfence_vvma(sbi_mask, start_addr, size) } fn remote_sfence_vma_asid( &self, - hart_mask: rustsbi::HartMask, + hart_mask: HartMask, start_addr: usize, size: usize, asid: usize, - ) -> rustsbi::spec::binary::SbiRet { - let sbi_mask = rustsbi_hart_mask_to_sbi(hart_mask); - sbi::rfence::remote_hfence_vvma_asid(sbi_mask, start_addr, size, asid).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |x| SbiRet { error: 0, value: 0 }, - ) + ) -> SbiRet { + let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); + sbi_rt::remote_hfence_vvma_asid(sbi_mask, start_addr, size, asid) } } @@ -193,7 +184,9 @@ impl Hsm for VHsm { // TODO: needs to handle the cpu hart stop restart. This is not a real stop, // but into the sleep state, need to call PsciIpiCpuOn // similar to psci guest cpu on this function (in fact, it is also copied from the aarch64 function) - fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> rustsbi::spec::binary::SbiRet { + fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> SbiRet { + info!("hart_start: {}, {:08x}, {}", hartid, start_addr, opaque); + let vm = active_vm().unwrap(); let physical_linear_id = vm.vcpuid_to_pcpuid(hartid); @@ -204,8 +197,6 @@ impl Hsm for VHsm { let cpu_idx = physical_linear_id.unwrap(); - debug!("[hart_start] {}, {}", hartid, start_addr); - // Get physical cpu's current status let state = CPU_IF_LIST.lock().get(cpu_idx).unwrap().state_for_start; @@ -260,7 +251,7 @@ impl Hsm for VHsm { } } - fn hart_stop(&self) -> rustsbi::spec::binary::SbiRet { + fn hart_stop(&self) -> SbiRet { // Note: copy from aarch64 code // save the vcpu context for resume current_cpu().active_vcpu.clone().unwrap().reset_context(); @@ -275,18 +266,18 @@ impl Hsm for VHsm { SbiRet::success(0) } - fn hart_get_status(&self, hartid: usize) -> rustsbi::spec::binary::SbiRet { + fn hart_get_status(&self, hartid: usize) -> SbiRet { let vm = active_vm().unwrap(); let vcpu_ = vm.vcpu(hartid); if let Some(vcpu) = vcpu_ { let state = vcpu.state(); match state { // Both the running state and the ready state are HART_STATE_STARTED - VcpuState::Running => SbiRet::success(HART_STATE_STARTED), - VcpuState::Ready => SbiRet::success(HART_STATE_STARTED), + VcpuState::Running => SbiRet::success(HART_START), + VcpuState::Ready => SbiRet::success(HART_START), // The inactive state and the sleep state (which is no longer functioning) are both HART_STATE_STOPPED - VcpuState::Invalid => SbiRet::success(HART_STATE_STOPPED), - VcpuState::Sleep => SbiRet::success(HART_STATE_STOPPED), + VcpuState::Invalid => SbiRet::success(HART_STOP), + VcpuState::Sleep => SbiRet::success(HART_STOP), } } else { SbiRet::invalid_param() @@ -297,8 +288,9 @@ impl Hsm for VHsm { #[derive(Default)] struct VSrst {} +#[allow(unused_variables)] impl Reset for VSrst { - fn system_reset(&self, reset_type: u32, reset_reason: u32) -> rustsbi::spec::binary::SbiRet { + fn system_reset(&self, reset_type: u32, reset_reason: u32) -> SbiRet { todo!() } } @@ -306,12 +298,13 @@ impl Reset for VSrst { #[derive(Default)] struct VPmu {} +#[allow(unused_variables)] impl Pmu for VPmu { fn num_counters(&self) -> usize { todo!() } - fn counter_get_info(&self, counter_idx: usize) -> rustsbi::spec::binary::SbiRet { + fn counter_get_info(&self, counter_idx: usize) -> SbiRet { todo!() } @@ -322,7 +315,7 @@ impl Pmu for VPmu { config_flags: usize, event_idx: usize, event_data: u64, - ) -> rustsbi::spec::binary::SbiRet { + ) -> SbiRet { todo!() } @@ -332,7 +325,7 @@ impl Pmu for VPmu { counter_idx_mask: usize, start_flags: usize, initial_value: u64, - ) -> rustsbi::spec::binary::SbiRet { + ) -> SbiRet { todo!() } @@ -341,39 +334,99 @@ impl Pmu for VPmu { counter_idx_base: usize, counter_idx_mask: usize, stop_flags: usize, - ) -> rustsbi::spec::binary::SbiRet { + ) -> SbiRet { todo!() } - fn counter_fw_read(&self, counter_idx: usize) -> rustsbi::spec::binary::SbiRet { + fn counter_fw_read(&self, counter_idx: usize) -> SbiRet { todo!() } } -// The mutual exclusion of SBICALL is maintained by the **underlying function**, and the Hypervisor does not hold the lock +#[derive(Default)] +struct VInfo {} + +impl EnvInfo for VInfo { + fn mvendorid(&self) -> usize { + 0x0 + } + + fn marchid(&self) -> usize { + 0x0 + } + + fn mimpid(&self) -> usize { + KVM + } +} + + +pub struct VmHart { + pub env: Mutex, +} + +#[derive(RustSBI, Default)] +pub struct ShyperSBI { + console: VConsole, + timer: VTimer, + ipi: VIpi, + hsm: VHsm, + reset: VSrst, + fence: VRfnc, + pmu: VPmu, + info: VInfo, +} + + impl VmHart { pub fn new() -> Self { - let info = MachineInfo { - mvendorid: 0, - marchid: 0, - mimpid: 0, - }; VmHart { - env: Mutex::new(RustSBI::with_machine_info( - VTimer::default(), - VIpi::default(), - VRfnc::default(), - VHsm::default(), - VSrst::default(), - VPmu::default(), - info, - )), + env: Mutex::new(ShyperSBI{ + console: VConsole::default(), + timer: VTimer::default(), + ipi: VIpi::default(), + fence: VRfnc::default(), + hsm: VHsm::default(), + reset: VSrst::default(), + pmu: VPmu::default(), + info: VInfo::default(), + }), } } /// ecall dispatch function #[inline(always)] + #[allow(unused_mut)] pub fn handle_ecall(&self, extension: usize, function: usize, param: [usize; 6]) -> SbiRet { - self.env.lock().handle_ecall(extension, function, param) + use sbi_spec::legacy::{LEGACY_CONSOLE_GETCHAR, LEGACY_CONSOLE_PUTCHAR}; + match extension { + EID_BASE => { + match function { + PROBE_EXTENSION => { + if matches!(param[0], LEGACY_CONSOLE_GETCHAR | LEGACY_CONSOLE_PUTCHAR) { + SbiRet::success(1) + } else { + self.env.lock().handle_ecall(extension, function, param) + } + } + _ => { self.env.lock().handle_ecall(extension, function, param) } + } + } + LEGACY_CONSOLE_GETCHAR => { + let mut ch: u8 = 0; + let byte = Physical::new(1, 0, &ch as *const u8 as usize); + sbi_rt::console_read(byte); + let mut sbi_ret = SbiRet::success(0); + sbi_ret.error = ch as usize; + sbi_ret + } + LEGACY_CONSOLE_PUTCHAR => { + sbi_rt::console_write_byte(param[0] as u8) + } + _ => { + self.env.lock().handle_ecall(extension,function, param) + } + + } } -} +} \ No newline at end of file diff --git a/src/arch/riscv64/sbicall_legacy.rs b/src/arch/riscv64/sbicall_legacy.rs deleted file mode 100644 index 1ba3fbd..0000000 --- a/src/arch/riscv64/sbicall_legacy.rs +++ /dev/null @@ -1,379 +0,0 @@ -use alloc::vec::Vec; -/// This file provides the interface that the VM accesses to the upper-layer SBI. -/// For some SBI operations, Hypervisor emulation is required instead of -/// directly invoking the M-state SBI software. -use rustsbi::{ - init_hsm, init_ipi, /*init_pmu,*/ init_remote_fence, init_reset, init_timer, - spec::{ - base::{impl_id::KVM, EID_BASE, GET_MARCHID, GET_MIMPID, GET_MVENDORID}, - binary::SbiRet, - hsm::{HART_STATE_STARTED, HART_STATE_STOPPED}, - }, - Hsm, Ipi, Pmu, Reset, Timer, -}; -use rustsbi::legacy_stdio::LegacyStdio; -use rustsbi::legacy_stdio::init_legacy_stdio; - -use crate::kernel::{ - active_vm, current_cpu, ipi_send_msg, IpiInnerMsg, IpiIntInjectMsg, IpiPowerMessage, IpiType, PowerEvent, - VcpuState, Vm, -}; -use crate::kernel::IpiType::IpiTIntInject; -use crate::kernel::IpiInnerMsg::IntInjectMsg; - -use super::IRQ_IPI; -use crate::kernel::Scheduler; - -#[derive(Default)] -struct VTimer {} - -impl Timer for VTimer { - fn set_timer(&self, stime_value: u64) { - // Clear the current hart clock interrupt (triggered by setting the next timer) - riscv::register::hvip::clear_timing_interrupt(); - - // SAFETY: Enable timer interrupt - unsafe { riscv::register::sie::set_stimer() }; - - // Set the time for the next vcpu clock interruption at the VCPU level - current_cpu() - .active_vcpu - .as_ref() - .unwrap() - .inner - .inner_mut - .lock() - .vm_ctx - .next_timer_intr = stime_value; - } -} - -#[derive(Default)] -struct VIpi {} - -impl Ipi for VIpi { - fn send_ipi(&self, hart_mask: rustsbi::HartMask) -> rustsbi::spec::binary::SbiRet { - let vm = current_cpu().active_vcpu.as_ref().unwrap().vm().unwrap(); - let vm_id = vm.id(); - let (pcpu_ids, valid) = get_pcpu_ids(&vm, hart_mask); - - if !valid { - SbiRet::invalid_param() - } else { - for pcpu in pcpu_ids { - // Send remote IPI request for injection interrupt - let ok = ipi_send_msg( - pcpu, - IpiTIntInject, - IntInjectMsg(IpiIntInjectMsg { vm_id, int_id: IRQ_IPI }), - ); - if !ok { - warn!("send ipi failed!"); - return SbiRet::failed(); - } - } - SbiRet::success(0) - } - } -} - -#[inline(always)] -fn get_pcpu_ids(vm: &Vm, hart_mask: rustsbi::HartMask) -> (Vec, bool) { - let mut ret: Vec = Vec::new(); - let nvcpu = vm.cpu_num(); - let mut valid = true; - - for i in 0..64 { - if hart_mask.has_bit(i) { - // If the number of cpus selected by Hart Mask exceeds the number of vcpus, an error is returned - if i >= nvcpu { - valid = false; - break; - } - - let pcpu = vm.vcpu(i).unwrap().phys_id(); - ret.push(pcpu); - } - } - - (ret, valid) -} - -#[derive(Default)] -struct VRfnc {} - -// Convert the hart mask in rustsbi format to the hart mask in sbi format -#[inline(always)] -fn rustsbi_hart_mask_to_sbi(hart_mask: rustsbi::HartMask) -> sbi::HartMask { - let mut base: usize = 0; - for i in 0..64 { - if hart_mask.has_bit(i) { - base = i; - break; - } - } - - let mask = sbi::HartMask::new(base); - for i in 0..64 { - if hart_mask.has_bit(i) { - let _ = mask.with(i); - } - } - - mask -} - -// Converts the vCPU-based hart mask to the hart mask of the pcpu corresponding to the vcpu of the current vm -// If an error occurs (for example, the vcpu core number exceeds the number of Vcpus on the vm), return an empty HartMask -#[inline(always)] -fn vcpu_hart_mask_to_pcpu_mask(hart_mask: rustsbi::HartMask) -> sbi::HartMask { - let (pcpus, valid) = get_pcpu_ids(&active_vm().unwrap(), hart_mask.clone()); - if valid { - let mask = sbi::HartMask::new(0); - for pcpu in pcpus { - let _ = mask.with(pcpu); - } - mask - } else { - // no core selected - warn!( - "vcpu_hart_mask_to_pcpu_mask: no core selected since invalid hart_mask: {:?}!", - hart_mask - ); - sbi::HartMask::new(0) - } -} - -// hart mask is parsed by vcpu, not by pcpu -impl rustsbi::Fence for VRfnc { - fn remote_fence_i(&self, hart_mask: rustsbi::HartMask) -> rustsbi::spec::binary::SbiRet { - sbi::rfence::remote_fence_i(vcpu_hart_mask_to_pcpu_mask(hart_mask)).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |_x| SbiRet { error: 0, value: 0 }, - ) - } - - fn remote_sfence_vma( - &self, - hart_mask: rustsbi::HartMask, - start_addr: usize, - size: usize, - ) -> rustsbi::spec::binary::SbiRet { - let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); - // On harts specified by hart_mask,execute hfence.vvma(vmid, start_addr, size) (vmid is from current cpu's hgatp) - sbi::rfence::remote_hfence_vvma(sbi_mask, start_addr, size).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |_x| SbiRet { error: 0, value: 0 }, - ) - } - - fn remote_sfence_vma_asid( - &self, - hart_mask: rustsbi::HartMask, - start_addr: usize, - size: usize, - asid: usize, - ) -> rustsbi::spec::binary::SbiRet { - let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); - sbi::rfence::remote_hfence_vvma_asid(sbi_mask, start_addr, size, asid).map_or_else( - |err| SbiRet { - error: (-(err as isize)) as usize, - value: 0, - }, - |_x| SbiRet { error: 0, value: 0 }, - ) - } -} - -#[derive(Default)] -struct VHsm {} - -impl Hsm for VHsm { - // TODO: needs to handle the cpu hart stop restart. This is not a real stop, - // but into the sleep state, need to call PsciIpiCpuOn - // similar to psci guest cpu on this function (in fact, it is also copied from the aarch64 function) - fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> rustsbi::spec::binary::SbiRet { - info!("hart_start: {}, {:08x}, {}", hartid, start_addr, opaque); - - let vcpu_id = hartid; - let vm = active_vm().unwrap(); - let physical_linear_id = vm.vcpuid_to_pcpuid(vcpu_id); - - if vcpu_id >= vm.cpu_num() || physical_linear_id.is_err() { - warn!("hart_start: target vcpu {} not exist", vcpu_id); - return SbiRet::invalid_param(); - } - - let m = IpiPowerMessage { - src: vm.id(), - vcpuid: 0, - event: PowerEvent::PsciIpiCpuOn, - entry: start_addr, - context: opaque, - }; - - // Receiver and handler are in psci_ipi_handler function of `interrupt.rs` - if !ipi_send_msg(physical_linear_id.unwrap(), IpiType::IpiTPower, IpiInnerMsg::Power(m)) { - warn!("psci_guest_cpu_on: fail to send msg"); - return SbiRet::failed(); - } - - SbiRet::success(0) - } - - fn hart_stop(&self) -> rustsbi::spec::binary::SbiRet { - // Note: copy from aarch64 code - // save the vcpu context for resume - current_cpu().active_vcpu.clone().unwrap().reset_context(); - - // There is no need to explicitly call do schedule - // because sleep automatically schedules the next vcpu - // when it detects that sleep has an active vcpu - current_cpu() - .scheduler() - .sleep(current_cpu().active_vcpu.clone().unwrap()); - - SbiRet::success(0) - } - - fn hart_get_status(&self, hartid: usize) -> rustsbi::spec::binary::SbiRet { - let vm = active_vm().unwrap(); - let vcpu_ = vm.vcpu(hartid); - if let Some(vcpu) = vcpu_ { - let state = vcpu.state(); - match state { - // Both the running state and the ready state are HART_STATE_STARTED - VcpuState::Running => SbiRet::success(HART_STATE_STARTED), - VcpuState::Ready => SbiRet::success(HART_STATE_STARTED), - // The inactive state and the sleep state (which is no longer functioning) are both HART_STATE_STOPPED - VcpuState::Invalid => SbiRet::success(HART_STATE_STOPPED), - VcpuState::Sleep => SbiRet::success(HART_STATE_STOPPED), - } - } else { - SbiRet::invalid_param() - } - } -} - -#[derive(Default)] -struct VSrst {} - -impl Reset for VSrst { - #[allow(unused_variables)] - fn system_reset(&self, reset_type: u32, reset_reason: u32) -> rustsbi::spec::binary::SbiRet { - todo!() - } -} - -#[derive(Default)] -struct VPmu {} - -impl Pmu for VPmu { - fn num_counters(&self) -> usize { - todo!() - } - - #[allow(unused_variables)] - fn counter_get_info(&self, counter_idx: usize) -> rustsbi::spec::binary::SbiRet { - todo!() - } - - #[allow(unused_variables)] - fn counter_config_matching( - &self, - counter_idx_base: usize, - counter_idx_mask: usize, - config_flags: usize, - event_idx: usize, - event_data: u64, - ) -> rustsbi::spec::binary::SbiRet { - todo!() - } - - #[allow(unused_variables)] - fn counter_start( - &self, - counter_idx_base: usize, - counter_idx_mask: usize, - start_flags: usize, - initial_value: u64, - ) -> rustsbi::spec::binary::SbiRet { - todo!() - } - - #[allow(unused_variables)] - fn counter_stop( - &self, - counter_idx_base: usize, - counter_idx_mask: usize, - stop_flags: usize, - ) -> rustsbi::spec::binary::SbiRet { - todo!() - } - - #[allow(unused_variables)] - fn counter_fw_read(&self, counter_idx: usize) -> rustsbi::spec::binary::SbiRet { - todo!() - } -} - -#[derive(Default)] -struct VLegacyStdio {} - -const GETC_EMPTY: u8 = 255; - -impl LegacyStdio for VLegacyStdio { - fn getchar(&self) -> u8 { - match sbi::legacy::console_getchar() { - Some(c) => c, - None => GETC_EMPTY, - } - } - - fn putchar(&self, ch: u8) { - sbi::legacy::console_putchar(ch); - } -} -static TIMER: VTimer = VTimer {}; -static IPI: VIpi = VIpi {}; -static RFNC: VRfnc = VRfnc {}; -static HSM: VHsm = VHsm {}; -static SRST: VSrst = VSrst {}; -static PMU: VPmu = VPmu {}; -static STDIO: VLegacyStdio = VLegacyStdio {}; - -// The mutual exclusion of SBICALL is maintained by the **underlying function**, and the Hypervisor does not hold the lock -pub fn init_ecall_handler() { - init_timer(&TIMER); - init_ipi(&IPI); - init_remote_fence(&RFNC); - init_hsm(&HSM); - init_reset(&SRST); - //init_pmu(&PMU); - init_legacy_stdio(&STDIO); -} - -/// ecall dispatch function -#[inline(always)] -pub fn hypervisor_handle_ecall(extension: usize, function: usize, param: [usize; 6]) -> SbiRet { - // patch - if extension == EID_BASE { - match function { - GET_MARCHID => { - let marchid = 0; - SbiRet::success(marchid) - } - GET_MIMPID => SbiRet::success(KVM), - GET_MVENDORID => SbiRet::success(0), - _ => rustsbi::ecall(extension, function, param), - } - } else { - rustsbi::ecall(extension, function, param) - } -} diff --git a/src/arch/riscv64/start.rs b/src/arch/riscv64/start.rs index ec7a680..a9f8d11 100644 --- a/src/arch/riscv64/start.rs +++ b/src/arch/riscv64/start.rs @@ -260,7 +260,7 @@ pub fn arch_boot_secondary_cores(dtb: &mut fdt::myctypes::c_void) { if (BOOTED_CORES.load(SeqCst) & (1 << i)) != 0 { continue; } - let result = sbi::hsm::hart_start(i, _secondary_start as usize, dtb as *mut _ as usize); + let result = sbi_rt::hart_start(i, _secondary_start as usize, dtb as *mut _ as usize).into_result(); if let Err(err) = result { println!("An error happens when booting core {}: {:?}", i, err); } diff --git a/src/arch/riscv64/timer.rs b/src/arch/riscv64/timer.rs index f09ce6f..caa17d9 100644 --- a/src/arch/riscv64/timer.rs +++ b/src/arch/riscv64/timer.rs @@ -1,4 +1,3 @@ -use sbi; use riscv; use spin::Mutex; @@ -38,7 +37,7 @@ pub fn timer_arch_set(num_ms: usize) { let slice_lock = TIMER_SLICE.lock(); let val = *slice_lock * num_ms; drop(slice_lock); - let _ = sbi::timer::set_timer((timer_arch_get_counter() + val) as u64); + let _ = sbi_rt::set_timer((timer_arch_get_counter() + val) as u64); } pub fn timer_arch_init() { diff --git a/src/utils/print.rs b/src/utils/print.rs index b822ef9..1208189 100644 --- a/src/utils/print.rs +++ b/src/utils/print.rs @@ -21,7 +21,7 @@ impl Write for Writer { #[cfg(target_arch = "aarch64")] crate::driver::putc(b); #[cfg(target_arch = "riscv64")] - sbi::legacy::console_putchar(b); + sbi_rt::console_write_byte(b); } Ok(()) } -- Gitee From 3da2b9d57c6a65e6338cfcc1de5dc317c6a4a6ff Mon Sep 17 00:00:00 2001 From: guttatus Date: Tue, 5 Nov 2024 21:05:29 +0800 Subject: [PATCH 2/4] fix: remove unused import and pmu --- src/arch/riscv64/sbicall.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/arch/riscv64/sbicall.rs b/src/arch/riscv64/sbicall.rs index 5c91731..6aa62fb 100644 --- a/src/arch/riscv64/sbicall.rs +++ b/src/arch/riscv64/sbicall.rs @@ -8,13 +8,10 @@ use sbi_spec::base::{impl_id::KVM, EID_BASE, PROBE_EXTENSION}; use sbi_spec::hsm::{HART_START, HART_STOP}; use spin::Mutex; -use timer::timer_arch_get_counter; +// use timer::timer_arch_get_counter; use crate::{ - arch::{ - power_arch_cpu_on, - timer, - }, + arch::power_arch_cpu_on, kernel::{ active_vm, current_cpu, ipi_send_msg, CpuState, IpiInnerMsg, IpiIntInjectMsg, IpiPowerMessage, IpiType, PowerEvent, StartReason, VcpuState, Vm, CPU_IF_LIST, @@ -48,8 +45,7 @@ struct VTimer {} impl Timer for VTimer { fn set_timer(&self, stime_value: u64) { - info!("set_timer: {}, current_time: {}", stime_value, timer_arch_get_counter()); - + // info!("set_timer: {}, current_time: {}", stime_value, timer_arch_get_counter()); // Clear the current hart clock interrupt (triggered by setting the next timer) riscv::register::hvip::clear_timing_interrupt(); @@ -371,9 +367,8 @@ pub struct ShyperSBI { timer: VTimer, ipi: VIpi, hsm: VHsm, - reset: VSrst, fence: VRfnc, - pmu: VPmu, + reset: VSrst, info: VInfo, } @@ -388,7 +383,6 @@ impl VmHart { fence: VRfnc::default(), hsm: VHsm::default(), reset: VSrst::default(), - pmu: VPmu::default(), info: VInfo::default(), }), } -- Gitee From bb54e63c4274dee734c29c2aff5a1810a820f501 Mon Sep 17 00:00:00 2001 From: guttatus Date: Fri, 8 Nov 2024 11:11:14 +0800 Subject: [PATCH 3/4] fix: use sbicall_legacy's hart_start implemention --- src/arch/riscv64/sbicall.rs | 74 +++++++++---------------------------- 1 file changed, 18 insertions(+), 56 deletions(-) diff --git a/src/arch/riscv64/sbicall.rs b/src/arch/riscv64/sbicall.rs index 6aa62fb..7a2f0a2 100644 --- a/src/arch/riscv64/sbicall.rs +++ b/src/arch/riscv64/sbicall.rs @@ -72,7 +72,7 @@ struct VIpi {} impl Ipi for VIpi { fn send_ipi(&self, hart_mask: HartMask) -> SbiRet { - info!("sbi_send_ipi: {:?}", hart_mask); + // info!("sbi_send_ipi: {:?}", hart_mask); let vm = current_cpu().active_vcpu.as_ref().unwrap().vm().unwrap(); let vm_id = vm.id(); let (pcpu_ids, valid) = get_pcpu_ids(&vm, hart_mask); @@ -183,68 +183,30 @@ impl Hsm for VHsm { fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> SbiRet { info!("hart_start: {}, {:08x}, {}", hartid, start_addr, opaque); + let vcpu_id = hartid; let vm = active_vm().unwrap(); - let physical_linear_id = vm.vcpuid_to_pcpuid(hartid); + let physical_linear_id = vm.vcpuid_to_pcpuid(vcpu_id); - if hartid > vm.cpu_num() || physical_linear_id.is_err() { - warn!("hart_start: invalid hartid {}", hartid); + if vcpu_id >= vm.cpu_num() || physical_linear_id.is_err() { + warn!("hart_start: target vcpu {} not exist", vcpu_id); return SbiRet::invalid_param(); } - let cpu_idx = physical_linear_id.unwrap(); - - // Get physical cpu's current status - let state = CPU_IF_LIST.lock().get(cpu_idx).unwrap().state_for_start; - - let mut r = 0; - if state == CpuState::CpuInv { - // If a pcpu is in the closed state, schedule a vcpu to start the pcpu - let mut cpu_if_list = CPU_IF_LIST.lock(); - if let Some(cpu_if) = cpu_if_list.get_mut(cpu_idx) { - cpu_if.ctx = opaque as u64; - cpu_if.entry = start_addr as u64; - cpu_if.vm_id = vm.id(); - cpu_if.state_for_start = CpuState::CpuIdle; - cpu_if.vcpuid = hartid; - cpu_if.start_reason = StartReason::SecondaryCore; - } - drop(cpu_if_list); - - let entry_point = crate::arch::_secondary_start as usize; - - // SAFETY: - // It attempts to power on the CPU specified by the cpu_idx parameter. - // The entry is the address of function _secondary_start. - // The ctx here is the cpu_idx. - unsafe { - r = power_arch_cpu_on(hartid, entry_point, cpu_idx); - } - debug!( - "start to power_arch_cpu_on! hartid={:X}, entry_point={:X}", - hartid, entry_point - ); - } else { - // Pass a message so that the corresponding core is started - // Predetermined assumption: The corresponding core has been started (non-secondary start) - let m = IpiPowerMessage { - src: vm.id(), - vcpuid: hartid, - event: PowerEvent::PsciIpiVcpuAssignAndCpuOn, - entry: start_addr, - context: opaque, - }; - - if !ipi_send_msg(physical_linear_id.unwrap(), IpiType::IpiTPower, IpiInnerMsg::Power(m)) { - warn!("psci_guest_cpu_on: fail to send msg"); - return SbiRet::failed(); - } + let m = IpiPowerMessage { + src: vm.id(), + vcpuid: 0, + event: PowerEvent::PsciIpiCpuOn, + entry: start_addr, + context: opaque, + }; + + // Receiver and handler are in psci_ipi_handler function of `interrupt.rs` + if !ipi_send_msg(physical_linear_id.unwrap(), IpiType::IpiTPower, IpiInnerMsg::Power(m)) { + warn!("psci_guest_cpu_on: fail to send msg"); + return SbiRet::failed(); } - if r == 0 { - SbiRet::success(0) - } else { - SbiRet::failed() - } + SbiRet::success(0) } fn hart_stop(&self) -> SbiRet { -- Gitee From 19e5b153e698355960b12d6ed485f54d4366d2f9 Mon Sep 17 00:00:00 2001 From: guttatus Date: Fri, 8 Nov 2024 22:34:37 +0800 Subject: [PATCH 4/4] fmt: fmt code --- src/arch/riscv64/exception.rs | 9 ++--- src/arch/riscv64/power.rs | 2 +- src/arch/riscv64/sbicall.rs | 76 +++++++++++++---------------------- 3 files changed, 33 insertions(+), 54 deletions(-) diff --git a/src/arch/riscv64/exception.rs b/src/arch/riscv64/exception.rs index 37c0b90..271c908 100644 --- a/src/arch/riscv64/exception.rs +++ b/src/arch/riscv64/exception.rs @@ -4,10 +4,7 @@ use riscv::register::hstatus::{self, VirtualizationMode}; use rustsbi::spec::hsm::{EID_HSM, HART_STOP}; use spin::Once; -use crate::arch::{ - VmHart, ldst_guest_page_fault_handler, A0_NUM, A1_NUM, A2_NUM, A3_NUM, A4_NUM, A5_NUM, A6_NUM, - A7_NUM, -}; +use crate::arch::{VmHart, ldst_guest_page_fault_handler, A0_NUM, A1_NUM, A2_NUM, A3_NUM, A4_NUM, A5_NUM, A6_NUM, A7_NUM}; use crate::kernel::{current_cpu, hvc_guest_handler, interrupt_handler}; use super::interface::ContextFrame; use super::riscv_get_pending_irqs; @@ -98,7 +95,9 @@ fn ecall_handler(ctx: &mut ContextFrame) { return; } - ret = SBI_VM_HART.call_once(|| VmHart::new()).handle_ecall(eid as usize, fid as usize, [x0, x1, x2, x3, x4, x5]); + ret = SBI_VM_HART + .call_once(|| VmHart::new()) + .handle_ecall(eid as usize, fid as usize, [x0, x1, x2, x3, x4, x5]); if eid == EID_HSM as u64 && fid == HART_STOP as u64 { // hart_stop,no need to move elr diff --git a/src/arch/riscv64/power.rs b/src/arch/riscv64/power.rs index fc55d77..7bbb122 100644 --- a/src/arch/riscv64/power.rs +++ b/src/arch/riscv64/power.rs @@ -3,7 +3,7 @@ use crate::{ kernel::{current_cpu, vcpu_set_vgein, CpuState, Scheduler, Vcpu, Vm}, }; use riscv::register::hstatus; -use sbi_rt::{hart_start, hart_stop, system_reset, ColdReboot, NoReason, Shutdown}; +use sbi_rt::{hart_start, hart_stop, system_reset, ColdReboot, NoReason, Shutdown}; use super::{A0_NUM, A1_NUM}; diff --git a/src/arch/riscv64/sbicall.rs b/src/arch/riscv64/sbicall.rs index 7a2f0a2..111f4ad 100644 --- a/src/arch/riscv64/sbicall.rs +++ b/src/arch/riscv64/sbicall.rs @@ -11,10 +11,9 @@ use spin::Mutex; // use timer::timer_arch_get_counter; use crate::{ - arch::power_arch_cpu_on, kernel::{ - active_vm, current_cpu, ipi_send_msg, CpuState, IpiInnerMsg, IpiIntInjectMsg, IpiPowerMessage, - IpiType, PowerEvent, StartReason, VcpuState, Vm, CPU_IF_LIST, + active_vm, current_cpu, ipi_send_msg, IpiInnerMsg, IpiIntInjectMsg, IpiPowerMessage, IpiType, PowerEvent, + VcpuState, Vm, }, }; use crate::kernel::IpiType::IpiTIntInject; @@ -24,7 +23,7 @@ use super::IRQ_IPI; use crate::kernel::Scheduler; #[derive(Default)] -struct VConsole {} +struct VConsole {} impl Console for VConsole { fn write(&self, bytes: Physical<&[u8]>) -> SbiRet { @@ -137,37 +136,25 @@ fn vcpu_hart_mask_to_pcpu_mask(hart_mask: HartMask) -> HartMask { "vcpu_hart_mask_to_pcpu_mask: no core selected since invalid hart_mask: {:?}!", hart_mask ); - HartMask::from_mask_base(0,0) + HartMask::from_mask_base(0, 0) } } #[derive(Default)] struct VRfnc {} - impl rustsbi::Fence for VRfnc { fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet { sbi_rt::remote_fence_i(vcpu_hart_mask_to_pcpu_mask(hart_mask)) } - fn remote_sfence_vma( - &self, - hart_mask: HartMask, - start_addr: usize, - size: usize, - ) -> SbiRet { + fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet { let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); // On harts specified by hart_mask,execute hfence.vvma(vmid, start_addr, size) (vmid is from current cpu's hgatp) sbi_rt::remote_hfence_vvma(sbi_mask, start_addr, size) } - fn remote_sfence_vma_asid( - &self, - hart_mask: HartMask, - start_addr: usize, - size: usize, - asid: usize, - ) -> SbiRet { + fn remote_sfence_vma_asid(&self, hart_mask: HartMask, start_addr: usize, size: usize, asid: usize) -> SbiRet { let sbi_mask = vcpu_hart_mask_to_pcpu_mask(hart_mask); sbi_rt::remote_hfence_vvma_asid(sbi_mask, start_addr, size, asid) } @@ -287,12 +274,7 @@ impl Pmu for VPmu { todo!() } - fn counter_stop( - &self, - counter_idx_base: usize, - counter_idx_mask: usize, - stop_flags: usize, - ) -> SbiRet { + fn counter_stop(&self, counter_idx_base: usize, counter_idx_mask: usize, stop_flags: usize) -> SbiRet { todo!() } @@ -318,7 +300,6 @@ impl EnvInfo for VInfo { } } - pub struct VmHart { pub env: Mutex, } @@ -334,11 +315,10 @@ pub struct ShyperSBI { info: VInfo, } - impl VmHart { pub fn new() -> Self { VmHart { - env: Mutex::new(ShyperSBI{ + env: Mutex::new(ShyperSBI { console: VConsole::default(), timer: VTimer::default(), ipi: VIpi::default(), @@ -356,33 +336,33 @@ impl VmHart { pub fn handle_ecall(&self, extension: usize, function: usize, param: [usize; 6]) -> SbiRet { use sbi_spec::legacy::{LEGACY_CONSOLE_GETCHAR, LEGACY_CONSOLE_PUTCHAR}; match extension { - EID_BASE => { - match function { - PROBE_EXTENSION => { - if matches!(param[0], LEGACY_CONSOLE_GETCHAR | LEGACY_CONSOLE_PUTCHAR) { - SbiRet::success(1) - } else { - self.env.lock().handle_ecall(extension, function, param) - } + EID_BASE => match function { + PROBE_EXTENSION => { + if matches!(param[0], LEGACY_CONSOLE_GETCHAR | LEGACY_CONSOLE_PUTCHAR) { + SbiRet::success(1) + } else { + self.env.lock().handle_ecall(extension, function, param) } - _ => { self.env.lock().handle_ecall(extension, function, param) } } - } + _ => self.env.lock().handle_ecall(extension, function, param), + }, LEGACY_CONSOLE_GETCHAR => { let mut ch: u8 = 0; - let byte = Physical::new(1, 0, &ch as *const u8 as usize); + let byte = Physical::new(1, &ch as *const u8 as usize, 0); sbi_rt::console_read(byte); - let mut sbi_ret = SbiRet::success(0); - sbi_ret.error = ch as usize; - sbi_ret + SbiRet { + error: ch as usize, + value: param[1], + } } LEGACY_CONSOLE_PUTCHAR => { - sbi_rt::console_write_byte(param[0] as u8) - } - _ => { - self.env.lock().handle_ecall(extension,function, param) + sbi_rt::console_write_byte(param[0] as u8); + SbiRet { + error: 0, + value: param[1], + } } - + _ => self.env.lock().handle_ecall(extension, function, param), } } -} \ No newline at end of file +} -- Gitee