From 4434302f5555b6dd11331e86492e037a2d31d861 Mon Sep 17 00:00:00 2001 From: guoweikang Date: Mon, 26 Aug 2024 13:21:38 +0800 Subject: [PATCH 1/2] axdevice init Signed-off-by: guoweikang --- Cargo.toml | 9 +++++++ src/config.rs | 12 +++++++++ src/device.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 22 ++++++++-------- 4 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 src/config.rs create mode 100644 src/device.rs diff --git a/Cargo.toml b/Cargo.toml index 81e3a63..68ee5f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,13 @@ name = "axdevice" version = "0.1.0" edition = "2021" +[features] + [dependencies] +log = "=0.4.19" +cfg-if = "1.0" +serde = { version = "1.0.204", default-features = false, features = ["derive"] } + +emu_device = { git = "https://github.com/arceos-hypervisor/emu-devices.git" } +# System independent crates provided by ArceOS. +axerrno = "0.1.0" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..31f2841 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,12 @@ +use alloc::vec::Vec; +use emu_device::EmulatedDeviceConfig; + +pub struct AxVmDeviceConfig { + pub emu_configs: Vec, +} + +impl AxVmDeviceConfig { + pub fn new(emu_configs: Vec) -> Self { + Self { emu_configs } + } +} diff --git a/src/device.rs b/src/device.rs new file mode 100644 index 0000000..cd80208 --- /dev/null +++ b/src/device.rs @@ -0,0 +1,71 @@ +use alloc::sync::Arc; +use alloc::vec::Vec; + +use emu_device::EmuDev; +use emu_device::EmulatedDeviceConfig; + +use crate::AxVmDeviceConfig; +use axerrno::AxResult; + +// represent A vm own devices +pub struct AxVmDevices { + // emu devices + emu_devices: Vec>, + // TODO passthrough devices or other type devices ... +} + +impl AxVmDevices { + fn init_emu_dev(this: &mut Self, emu_configs: &Vec) { + for config in emu_configs { + let dev = config.to_emu_dev(); + if let Ok(emu_dev) = dev { + this.emu_devices.push(emu_dev) + } + } + } + + pub fn new(config: AxVmDeviceConfig) -> Self { + let mut this = Self { + emu_devices: Vec::new(), + }; + + Self::init_emu_dev(&mut this, &config.emu_configs); + this + } + + pub fn find_emu_dev(&self, ipa: usize) -> Option> { + self.emu_devices + .iter() + .find(|&dev| dev.address_range().contains(&ipa)) + .cloned() + } + + pub fn handle_emu_read(&self, addr: usize, width: usize) -> AxResult { + if let Some(emu_dev) = self.find_emu_dev(addr) { + info!( + "emu: {:?} handler read ipa {:#x}", + emu_dev.address_range(), + addr + ); + return emu_dev.handle_read(addr, width); + } + + panic!("emu_handle: no emul handler for data abort ipa {:#x}", addr); + } + + pub fn handle_emu_write(&self, addr: usize, width: usize, val: usize) { + if let Some(emu_dev) = self.find_emu_dev(addr) { + info!( + "emu: {:?} handler write ipa {:#x}", + emu_dev.address_range(), + addr + ); + emu_dev.handle_write(addr, width, val); + return; + } + panic!( + "emu_handler: no emul handler for data abort ipa {:#x}", + addr + ); + } +} diff --git a/src/lib.rs b/src/lib.rs index b93cf3f..07fdca1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,12 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +#![no_std] -#[cfg(test)] -mod tests { - use super::*; +extern crate alloc; +#[macro_use] +extern crate log; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub use emu_device::EmulatedDeviceConfig; +mod config; +pub use config::AxVmDeviceConfig; + +mod device; +pub use device::AxVmDevices; From cd195972ee1491ccdc4534a40d2d07618fd69190 Mon Sep 17 00:00:00 2001 From: buhenxihuan <1127751018@qq.com> Date: Wed, 28 Aug 2024 16:24:39 +0800 Subject: [PATCH 2/2] refactor the construct; cargo fmt modify the type of addr fmt and modify the init function of AxVmDevices add some doc --- Cargo.toml | 7 +++--- src/config.rs | 6 ++++- src/device.rs | 70 +++++++++++++++++++++++++++++++++------------------ src/lib.rs | 13 +++++++--- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 68ee5f5..ce277fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ edition = "2021" [dependencies] log = "=0.4.19" cfg-if = "1.0" -serde = { version = "1.0.204", default-features = false, features = ["derive"] } - -emu_device = { git = "https://github.com/arceos-hypervisor/emu-devices.git" } +serde = { version = "1.0.204", default-features = false, features = ["derive", "alloc"] } # System independent crates provided by ArceOS. axerrno = "0.1.0" +memory_addr = "0.3.0" +axaddrspace = { git = "https://github.com/arceos-hypervisor/axaddrspace.git" } +axdevice_base = { git = "https://github.com/arceos-hypervisor/axdevice_crates.git"} diff --git a/src/config.rs b/src/config.rs index 31f2841..a70e225 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,11 +1,15 @@ use alloc::vec::Vec; -use emu_device::EmulatedDeviceConfig; +use axdevice_base::EmulatedDeviceConfig; +/// The vector of DeviceConfig pub struct AxVmDeviceConfig { + /// The vector of EmulatedDeviceConfig pub emu_configs: Vec, } +/// The implemention for AxVmDeviceConfig impl AxVmDeviceConfig { + /// The new function for AxVmDeviceConfig pub fn new(emu_configs: Vec) -> Self { Self { emu_configs } } diff --git a/src/device.rs b/src/device.rs index cd80208..6db6a13 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,47 +1,69 @@ +use crate::AxVmDeviceConfig; + use alloc::sync::Arc; use alloc::vec::Vec; -use emu_device::EmuDev; -use emu_device::EmulatedDeviceConfig; - -use crate::AxVmDeviceConfig; +use axaddrspace::GuestPhysAddr; +use axdevice_base::EmulatedDeviceConfig; +use axdevice_base::{BaseDeviceOps, EmuDeviceType}; use axerrno::AxResult; -// represent A vm own devices +/// represent A vm own devices pub struct AxVmDevices { - // emu devices - emu_devices: Vec>, + /// emu devices + emu_devices: Vec>, // TODO passthrough devices or other type devices ... } +/// The implemention for AxVmDevices impl AxVmDevices { - fn init_emu_dev(this: &mut Self, emu_configs: &Vec) { - for config in emu_configs { - let dev = config.to_emu_dev(); - if let Ok(emu_dev) = dev { - this.emu_devices.push(emu_dev) - } - } - } - + /// According AxVmDeviceConfig to init the AxVmDevices pub fn new(config: AxVmDeviceConfig) -> Self { let mut this = Self { emu_devices: Vec::new(), }; - Self::init_emu_dev(&mut this, &config.emu_configs); + Self::init(&mut this, &config.emu_configs); this } - pub fn find_emu_dev(&self, ipa: usize) -> Option> { + /// According the emu_configs to init every specific device + fn init(this: &mut Self, emu_configs: &Vec) { + /* + for config in emu_configs { + let dev = match EmuDeviceType::from_usize(config.emu_type) { + // todo call specific initialization function of devcise + EmuDeviceType::EmuDeviceTConsole => , + EmuDeviceType::EmuDeviceTGicdV2 => , + EmuDeviceType::EmuDeviceTGPPT => , + EmuDeviceType::EmuDeviceTVirtioBlk => , + EmuDeviceType::EmuDeviceTVirtioNet => , + EmuDeviceType::EmuDeviceTVirtioConsole => , + EmuDeviceType::EmuDeviceTIOMMU => , + EmuDeviceType::EmuDeviceTICCSRE => , + EmuDeviceType::EmuDeviceTSGIR => , + EmuDeviceType::EmuDeviceTGICR => , + EmuDeviceType::EmuDeviceTMeta => , + _ => panic!("emu type: {} is still not supported", config.emu_type), + }; + if let Ok(emu_dev) = dev { + this.emu_devices.push(emu_dev) + } + } + */ + } + + /// Find specific device by ipa + pub fn find_dev(&self, ipa: GuestPhysAddr) -> Option> { self.emu_devices .iter() - .find(|&dev| dev.address_range().contains(&ipa)) + .find(|&dev| dev.address_range().contains(ipa)) .cloned() } - pub fn handle_emu_read(&self, addr: usize, width: usize) -> AxResult { - if let Some(emu_dev) = self.find_emu_dev(addr) { + /// Handle the MMIO read by GuestPhysAddr and data width, return the value of the guest want to read + pub fn handle_mmio_read(&self, addr: GuestPhysAddr, width: usize) -> AxResult { + if let Some(emu_dev) = self.find_dev(addr) { info!( "emu: {:?} handler read ipa {:#x}", emu_dev.address_range(), @@ -49,12 +71,12 @@ impl AxVmDevices { ); return emu_dev.handle_read(addr, width); } - panic!("emu_handle: no emul handler for data abort ipa {:#x}", addr); } - pub fn handle_emu_write(&self, addr: usize, width: usize, val: usize) { - if let Some(emu_dev) = self.find_emu_dev(addr) { + /// Handle the MMIO write by GuestPhysAddr, data width and the value need to write, call specific device to write the value + pub fn handle_mmio_write(&self, addr: GuestPhysAddr, width: usize, val: usize) { + if let Some(emu_dev) = self.find_dev(addr) { info!( "emu: {:?} handler write ipa {:#x}", emu_dev.address_range(), diff --git a/src/lib.rs b/src/lib.rs index 07fdca1..adf233e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,19 @@ #![no_std] +//! This module is designed for an environment where the standard library is not available (`no_std`). +//! +//! The `alloc` crate is used to enable dynamic memory allocation in the absence of the standard library. +//! +//! The `log` crate is included for logging purposes, with macros being imported globally. +//! +//! The module is structured into two main parts: `config` and `device`, which manage the configuration and handling of AxVm devices respectively. + extern crate alloc; #[macro_use] extern crate log; -pub use emu_device::EmulatedDeviceConfig; mod config; -pub use config::AxVmDeviceConfig; - mod device; + +pub use config::AxVmDeviceConfig; pub use device::AxVmDevices;