mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 03:15:20 +00:00
aarch64: Address Rust 1.51.0 clippy issue (upper_case_acroynms)
error: name `GPIOInterruptDisabled` contains a capitalized acronym Error: --> devices/src/legacy/gpio_pl061.rs:46:5 | 46 | GPIOInterruptDisabled, | ^^^^^^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GpioInterruptDisabled` | = note: `-D clippy::upper-case-acronyms` implied by `-D warnings` = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
3c6dfd7709
commit
40da6210f4
@ -16,12 +16,12 @@ use std::{io, result};
|
|||||||
use super::super::DeviceType;
|
use super::super::DeviceType;
|
||||||
use super::super::InitramfsConfig;
|
use super::super::InitramfsConfig;
|
||||||
use super::get_fdt_addr;
|
use super::get_fdt_addr;
|
||||||
use super::gic::GICDevice;
|
use super::gic::GicDevice;
|
||||||
use super::layout::{
|
use super::layout::{
|
||||||
FDT_MAX_SIZE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, PCI_MMCONFIG_SIZE,
|
FDT_MAX_SIZE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, PCI_MMCONFIG_SIZE,
|
||||||
PCI_MMCONFIG_START,
|
PCI_MMCONFIG_START,
|
||||||
};
|
};
|
||||||
use crate::aarch64::fdt::Error::CstringFDTTransform;
|
use crate::aarch64::fdt::Error::CstringFdtTransform;
|
||||||
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
|
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
|
||||||
|
|
||||||
// This is a value for uniquely identifying the FDT node declaring the interrupt controller.
|
// This is a value for uniquely identifying the FDT node declaring the interrupt controller.
|
||||||
@ -68,7 +68,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for devices to be added to the Flattened Device Tree.
|
/// Trait for devices to be added to the Flattened Device Tree.
|
||||||
pub trait DeviceInfoForFDT {
|
pub trait DeviceInfoForFdt {
|
||||||
/// Returns the address where this device will be loaded.
|
/// Returns the address where this device will be loaded.
|
||||||
fn addr(&self) -> u64;
|
fn addr(&self) -> u64;
|
||||||
/// Returns the associated interrupt for this device.
|
/// Returns the associated interrupt for this device.
|
||||||
@ -81,27 +81,27 @@ pub trait DeviceInfoForFDT {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Failed to append node to the FDT.
|
/// Failed to append node to the FDT.
|
||||||
AppendFDTNode(io::Error),
|
AppendFdtNode(io::Error),
|
||||||
/// Failed to append a property to the FDT.
|
/// Failed to append a property to the FDT.
|
||||||
AppendFDTProperty(io::Error),
|
AppendFdtProperty(io::Error),
|
||||||
/// Syscall for creating FDT failed.
|
/// Syscall for creating FDT failed.
|
||||||
CreateFDT(io::Error),
|
CreateFdt(io::Error),
|
||||||
/// Failed to obtain a C style string.
|
/// Failed to obtain a C style string.
|
||||||
CstringFDTTransform(NulError),
|
CstringFdtTransform(NulError),
|
||||||
/// Failure in calling syscall for terminating this FDT.
|
/// Failure in calling syscall for terminating this FDT.
|
||||||
FinishFDTReserveMap(io::Error),
|
FinishFdtReserveMap(io::Error),
|
||||||
/// Failure in writing FDT in memory.
|
/// Failure in writing FDT in memory.
|
||||||
WriteFDTToMemory(GuestMemoryError),
|
WriteFdtToMemory(GuestMemoryError),
|
||||||
}
|
}
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
/// Creates the flattened device tree for this aarch64 VM.
|
/// Creates the flattened device tree for this aarch64 VM.
|
||||||
pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
|
pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHasher>(
|
||||||
guest_mem: &GuestMemoryMmap,
|
guest_mem: &GuestMemoryMmap,
|
||||||
cmdline: &CStr,
|
cmdline: &CStr,
|
||||||
vcpu_mpidr: Vec<u64>,
|
vcpu_mpidr: Vec<u64>,
|
||||||
device_info: &HashMap<(DeviceType, String), T, S>,
|
device_info: &HashMap<(DeviceType, String), T, S>,
|
||||||
gic_device: &dyn GICDevice,
|
gic_device: &dyn GicDevice,
|
||||||
initrd: &Option<InitramfsConfig>,
|
initrd: &Option<InitramfsConfig>,
|
||||||
pci_space_address: &(u64, u64),
|
pci_space_address: &(u64, u64),
|
||||||
) -> Result<Vec<u8>> {
|
) -> Result<Vec<u8>> {
|
||||||
@ -145,7 +145,7 @@ pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHash
|
|||||||
let fdt_address = GuestAddress(get_fdt_addr(&guest_mem));
|
let fdt_address = GuestAddress(get_fdt_addr(&guest_mem));
|
||||||
guest_mem
|
guest_mem
|
||||||
.write_slice(fdt_final.as_slice(), fdt_address)
|
.write_slice(fdt_final.as_slice(), fdt_address)
|
||||||
.map_err(Error::WriteFDTToMemory)?;
|
.map_err(Error::WriteFdtToMemory)?;
|
||||||
Ok(fdt_final)
|
Ok(fdt_final)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ fn allocate_fdt(fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
let mut fdt_ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, FDT_MAX_SIZE as c_int) };
|
let mut fdt_ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, FDT_MAX_SIZE as c_int) };
|
||||||
|
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::CreateFDT(io::Error::last_os_error()));
|
return Err(Error::CreateFdt(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The flattened device trees created with fdt_create() contains a list of
|
// The flattened device trees created with fdt_create() contains a list of
|
||||||
@ -166,7 +166,7 @@ fn allocate_fdt(fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
// Safe since we previously allocated this array.
|
// Safe since we previously allocated this array.
|
||||||
fdt_ret = unsafe { fdt_finish_reservemap(fdt.as_mut_ptr() as *mut c_void) };
|
fdt_ret = unsafe { fdt_finish_reservemap(fdt.as_mut_ptr() as *mut c_void) };
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
|
return Err(Error::FinishFdtReserveMap(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ fn finish_fdt(from_fdt: &mut Vec<u8>, to_fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
// Safe since we allocated `fdt_final` and previously passed in its size.
|
// Safe since we allocated `fdt_final` and previously passed in its size.
|
||||||
let mut fdt_ret = unsafe { fdt_finish(from_fdt.as_mut_ptr() as *mut c_void) };
|
let mut fdt_ret = unsafe { fdt_finish(from_fdt.as_mut_ptr() as *mut c_void) };
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
|
return Err(Error::FinishFdtReserveMap(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe because we allocated both arrays with the correct size.
|
// Safe because we allocated both arrays with the correct size.
|
||||||
@ -187,25 +187,25 @@ fn finish_fdt(from_fdt: &mut Vec<u8>, to_fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
|
return Err(Error::FinishFdtReserveMap(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe since we allocated `to_fdt`.
|
// Safe since we allocated `to_fdt`.
|
||||||
fdt_ret = unsafe { fdt_pack(to_fdt.as_mut_ptr() as *mut c_void) };
|
fdt_ret = unsafe { fdt_pack(to_fdt.as_mut_ptr() as *mut c_void) };
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::FinishFDTReserveMap(io::Error::last_os_error()));
|
return Err(Error::FinishFdtReserveMap(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Following are auxiliary functions for appending nodes to FDT.
|
// Following are auxiliary functions for appending nodes to FDT.
|
||||||
fn append_begin_node(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
fn append_begin_node(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
||||||
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
|
let cstr_name = CString::new(name).map_err(CstringFdtTransform)?;
|
||||||
|
|
||||||
// Safe because we allocated fdt and converted name to a CString
|
// Safe because we allocated fdt and converted name to a CString
|
||||||
let fdt_ret = unsafe { fdt_begin_node(fdt.as_mut_ptr() as *mut c_void, cstr_name.as_ptr()) };
|
let fdt_ret = unsafe { fdt_begin_node(fdt.as_mut_ptr() as *mut c_void, cstr_name.as_ptr()) };
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::AppendFDTNode(io::Error::last_os_error()));
|
return Err(Error::AppendFdtNode(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ fn append_end_node(fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
// Safe because we allocated fdt.
|
// Safe because we allocated fdt.
|
||||||
let fdt_ret = unsafe { fdt_end_node(fdt.as_mut_ptr() as *mut c_void) };
|
let fdt_ret = unsafe { fdt_end_node(fdt.as_mut_ptr() as *mut c_void) };
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::AppendFDTNode(io::Error::last_os_error()));
|
return Err(Error::AppendFdtNode(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -229,13 +229,13 @@ fn append_property_u64(fdt: &mut Vec<u8>, name: &str, val: u64) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn append_property_string(fdt: &mut Vec<u8>, name: &str, value: &str) -> Result<()> {
|
fn append_property_string(fdt: &mut Vec<u8>, name: &str, value: &str) -> Result<()> {
|
||||||
let cstr_value = CString::new(value).map_err(CstringFDTTransform)?;
|
let cstr_value = CString::new(value).map_err(CstringFdtTransform)?;
|
||||||
append_property_cstring(fdt, name, &cstr_value)
|
append_property_cstring(fdt, name, &cstr_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Result<()> {
|
fn append_property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) -> Result<()> {
|
||||||
let value_bytes = cstr_value.to_bytes_with_nul();
|
let value_bytes = cstr_value.to_bytes_with_nul();
|
||||||
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
|
let cstr_name = CString::new(name).map_err(CstringFdtTransform)?;
|
||||||
// Safe because we allocated fdt, converted name and value to CStrings
|
// Safe because we allocated fdt, converted name and value to CStrings
|
||||||
let fdt_ret = unsafe {
|
let fdt_ret = unsafe {
|
||||||
fdt_property(
|
fdt_property(
|
||||||
@ -246,13 +246,13 @@ fn append_property_cstring(fdt: &mut Vec<u8>, name: &str, cstr_value: &CStr) ->
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
|
return Err(Error::AppendFdtProperty(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_property_null(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
fn append_property_null(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
||||||
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
|
let cstr_name = CString::new(name).map_err(CstringFdtTransform)?;
|
||||||
|
|
||||||
// Safe because we allocated fdt, converted name to a CString
|
// Safe because we allocated fdt, converted name to a CString
|
||||||
let fdt_ret = unsafe {
|
let fdt_ret = unsafe {
|
||||||
@ -264,13 +264,13 @@ fn append_property_null(fdt: &mut Vec<u8>, name: &str) -> Result<()> {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
|
return Err(Error::AppendFdtProperty(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_property(fdt: &mut Vec<u8>, name: &str, val: &[u8]) -> Result<()> {
|
fn append_property(fdt: &mut Vec<u8>, name: &str, val: &[u8]) -> Result<()> {
|
||||||
let cstr_name = CString::new(name).map_err(CstringFDTTransform)?;
|
let cstr_name = CString::new(name).map_err(CstringFdtTransform)?;
|
||||||
let val_ptr = val.as_ptr() as *const c_void;
|
let val_ptr = val.as_ptr() as *const c_void;
|
||||||
|
|
||||||
// Safe because we allocated fdt and converted name to a CString
|
// Safe because we allocated fdt and converted name to a CString
|
||||||
@ -283,7 +283,7 @@ fn append_property(fdt: &mut Vec<u8>, name: &str, val: &[u8]) -> Result<()> {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
if fdt_ret != 0 {
|
if fdt_ret != 0 {
|
||||||
return Err(Error::AppendFDTProperty(io::Error::last_os_error()));
|
return Err(Error::AppendFdtProperty(io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -380,7 +380,7 @@ fn create_chosen_node(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_gic_node(fdt: &mut Vec<u8>, gic_device: &dyn GICDevice) -> Result<()> {
|
fn create_gic_node(fdt: &mut Vec<u8>, gic_device: &dyn GicDevice) -> Result<()> {
|
||||||
let gic_reg_prop = generate_prop64(gic_device.device_properties());
|
let gic_reg_prop = generate_prop64(gic_device.device_properties());
|
||||||
|
|
||||||
append_begin_node(fdt, "intc")?;
|
append_begin_node(fdt, "intc")?;
|
||||||
@ -472,7 +472,7 @@ fn create_psci_node(fdt: &mut Vec<u8>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_virtio_node<T: DeviceInfoForFDT + Clone + Debug>(
|
fn create_virtio_node<T: DeviceInfoForFdt + Clone + Debug>(
|
||||||
fdt: &mut Vec<u8>,
|
fdt: &mut Vec<u8>,
|
||||||
dev_info: &T,
|
dev_info: &T,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -489,7 +489,7 @@ fn create_virtio_node<T: DeviceInfoForFDT + Clone + Debug>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_serial_node<T: DeviceInfoForFDT + Clone + Debug>(
|
fn create_serial_node<T: DeviceInfoForFdt + Clone + Debug>(
|
||||||
fdt: &mut Vec<u8>,
|
fdt: &mut Vec<u8>,
|
||||||
dev_info: &T,
|
dev_info: &T,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -508,7 +508,7 @@ fn create_serial_node<T: DeviceInfoForFDT + Clone + Debug>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_rtc_node<T: DeviceInfoForFDT + Clone + Debug>(
|
fn create_rtc_node<T: DeviceInfoForFdt + Clone + Debug>(
|
||||||
fdt: &mut Vec<u8>,
|
fdt: &mut Vec<u8>,
|
||||||
dev_info: &T,
|
dev_info: &T,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -526,7 +526,7 @@ fn create_rtc_node<T: DeviceInfoForFDT + Clone + Debug>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_gpio_node<T: DeviceInfoForFDT + Clone + Debug>(
|
fn create_gpio_node<T: DeviceInfoForFdt + Clone + Debug>(
|
||||||
fdt: &mut Vec<u8>,
|
fdt: &mut Vec<u8>,
|
||||||
dev_info: &T,
|
dev_info: &T,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -561,7 +561,7 @@ fn create_gpio_node<T: DeviceInfoForFDT + Clone + Debug>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_devices_node<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
|
fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHasher>(
|
||||||
fdt: &mut Vec<u8>,
|
fdt: &mut Vec<u8>,
|
||||||
dev_info: &HashMap<(DeviceType, String), T, S>,
|
dev_info: &HashMap<(DeviceType, String), T, S>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -570,8 +570,8 @@ fn create_devices_node<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::Buil
|
|||||||
|
|
||||||
for ((device_type, _device_id), info) in dev_info {
|
for ((device_type, _device_id), info) in dev_info {
|
||||||
match device_type {
|
match device_type {
|
||||||
DeviceType::GPIO => create_gpio_node(fdt, info)?,
|
DeviceType::Gpio => create_gpio_node(fdt, info)?,
|
||||||
DeviceType::RTC => create_rtc_node(fdt, info)?,
|
DeviceType::Rtc => create_rtc_node(fdt, info)?,
|
||||||
DeviceType::Serial => create_serial_node(fdt, info)?,
|
DeviceType::Serial => create_serial_node(fdt, info)?,
|
||||||
DeviceType::Virtio(_) => {
|
DeviceType::Virtio(_) => {
|
||||||
ordered_virtio_device.push(info);
|
ordered_virtio_device.push(info);
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
pub mod kvm {
|
pub mod kvm {
|
||||||
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
|
use crate::aarch64::gic::dist_regs::{get_dist_regs, read_ctlr, set_dist_regs, write_ctlr};
|
||||||
use crate::aarch64::gic::icc_regs::{get_icc_regs, set_icc_regs};
|
use crate::aarch64::gic::icc_regs::{get_icc_regs, set_icc_regs};
|
||||||
use crate::aarch64::gic::kvm::{save_pending_tables, KvmGICDevice};
|
use crate::aarch64::gic::kvm::{save_pending_tables, KvmGicDevice};
|
||||||
use crate::aarch64::gic::redist_regs::{get_redist_regs, set_redist_regs};
|
use crate::aarch64::gic::redist_regs::{get_redist_regs, set_redist_regs};
|
||||||
use crate::aarch64::gic::GICDevice;
|
use crate::aarch64::gic::GicDevice;
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
@ -37,14 +37,14 @@ pub mod kvm {
|
|||||||
/// Error in restoring GIC redistributor registers.
|
/// Error in restoring GIC redistributor registers.
|
||||||
RestoreRedistributorRegisters(crate::aarch64::gic::Error),
|
RestoreRedistributorRegisters(crate::aarch64::gic::Error),
|
||||||
/// Error in saving GIC CPU interface registers.
|
/// Error in saving GIC CPU interface registers.
|
||||||
SaveICCRegisters(crate::aarch64::gic::Error),
|
SaveIccRegisters(crate::aarch64::gic::Error),
|
||||||
/// Error in restoring GIC CPU interface registers.
|
/// Error in restoring GIC CPU interface registers.
|
||||||
RestoreICCRegisters(crate::aarch64::gic::Error),
|
RestoreIccRegisters(crate::aarch64::gic::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
pub struct KvmGICv3 {
|
pub struct KvmGicV3 {
|
||||||
/// The hypervisor agnostic device
|
/// The hypervisor agnostic device
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
|
|
||||||
@ -67,34 +67,34 @@ pub mod kvm {
|
|||||||
gicd_ctlr: u32,
|
gicd_ctlr: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICv3 {
|
impl KvmGicV3 {
|
||||||
// Unfortunately bindgen omits defines that are based on other defines.
|
// Unfortunately bindgen omits defines that are based on other defines.
|
||||||
// See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel.
|
// See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel.
|
||||||
pub const SZ_64K: u64 = 0x0001_0000;
|
pub const SZ_64K: u64 = 0x0001_0000;
|
||||||
const KVM_VGIC_V3_DIST_SIZE: u64 = KvmGICv3::SZ_64K;
|
const KVM_VGIC_V3_DIST_SIZE: u64 = KvmGicV3::SZ_64K;
|
||||||
const KVM_VGIC_V3_REDIST_SIZE: u64 = (2 * KvmGICv3::SZ_64K);
|
const KVM_VGIC_V3_REDIST_SIZE: u64 = (2 * KvmGicV3::SZ_64K);
|
||||||
|
|
||||||
// Device trees specific constants
|
// Device trees specific constants
|
||||||
pub const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
|
pub const ARCH_GIC_V3_MAINT_IRQ: u32 = 9;
|
||||||
|
|
||||||
/// Get the address of the GIC distributor.
|
/// Get the address of the GIC distributor.
|
||||||
pub fn get_dist_addr() -> u64 {
|
pub fn get_dist_addr() -> u64 {
|
||||||
layout::MAPPED_IO_START - KvmGICv3::KVM_VGIC_V3_DIST_SIZE
|
layout::MAPPED_IO_START - KvmGicV3::KVM_VGIC_V3_DIST_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the size of the GIC distributor.
|
/// Get the size of the GIC distributor.
|
||||||
pub fn get_dist_size() -> u64 {
|
pub fn get_dist_size() -> u64 {
|
||||||
KvmGICv3::KVM_VGIC_V3_DIST_SIZE
|
KvmGicV3::KVM_VGIC_V3_DIST_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the address of the GIC redistributors.
|
/// Get the address of the GIC redistributors.
|
||||||
pub fn get_redists_addr(vcpu_count: u64) -> u64 {
|
pub fn get_redists_addr(vcpu_count: u64) -> u64 {
|
||||||
KvmGICv3::get_dist_addr() - KvmGICv3::get_redists_size(vcpu_count)
|
KvmGicV3::get_dist_addr() - KvmGicV3::get_redists_size(vcpu_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the size of the GIC redistributors.
|
/// Get the size of the GIC redistributors.
|
||||||
pub fn get_redists_size(vcpu_count: u64) -> u64 {
|
pub fn get_redists_size(vcpu_count: u64) -> u64 {
|
||||||
vcpu_count * KvmGICv3::KVM_VGIC_V3_REDIST_SIZE
|
vcpu_count * KvmGicV3::KVM_VGIC_V3_REDIST_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save the state of GIC.
|
/// Save the state of GIC.
|
||||||
@ -112,7 +112,7 @@ pub mod kvm {
|
|||||||
.map_err(Error::SaveRedistributorRegisters)?;
|
.map_err(Error::SaveRedistributorRegisters)?;
|
||||||
|
|
||||||
let icc_state =
|
let icc_state =
|
||||||
get_icc_regs(&self.device(), &gicr_typers).map_err(Error::SaveICCRegisters)?;
|
get_icc_regs(&self.device(), &gicr_typers).map_err(Error::SaveIccRegisters)?;
|
||||||
|
|
||||||
Ok(Gicv3State {
|
Ok(Gicv3State {
|
||||||
dist: dist_state,
|
dist: dist_state,
|
||||||
@ -134,13 +134,13 @@ pub mod kvm {
|
|||||||
.map_err(Error::RestoreRedistributorRegisters)?;
|
.map_err(Error::RestoreRedistributorRegisters)?;
|
||||||
|
|
||||||
set_icc_regs(&self.device(), &gicr_typers, &state.icc)
|
set_icc_regs(&self.device(), &gicr_typers, &state.icc)
|
||||||
.map_err(Error::RestoreICCRegisters)?;
|
.map_err(Error::RestoreIccRegisters)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GICDevice for KvmGICv3 {
|
impl GicDevice for KvmGicV3 {
|
||||||
fn device(&self) -> &Arc<dyn hypervisor::Device> {
|
fn device(&self) -> &Arc<dyn hypervisor::Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fdt_maint_irq(&self) -> u32 {
|
fn fdt_maint_irq(&self) -> u32 {
|
||||||
KvmGICv3::ARCH_GIC_V3_MAINT_IRQ
|
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_properties(&self) -> &[u64] {
|
fn device_properties(&self) -> &[u64] {
|
||||||
@ -170,7 +170,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICDevice for KvmGICv3 {
|
impl KvmGicDevice for KvmGicV3 {
|
||||||
fn version() -> u32 {
|
fn version() -> u32 {
|
||||||
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
|
kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3
|
||||||
}
|
}
|
||||||
@ -178,15 +178,15 @@ pub mod kvm {
|
|||||||
fn create_device(
|
fn create_device(
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
vcpu_count: u64,
|
vcpu_count: u64,
|
||||||
) -> Box<dyn GICDevice> {
|
) -> Box<dyn GicDevice> {
|
||||||
Box::new(KvmGICv3 {
|
Box::new(KvmGicV3 {
|
||||||
device,
|
device,
|
||||||
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
||||||
properties: [
|
properties: [
|
||||||
KvmGICv3::get_dist_addr(),
|
KvmGicV3::get_dist_addr(),
|
||||||
KvmGICv3::get_dist_size(),
|
KvmGicV3::get_dist_size(),
|
||||||
KvmGICv3::get_redists_addr(vcpu_count),
|
KvmGicV3::get_redists_addr(vcpu_count),
|
||||||
KvmGICv3::get_redists_size(vcpu_count),
|
KvmGicV3::get_redists_size(vcpu_count),
|
||||||
],
|
],
|
||||||
vcpu_count,
|
vcpu_count,
|
||||||
})
|
})
|
||||||
@ -194,7 +194,7 @@ pub mod kvm {
|
|||||||
|
|
||||||
fn init_device_attributes(
|
fn init_device_attributes(
|
||||||
_vm: &Arc<dyn hypervisor::Vm>,
|
_vm: &Arc<dyn hypervisor::Vm>,
|
||||||
gic_device: &dyn GICDevice,
|
gic_device: &dyn GicDevice,
|
||||||
) -> crate::aarch64::gic::Result<()> {
|
) -> crate::aarch64::gic::Result<()> {
|
||||||
/* Setting up the distributor attribute.
|
/* Setting up the distributor attribute.
|
||||||
We are placing the GIC below 1GB so we need to substract the size of the distributor.
|
We are placing the GIC below 1GB so we need to substract the size of the distributor.
|
||||||
@ -203,7 +203,7 @@ pub mod kvm {
|
|||||||
gic_device.device(),
|
gic_device.device(),
|
||||||
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
|
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST),
|
||||||
&KvmGICv3::get_dist_addr() as *const u64 as u64,
|
&KvmGicV3::get_dist_addr() as *const u64 as u64,
|
||||||
0,
|
0,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ pub mod kvm {
|
|||||||
gic_device.device(),
|
gic_device.device(),
|
||||||
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
|
u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST),
|
||||||
&KvmGICv3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64,
|
&KvmGicV3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64,
|
||||||
0,
|
0,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const GIC_V3_SNAPSHOT_ID: &str = "gic-v3";
|
pub const GIC_V3_SNAPSHOT_ID: &str = "gic-v3";
|
||||||
impl Snapshottable for KvmGICv3 {
|
impl Snapshottable for KvmGicV3 {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
GIC_V3_SNAPSHOT_ID.to_string()
|
GIC_V3_SNAPSHOT_ID.to_string()
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pausable for KvmGICv3 {}
|
impl Pausable for KvmGicV3 {}
|
||||||
impl Transportable for KvmGICv3 {}
|
impl Transportable for KvmGicV3 {}
|
||||||
impl Migratable for KvmGICv3 {}
|
impl Migratable for KvmGicV3 {}
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@ pub mod kvm {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{boxed::Box, result};
|
use std::{boxed::Box, result};
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
use crate::aarch64::gic::gicv3::kvm::KvmGICv3;
|
use crate::aarch64::gic::gicv3::kvm::KvmGicV3;
|
||||||
use crate::aarch64::gic::kvm::KvmGICDevice;
|
use crate::aarch64::gic::kvm::KvmGicDevice;
|
||||||
use crate::aarch64::gic::{Error, GICDevice};
|
use crate::aarch64::gic::{Error, GicDevice};
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
|
|
||||||
pub struct KvmGICv3ITS {
|
pub struct KvmGicV3Its {
|
||||||
/// The hypervisor agnostic device
|
/// The hypervisor agnostic device
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
|
|
||||||
@ -29,19 +29,19 @@ pub mod kvm {
|
|||||||
vcpu_count: u64,
|
vcpu_count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICv3ITS {
|
impl KvmGicV3Its {
|
||||||
const KVM_VGIC_V3_ITS_SIZE: u64 = (2 * KvmGICv3::SZ_64K);
|
const KVM_VGIC_V3_ITS_SIZE: u64 = (2 * KvmGicV3::SZ_64K);
|
||||||
|
|
||||||
fn get_msi_size() -> u64 {
|
fn get_msi_size() -> u64 {
|
||||||
KvmGICv3ITS::KVM_VGIC_V3_ITS_SIZE
|
KvmGicV3Its::KVM_VGIC_V3_ITS_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_msi_addr(vcpu_count: u64) -> u64 {
|
fn get_msi_addr(vcpu_count: u64) -> u64 {
|
||||||
KvmGICv3::get_redists_addr(vcpu_count) - KvmGICv3ITS::get_msi_size()
|
KvmGicV3::get_redists_addr(vcpu_count) - KvmGicV3Its::get_msi_size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GICDevice for KvmGICv3ITS {
|
impl GicDevice for KvmGicV3Its {
|
||||||
fn device(&self) -> &Arc<dyn hypervisor::Device> {
|
fn device(&self) -> &Arc<dyn hypervisor::Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fdt_maint_irq(&self) -> u32 {
|
fn fdt_maint_irq(&self) -> u32 {
|
||||||
KvmGICv3::ARCH_GIC_V3_MAINT_IRQ
|
KvmGicV3::ARCH_GIC_V3_MAINT_IRQ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msi_properties(&self) -> &[u64] {
|
fn msi_properties(&self) -> &[u64] {
|
||||||
@ -83,27 +83,27 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmGICDevice for KvmGICv3ITS {
|
impl KvmGicDevice for KvmGicV3Its {
|
||||||
fn version() -> u32 {
|
fn version() -> u32 {
|
||||||
KvmGICv3::version()
|
KvmGicV3::version()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_device(
|
fn create_device(
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
vcpu_count: u64,
|
vcpu_count: u64,
|
||||||
) -> Box<dyn GICDevice> {
|
) -> Box<dyn GicDevice> {
|
||||||
Box::new(KvmGICv3ITS {
|
Box::new(KvmGicV3Its {
|
||||||
device,
|
device,
|
||||||
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
gicr_typers: vec![0; vcpu_count.try_into().unwrap()],
|
||||||
gic_properties: [
|
gic_properties: [
|
||||||
KvmGICv3::get_dist_addr(),
|
KvmGicV3::get_dist_addr(),
|
||||||
KvmGICv3::get_dist_size(),
|
KvmGicV3::get_dist_size(),
|
||||||
KvmGICv3::get_redists_addr(vcpu_count),
|
KvmGicV3::get_redists_addr(vcpu_count),
|
||||||
KvmGICv3::get_redists_size(vcpu_count),
|
KvmGicV3::get_redists_size(vcpu_count),
|
||||||
],
|
],
|
||||||
msi_properties: [
|
msi_properties: [
|
||||||
KvmGICv3ITS::get_msi_addr(vcpu_count),
|
KvmGicV3Its::get_msi_addr(vcpu_count),
|
||||||
KvmGICv3ITS::get_msi_size(),
|
KvmGicV3Its::get_msi_size(),
|
||||||
],
|
],
|
||||||
vcpu_count,
|
vcpu_count,
|
||||||
})
|
})
|
||||||
@ -111,9 +111,9 @@ pub mod kvm {
|
|||||||
|
|
||||||
fn init_device_attributes(
|
fn init_device_attributes(
|
||||||
vm: &Arc<dyn hypervisor::Vm>,
|
vm: &Arc<dyn hypervisor::Vm>,
|
||||||
gic_device: &dyn GICDevice,
|
gic_device: &dyn GicDevice,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
KvmGICv3::init_device_attributes(vm, gic_device)?;
|
KvmGicV3::init_device_attributes(vm, gic_device)?;
|
||||||
|
|
||||||
let mut its_device = kvm_bindings::kvm_create_device {
|
let mut its_device = kvm_bindings::kvm_create_device {
|
||||||
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
|
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
|
||||||
@ -123,13 +123,13 @@ pub mod kvm {
|
|||||||
|
|
||||||
let its_fd = vm
|
let its_fd = vm
|
||||||
.create_device(&mut its_device)
|
.create_device(&mut its_device)
|
||||||
.map_err(Error::CreateGIC)?;
|
.map_err(Error::CreateGic)?;
|
||||||
|
|
||||||
Self::set_device_attribute(
|
Self::set_device_attribute(
|
||||||
&its_fd,
|
&its_fd,
|
||||||
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
|
u64::from(kvm_bindings::KVM_VGIC_ITS_ADDR_TYPE),
|
||||||
&KvmGICv3ITS::get_msi_addr(gic_device.vcpu_count()) as *const u64 as u64,
|
&KvmGicV3Its::get_msi_addr(gic_device.vcpu_count()) as *const u64 as u64,
|
||||||
0,
|
0,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use std::sync::Arc;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Error while calling KVM ioctl for setting up the global interrupt controller.
|
/// Error while calling KVM ioctl for setting up the global interrupt controller.
|
||||||
CreateGIC(hypervisor::HypervisorVmError),
|
CreateGic(hypervisor::HypervisorVmError),
|
||||||
/// Error while setting device attributes for the GIC.
|
/// Error while setting device attributes for the GIC.
|
||||||
SetDeviceAttribute(hypervisor::HypervisorDeviceError),
|
SetDeviceAttribute(hypervisor::HypervisorDeviceError),
|
||||||
/// Error while getting device attributes for the GIC.
|
/// Error while getting device attributes for the GIC.
|
||||||
@ -26,7 +26,7 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
pub trait GICDevice: Send {
|
pub trait GicDevice: Send {
|
||||||
/// Returns the hypervisor agnostic Device of the GIC device
|
/// Returns the hypervisor agnostic Device of the GIC device
|
||||||
fn device(&self) -> &Arc<dyn hypervisor::Device>;
|
fn device(&self) -> &Arc<dyn hypervisor::Device>;
|
||||||
|
|
||||||
@ -65,16 +65,16 @@ pub trait GICDevice: Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod kvm {
|
pub mod kvm {
|
||||||
use super::GICDevice;
|
use super::GicDevice;
|
||||||
use super::Result;
|
use super::Result;
|
||||||
use crate::aarch64::gic::gicv3_its::kvm::KvmGICv3ITS;
|
use crate::aarch64::gic::gicv3_its::kvm::KvmGicV3Its;
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Trait for GIC devices.
|
/// Trait for GIC devices.
|
||||||
pub trait KvmGICDevice: Send + Sync + GICDevice {
|
pub trait KvmGicDevice: Send + Sync + GicDevice {
|
||||||
/// Returns the GIC version of the device
|
/// Returns the GIC version of the device
|
||||||
fn version() -> u32;
|
fn version() -> u32;
|
||||||
|
|
||||||
@ -82,12 +82,12 @@ pub mod kvm {
|
|||||||
fn create_device(
|
fn create_device(
|
||||||
device: Arc<dyn hypervisor::Device>,
|
device: Arc<dyn hypervisor::Device>,
|
||||||
vcpu_count: u64,
|
vcpu_count: u64,
|
||||||
) -> Box<dyn GICDevice>;
|
) -> Box<dyn GicDevice>;
|
||||||
|
|
||||||
/// Setup the device-specific attributes
|
/// Setup the device-specific attributes
|
||||||
fn init_device_attributes(
|
fn init_device_attributes(
|
||||||
vm: &Arc<dyn hypervisor::Vm>,
|
vm: &Arc<dyn hypervisor::Vm>,
|
||||||
gic_device: &dyn GICDevice,
|
gic_device: &dyn GicDevice,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
/// Initialize a GIC device
|
/// Initialize a GIC device
|
||||||
@ -99,7 +99,7 @@ pub mod kvm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.create_device(&mut gic_device)
|
vm.create_device(&mut gic_device)
|
||||||
.map_err(super::Error::CreateGIC)
|
.map_err(super::Error::CreateGic)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a GIC device attribute
|
/// Set a GIC device attribute
|
||||||
@ -145,7 +145,7 @@ pub mod kvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Finalize the setup of a GIC device
|
/// Finalize the setup of a GIC device
|
||||||
fn finalize_device(gic_device: &dyn GICDevice) -> Result<()> {
|
fn finalize_device(gic_device: &dyn GicDevice) -> Result<()> {
|
||||||
/* We need to tell the kernel how many irqs to support with this vgic.
|
/* We need to tell the kernel how many irqs to support with this vgic.
|
||||||
* See the `layout` module for details.
|
* See the `layout` module for details.
|
||||||
*/
|
*/
|
||||||
@ -175,7 +175,7 @@ pub mod kvm {
|
|||||||
|
|
||||||
/// Method to initialize the GIC device
|
/// Method to initialize the GIC device
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GICDevice>> {
|
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> {
|
||||||
let vgic_fd = Self::init_device(vm)?;
|
let vgic_fd = Self::init_device(vm)?;
|
||||||
|
|
||||||
let device = Self::create_device(vgic_fd, vcpu_count);
|
let device = Self::create_device(vgic_fd, vcpu_count);
|
||||||
@ -190,9 +190,9 @@ pub mod kvm {
|
|||||||
|
|
||||||
/// Create a GICv3-ITS device.
|
/// Create a GICv3-ITS device.
|
||||||
///
|
///
|
||||||
pub fn create_gic(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GICDevice>> {
|
pub fn create_gic(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GicDevice>> {
|
||||||
debug!("creating a GICv3-ITS");
|
debug!("creating a GICv3-ITS");
|
||||||
KvmGICv3ITS::new(vm, vcpu_count)
|
KvmGicV3Its::new(vm, vcpu_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function that saves RDIST pending tables into guest RAM.
|
/// Function that saves RDIST pending tables into guest RAM.
|
||||||
|
@ -11,10 +11,10 @@ pub mod layout;
|
|||||||
/// Logic for configuring aarch64 registers.
|
/// Logic for configuring aarch64 registers.
|
||||||
pub mod regs;
|
pub mod regs;
|
||||||
|
|
||||||
pub use self::fdt::DeviceInfoForFDT;
|
pub use self::fdt::DeviceInfoForFdt;
|
||||||
use crate::DeviceType;
|
use crate::DeviceType;
|
||||||
use crate::RegionType;
|
use crate::RegionType;
|
||||||
use aarch64::gic::GICDevice;
|
use aarch64::gic::GicDevice;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@ -28,10 +28,10 @@ use vm_memory::{
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Failed to create a FDT.
|
/// Failed to create a FDT.
|
||||||
SetupFDT(fdt::Error),
|
SetupFdt(fdt::Error),
|
||||||
|
|
||||||
/// Failed to create a GIC.
|
/// Failed to create a GIC.
|
||||||
SetupGIC(gic::Error),
|
SetupGic(gic::Error),
|
||||||
|
|
||||||
/// Failed to compute the initramfs address.
|
/// Failed to compute the initramfs address.
|
||||||
InitramfsAddress,
|
InitramfsAddress,
|
||||||
@ -40,7 +40,7 @@ pub enum Error {
|
|||||||
RegsConfiguration(regs::Error),
|
RegsConfiguration(regs::Error),
|
||||||
|
|
||||||
/// Error configuring the MPIDR register
|
/// Error configuring the MPIDR register
|
||||||
VcpuRegMPIDR(hypervisor::HypervisorCpuError),
|
VcpuRegMpidr(hypervisor::HypervisorCpuError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for super::Error {
|
impl From<Error> for super::Error {
|
||||||
@ -74,7 +74,7 @@ pub fn configure_vcpu(
|
|||||||
.map_err(Error::RegsConfiguration)?;
|
.map_err(Error::RegsConfiguration)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mpidr = fd.read_mpidr().map_err(Error::VcpuRegMPIDR)?;
|
let mpidr = fd.read_mpidr().map_err(Error::VcpuRegMpidr)?;
|
||||||
Ok(mpidr)
|
Ok(mpidr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
|
|||||||
/// * `guest_mem` - The memory to be used by the guest.
|
/// * `guest_mem` - The memory to be used by the guest.
|
||||||
/// * `num_cpus` - Number of virtual CPUs the guest will have.
|
/// * `num_cpus` - Number of virtual CPUs the guest will have.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::BuildHasher>(
|
pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHasher>(
|
||||||
vm: &Arc<dyn hypervisor::Vm>,
|
vm: &Arc<dyn hypervisor::Vm>,
|
||||||
guest_mem: &GuestMemoryMmap,
|
guest_mem: &GuestMemoryMmap,
|
||||||
cmdline_cstring: &CStr,
|
cmdline_cstring: &CStr,
|
||||||
@ -126,8 +126,8 @@ pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::Bui
|
|||||||
device_info: &HashMap<(DeviceType, String), T, S>,
|
device_info: &HashMap<(DeviceType, String), T, S>,
|
||||||
initrd: &Option<super::InitramfsConfig>,
|
initrd: &Option<super::InitramfsConfig>,
|
||||||
pci_space_address: &(u64, u64),
|
pci_space_address: &(u64, u64),
|
||||||
) -> super::Result<Box<dyn GICDevice>> {
|
) -> super::Result<Box<dyn GicDevice>> {
|
||||||
let gic_device = gic::kvm::create_gic(vm, vcpu_count).map_err(Error::SetupGIC)?;
|
let gic_device = gic::kvm::create_gic(vm, vcpu_count).map_err(Error::SetupGic)?;
|
||||||
|
|
||||||
fdt::create_fdt(
|
fdt::create_fdt(
|
||||||
guest_mem,
|
guest_mem,
|
||||||
@ -138,7 +138,7 @@ pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::Bui
|
|||||||
initrd,
|
initrd,
|
||||||
pci_space_address,
|
pci_space_address,
|
||||||
)
|
)
|
||||||
.map_err(Error::SetupFDT)?;
|
.map_err(Error::SetupFdt)?;
|
||||||
|
|
||||||
Ok(gic_device)
|
Ok(gic_device)
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ pub mod aarch64;
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use aarch64::{
|
pub use aarch64::{
|
||||||
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT,
|
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt,
|
||||||
get_host_cpu_phys_bits, get_kernel_start, initramfs_load_addr, layout,
|
get_host_cpu_phys_bits, get_kernel_start, initramfs_load_addr, layout,
|
||||||
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint,
|
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint,
|
||||||
};
|
};
|
||||||
@ -128,10 +128,10 @@ pub enum DeviceType {
|
|||||||
Serial,
|
Serial,
|
||||||
/// Device Type: RTC.
|
/// Device Type: RTC.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
RTC,
|
Rtc,
|
||||||
/// Device Type: GPIO.
|
/// Device Type: GPIO.
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
GPIO,
|
Gpio,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default (smallest) memory page size for the supported architectures.
|
/// Default (smallest) memory page size for the supported architectures.
|
||||||
@ -146,13 +146,13 @@ impl fmt::Display for DeviceType {
|
|||||||
/// Structure to describe MMIO device information
|
/// Structure to describe MMIO device information
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub struct MMIODeviceInfo {
|
pub struct MmioDeviceInfo {
|
||||||
pub addr: u64,
|
pub addr: u64,
|
||||||
pub irq: u32,
|
pub irq: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
impl DeviceInfoForFDT for MMIODeviceInfo {
|
impl DeviceInfoForFdt for MmioDeviceInfo {
|
||||||
fn addr(&self) -> u64 {
|
fn addr(&self) -> u64 {
|
||||||
self.addr
|
self.addr
|
||||||
}
|
}
|
||||||
|
@ -43,20 +43,20 @@ const N_GPIOS: u32 = 8;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BadWriteOffset(u64),
|
BadWriteOffset(u64),
|
||||||
GPIOInterruptDisabled,
|
GpioInterruptDisabled,
|
||||||
GPIOInterruptFailure(io::Error),
|
GpioInterruptFailure(io::Error),
|
||||||
GPIOTriggerKeyFailure(u32),
|
GpioTriggerKeyFailure(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
|
Error::BadWriteOffset(offset) => write!(f, "Bad Write Offset: {}", offset),
|
||||||
Error::GPIOInterruptDisabled => write!(f, "GPIO interrupt disabled by guest driver.",),
|
Error::GpioInterruptDisabled => write!(f, "GPIO interrupt disabled by guest driver.",),
|
||||||
Error::GPIOInterruptFailure(ref e) => {
|
Error::GpioInterruptFailure(ref e) => {
|
||||||
write!(f, "Could not trigger GPIO interrupt: {}.", e)
|
write!(f, "Could not trigger GPIO interrupt: {}.", e)
|
||||||
}
|
}
|
||||||
Error::GPIOTriggerKeyFailure(key) => {
|
Error::GpioTriggerKeyFailure(key) => {
|
||||||
write!(f, "Invalid GPIO Input key triggerd: {}.", key)
|
write!(f, "Invalid GPIO Input key triggerd: {}.", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ impl fmt::Display for Error {
|
|||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
/// A GPIO device following the PL061 specification.
|
/// A GPIO device following the PL061 specification.
|
||||||
pub struct GPIO {
|
pub struct Gpio {
|
||||||
id: String,
|
id: String,
|
||||||
// Data Register
|
// Data Register
|
||||||
data: u32,
|
data: u32,
|
||||||
@ -90,7 +90,7 @@ pub struct GPIO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct GPIOState {
|
pub struct GpioState {
|
||||||
data: u32,
|
data: u32,
|
||||||
old_in_data: u32,
|
old_in_data: u32,
|
||||||
dir: u32,
|
dir: u32,
|
||||||
@ -102,10 +102,10 @@ pub struct GPIOState {
|
|||||||
afsel: u32,
|
afsel: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPIO {
|
impl Gpio {
|
||||||
/// Constructs an PL061 GPIO device.
|
/// Constructs an PL061 GPIO device.
|
||||||
pub fn new(id: String, interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> GPIO {
|
pub fn new(id: String, interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> Self {
|
||||||
GPIO {
|
Self {
|
||||||
id,
|
id,
|
||||||
data: 0,
|
data: 0,
|
||||||
old_in_data: 0,
|
old_in_data: 0,
|
||||||
@ -120,8 +120,8 @@ impl GPIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> GPIOState {
|
fn state(&self) -> GpioState {
|
||||||
GPIOState {
|
GpioState {
|
||||||
data: self.data,
|
data: self.data,
|
||||||
old_in_data: self.old_in_data,
|
old_in_data: self.old_in_data,
|
||||||
dir: self.dir,
|
dir: self.dir,
|
||||||
@ -134,7 +134,7 @@ impl GPIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_state(&mut self, state: &GPIOState) {
|
fn set_state(&mut self, state: &GpioState) {
|
||||||
self.data = state.data;
|
self.data = state.data;
|
||||||
self.old_in_data = state.old_in_data;
|
self.old_in_data = state.old_in_data;
|
||||||
self.dir = state.dir;
|
self.dir = state.dir;
|
||||||
@ -233,12 +233,12 @@ impl GPIO {
|
|||||||
self.pl061_internal_update();
|
self.pl061_internal_update();
|
||||||
|
|
||||||
match self.trigger_gpio_interrupt() {
|
match self.trigger_gpio_interrupt() {
|
||||||
Ok(_) | Err(Error::GPIOInterruptDisabled) => return Ok(()),
|
Ok(_) | Err(Error::GpioInterruptDisabled) => return Ok(()),
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::GPIOTriggerKeyFailure(key))
|
Err(Error::GpioTriggerKeyFailure(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger_gpio_interrupt(&self) -> Result<()> {
|
fn trigger_gpio_interrupt(&self) -> Result<()> {
|
||||||
@ -246,16 +246,16 @@ impl GPIO {
|
|||||||
// trigger their individual interrupts and then the combined GPIOINTR line.
|
// trigger their individual interrupts and then the combined GPIOINTR line.
|
||||||
if (self.istate & self.im) == 0 {
|
if (self.istate & self.im) == 0 {
|
||||||
warn!("Failed to trigger GPIO input interrupt (disabled by guest OS)");
|
warn!("Failed to trigger GPIO input interrupt (disabled by guest OS)");
|
||||||
return Err(Error::GPIOInterruptDisabled);
|
return Err(Error::GpioInterruptDisabled);
|
||||||
}
|
}
|
||||||
self.interrupt
|
self.interrupt
|
||||||
.trigger(0)
|
.trigger(0)
|
||||||
.map_err(Error::GPIOInterruptFailure)?;
|
.map_err(Error::GpioInterruptFailure)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BusDevice for GPIO {
|
impl BusDevice for Gpio {
|
||||||
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
||||||
let value;
|
let value;
|
||||||
let mut read_ok = true;
|
let mut read_ok = true;
|
||||||
@ -311,7 +311,7 @@ impl BusDevice for GPIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Snapshottable for GPIO {
|
impl Snapshottable for Gpio {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
self.id.clone()
|
self.id.clone()
|
||||||
}
|
}
|
||||||
@ -352,9 +352,9 @@ impl Snapshottable for GPIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pausable for GPIO {}
|
impl Pausable for Gpio {}
|
||||||
impl Transportable for GPIO {}
|
impl Transportable for Gpio {}
|
||||||
impl Migratable for GPIO {}
|
impl Migratable for Gpio {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -398,7 +398,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_read_write_and_event() {
|
fn test_gpio_read_write_and_event() {
|
||||||
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
|
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
|
||||||
let mut gpio = GPIO::new(
|
let mut gpio = Gpio::new(
|
||||||
String::from(GPIO_NAME),
|
String::from(GPIO_NAME),
|
||||||
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
||||||
);
|
);
|
||||||
|
@ -26,10 +26,10 @@ pub use self::i8042::I8042Device;
|
|||||||
pub use self::serial::Serial;
|
pub use self::serial::Serial;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use self::gpio_pl061::Error as GPIODeviceError;
|
pub use self::gpio_pl061::Error as GpioDeviceError;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use self::gpio_pl061::GPIO;
|
pub use self::gpio_pl061::Gpio;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use self::rtc_pl031::RTC;
|
pub use self::rtc_pl031::Rtc;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use self::uart_pl011::PL011;
|
pub use self::uart_pl011::Pl011;
|
||||||
|
@ -215,7 +215,7 @@ pub fn seconds_to_nanoseconds(value: i64) -> Option<i64> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A RTC device following the PL031 specification..
|
/// A RTC device following the PL031 specification..
|
||||||
pub struct RTC {
|
pub struct Rtc {
|
||||||
previous_now: Instant,
|
previous_now: Instant,
|
||||||
tick_offset: i64,
|
tick_offset: i64,
|
||||||
// This is used for implementing the RTC alarm. However, in Firecracker we do not need it.
|
// This is used for implementing the RTC alarm. However, in Firecracker we do not need it.
|
||||||
@ -227,10 +227,10 @@ pub struct RTC {
|
|||||||
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RTC {
|
impl Rtc {
|
||||||
/// Constructs an AMBA PL031 RTC device.
|
/// Constructs an AMBA PL031 RTC device.
|
||||||
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> RTC {
|
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>) -> Self {
|
||||||
RTC {
|
Self {
|
||||||
// This is used only for duration measuring purposes.
|
// This is used only for duration measuring purposes.
|
||||||
previous_now: Instant::now(),
|
previous_now: Instant::now(),
|
||||||
tick_offset: get_time(ClockType::Real) as i64,
|
tick_offset: get_time(ClockType::Real) as i64,
|
||||||
@ -289,7 +289,7 @@ impl RTC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BusDevice for RTC {
|
impl BusDevice for Rtc {
|
||||||
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
||||||
let v;
|
let v;
|
||||||
let mut read_ok = true;
|
let mut read_ok = true;
|
||||||
@ -450,7 +450,7 @@ mod tests {
|
|||||||
fn test_rtc_read_write_and_event() {
|
fn test_rtc_read_write_and_event() {
|
||||||
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
|
let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
|
||||||
|
|
||||||
let mut rtc = RTC::new(Arc::new(Box::new(TestInterrupt::new(
|
let mut rtc = Rtc::new(Arc::new(Box::new(TestInterrupt::new(
|
||||||
intr_evt.try_clone().unwrap(),
|
intr_evt.try_clone().unwrap(),
|
||||||
))));
|
))));
|
||||||
let mut data = [0; 4];
|
let mut data = [0; 4];
|
||||||
|
@ -49,7 +49,7 @@ const AMBA_ID_HIGH: u64 = 0x401;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BadWriteOffset(u64),
|
BadWriteOffset(u64),
|
||||||
DMANotImplemented,
|
DmaNotImplemented,
|
||||||
InterruptFailure(io::Error),
|
InterruptFailure(io::Error),
|
||||||
WriteAllFailure(io::Error),
|
WriteAllFailure(io::Error),
|
||||||
FlushFailure(io::Error),
|
FlushFailure(io::Error),
|
||||||
@ -59,7 +59,7 @@ impl fmt::Display for Error {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {}", offset),
|
Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {}", offset),
|
||||||
Error::DMANotImplemented => write!(f, "pl011: DMA not implemented."),
|
Error::DmaNotImplemented => write!(f, "pl011: DMA not implemented."),
|
||||||
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
|
Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {}", e),
|
||||||
Error::WriteAllFailure(e) => write!(f, "Failed to write: {}", e),
|
Error::WriteAllFailure(e) => write!(f, "Failed to write: {}", e),
|
||||||
Error::FlushFailure(e) => write!(f, "Failed to flush: {}", e),
|
Error::FlushFailure(e) => write!(f, "Failed to flush: {}", e),
|
||||||
@ -70,7 +70,7 @@ impl fmt::Display for Error {
|
|||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
/// A PL011 device following the PL011 specification.
|
/// A PL011 device following the PL011 specification.
|
||||||
pub struct PL011 {
|
pub struct Pl011 {
|
||||||
id: String,
|
id: String,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
lcr: u32,
|
lcr: u32,
|
||||||
@ -91,7 +91,7 @@ pub struct PL011 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct PL011State {
|
pub struct Pl011State {
|
||||||
flags: u32,
|
flags: u32,
|
||||||
lcr: u32,
|
lcr: u32,
|
||||||
rsr: u32,
|
rsr: u32,
|
||||||
@ -108,14 +108,14 @@ pub struct PL011State {
|
|||||||
read_trigger: u32,
|
read_trigger: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PL011 {
|
impl Pl011 {
|
||||||
/// Constructs an AMBA PL011 UART device.
|
/// Constructs an AMBA PL011 UART device.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: String,
|
id: String,
|
||||||
irq: Arc<Box<dyn InterruptSourceGroup>>,
|
irq: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
out: Option<Box<dyn io::Write + Send>>,
|
out: Option<Box<dyn io::Write + Send>>,
|
||||||
) -> PL011 {
|
) -> Self {
|
||||||
PL011 {
|
Self {
|
||||||
id,
|
id,
|
||||||
flags: 0x90u32,
|
flags: 0x90u32,
|
||||||
lcr: 0u32,
|
lcr: 0u32,
|
||||||
@ -136,8 +136,8 @@ impl PL011 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> PL011State {
|
fn state(&self) -> Pl011State {
|
||||||
PL011State {
|
Pl011State {
|
||||||
flags: self.flags,
|
flags: self.flags,
|
||||||
lcr: self.lcr,
|
lcr: self.lcr,
|
||||||
rsr: self.rsr,
|
rsr: self.rsr,
|
||||||
@ -155,7 +155,7 @@ impl PL011 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_state(&mut self, state: &PL011State) {
|
fn set_state(&mut self, state: &Pl011State) {
|
||||||
self.flags = state.flags;
|
self.flags = state.flags;
|
||||||
self.lcr = state.lcr;
|
self.lcr = state.lcr;
|
||||||
self.rsr = state.rsr;
|
self.rsr = state.rsr;
|
||||||
@ -264,7 +264,7 @@ impl PL011 {
|
|||||||
UARTDMACR => {
|
UARTDMACR => {
|
||||||
self.dmacr = val;
|
self.dmacr = val;
|
||||||
if (val & 3) != 0 {
|
if (val & 3) != 0 {
|
||||||
return Err(Error::DMANotImplemented);
|
return Err(Error::DmaNotImplemented);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
off => {
|
off => {
|
||||||
@ -279,7 +279,7 @@ impl PL011 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BusDevice for PL011 {
|
impl BusDevice for Pl011 {
|
||||||
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
||||||
let v;
|
let v;
|
||||||
let mut read_ok = true;
|
let mut read_ok = true;
|
||||||
@ -355,7 +355,7 @@ impl BusDevice for PL011 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Snapshottable for PL011 {
|
impl Snapshottable for Pl011 {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
self.id.clone()
|
self.id.clone()
|
||||||
}
|
}
|
||||||
@ -396,9 +396,9 @@ impl Snapshottable for PL011 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pausable for PL011 {}
|
impl Pausable for Pl011 {}
|
||||||
impl Transportable for PL011 {}
|
impl Transportable for Pl011 {}
|
||||||
impl Migratable for PL011 {}
|
impl Migratable for Pl011 {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -462,7 +462,7 @@ mod tests {
|
|||||||
fn pl011_output() {
|
fn pl011_output() {
|
||||||
let intr_evt = EventFd::new(0).unwrap();
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
let pl011_out = SharedBuffer::new();
|
let pl011_out = SharedBuffer::new();
|
||||||
let mut pl011 = PL011::new(
|
let mut pl011 = Pl011::new(
|
||||||
String::from(SERIAL_NAME),
|
String::from(SERIAL_NAME),
|
||||||
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
||||||
Some(Box::new(pl011_out.clone())),
|
Some(Box::new(pl011_out.clone())),
|
||||||
@ -482,7 +482,7 @@ mod tests {
|
|||||||
fn pl011_input() {
|
fn pl011_input() {
|
||||||
let intr_evt = EventFd::new(0).unwrap();
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
let pl011_out = SharedBuffer::new();
|
let pl011_out = SharedBuffer::new();
|
||||||
let mut pl011 = PL011::new(
|
let mut pl011 = Pl011::new(
|
||||||
String::from(SERIAL_NAME),
|
String::from(SERIAL_NAME),
|
||||||
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
Arc::new(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap()))),
|
||||||
Some(Box::new(pl011_out)),
|
Some(Box::new(pl011_out)),
|
||||||
|
@ -29,9 +29,9 @@ use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID};
|
|||||||
use acpi_tables::{aml, aml::Aml};
|
use acpi_tables::{aml, aml::Aml};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use arch::aarch64::gic::GICDevice;
|
use arch::aarch64::gic::GicDevice;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use arch::aarch64::DeviceInfoForFDT;
|
use arch::aarch64::DeviceInfoForFdt;
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
use arch::layout;
|
use arch::layout;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -47,10 +47,10 @@ use block_util::{
|
|||||||
use devices::gic;
|
use devices::gic;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::ioapic;
|
use devices::ioapic;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
use devices::legacy::Pl011;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::legacy::Serial;
|
use devices::legacy::Serial;
|
||||||
#[cfg(target_arch = "aarch64")]
|
|
||||||
use devices::legacy::PL011;
|
|
||||||
use devices::{
|
use devices::{
|
||||||
interrupt_controller, interrupt_controller::InterruptController, AcpiNotificationFlags,
|
interrupt_controller, interrupt_controller::InterruptController, AcpiNotificationFlags,
|
||||||
};
|
};
|
||||||
@ -405,7 +405,7 @@ pub enum DeviceManagerError {
|
|||||||
|
|
||||||
/// Failed to do AArch64 GPIO power button notification
|
/// Failed to do AArch64 GPIO power button notification
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
AArch64PowerButtonNotification(devices::legacy::GPIODeviceError),
|
AArch64PowerButtonNotification(devices::legacy::GpioDeviceError),
|
||||||
|
|
||||||
/// Failed to set O_DIRECT flag to file descriptor
|
/// Failed to set O_DIRECT flag to file descriptor
|
||||||
SetDirectIo,
|
SetDirectIo,
|
||||||
@ -507,7 +507,7 @@ pub struct Console {
|
|||||||
// Serial port on 0x3f8
|
// Serial port on 0x3f8
|
||||||
serial: Option<Arc<Mutex<Serial>>>,
|
serial: Option<Arc<Mutex<Serial>>>,
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
serial: Option<Arc<Mutex<PL011>>>,
|
serial: Option<Arc<Mutex<Pl011>>>,
|
||||||
virtio_console_input: Option<Arc<virtio_devices::ConsoleInput>>,
|
virtio_console_input: Option<Arc<virtio_devices::ConsoleInput>>,
|
||||||
input: Option<ConsoleInput>,
|
input: Option<ConsoleInput>,
|
||||||
}
|
}
|
||||||
@ -789,14 +789,14 @@ struct DeviceManagerState {
|
|||||||
/// Private structure for storing information about the MMIO device registered at some address on the bus.
|
/// Private structure for storing information about the MMIO device registered at some address on the bus.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub struct MMIODeviceInfo {
|
pub struct MmioDeviceInfo {
|
||||||
addr: u64,
|
addr: u64,
|
||||||
irq: u32,
|
irq: u32,
|
||||||
len: u64,
|
len: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
impl DeviceInfoForFDT for MMIODeviceInfo {
|
impl DeviceInfoForFdt for MmioDeviceInfo {
|
||||||
fn addr(&self) -> u64 {
|
fn addr(&self) -> u64 {
|
||||||
self.addr
|
self.addr
|
||||||
}
|
}
|
||||||
@ -852,7 +852,7 @@ pub struct DeviceManager {
|
|||||||
interrupt_controller: Option<Arc<Mutex<gic::Gic>>>,
|
interrupt_controller: Option<Arc<Mutex<gic::Gic>>>,
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
gic_device_entity: Option<Arc<Mutex<Box<dyn GICDevice>>>>,
|
gic_device_entity: Option<Arc<Mutex<Box<dyn GicDevice>>>>,
|
||||||
|
|
||||||
// Things to be added to the commandline (i.e. for virtio-mmio)
|
// Things to be added to the commandline (i.e. for virtio-mmio)
|
||||||
cmdline_additions: Vec<String>,
|
cmdline_additions: Vec<String>,
|
||||||
@ -915,7 +915,7 @@ pub struct DeviceManager {
|
|||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
id_to_dev_info: HashMap<(DeviceType, String), MMIODeviceInfo>,
|
id_to_dev_info: HashMap<(DeviceType, String), MmioDeviceInfo>,
|
||||||
|
|
||||||
// seccomp action
|
// seccomp action
|
||||||
seccomp_action: SeccompAction,
|
seccomp_action: SeccompAction,
|
||||||
@ -939,7 +939,7 @@ pub struct DeviceManager {
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
// GPIO device for AArch64
|
// GPIO device for AArch64
|
||||||
gpio_device: Option<Arc<Mutex<devices::legacy::GPIO>>>,
|
gpio_device: Option<Arc<Mutex<devices::legacy::Gpio>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceManager {
|
impl DeviceManager {
|
||||||
@ -1166,7 +1166,7 @@ impl DeviceManager {
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
/// Gets the information of the devices registered up to some point in time.
|
/// Gets the information of the devices registered up to some point in time.
|
||||||
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MMIODeviceInfo> {
|
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> {
|
||||||
&self.id_to_dev_info
|
&self.id_to_dev_info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1284,12 +1284,12 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub fn set_gic_device_entity(&mut self, device_entity: Arc<Mutex<Box<dyn GICDevice>>>) {
|
pub fn set_gic_device_entity(&mut self, device_entity: Arc<Mutex<Box<dyn GicDevice>>>) {
|
||||||
self.gic_device_entity = Some(device_entity);
|
self.gic_device_entity = Some(device_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub fn get_gic_device_entity(&self) -> Option<&Arc<Mutex<Box<dyn GICDevice>>>> {
|
pub fn get_gic_device_entity(&self) -> Option<&Arc<Mutex<Box<dyn GicDevice>>>> {
|
||||||
self.gic_device_entity.as_ref()
|
self.gic_device_entity.as_ref()
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@ -1536,7 +1536,7 @@ impl DeviceManager {
|
|||||||
})
|
})
|
||||||
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
||||||
|
|
||||||
let rtc_device = Arc::new(Mutex::new(devices::legacy::RTC::new(interrupt_group)));
|
let rtc_device = Arc::new(Mutex::new(devices::legacy::Rtc::new(interrupt_group)));
|
||||||
|
|
||||||
self.bus_devices
|
self.bus_devices
|
||||||
.push(Arc::clone(&rtc_device) as Arc<Mutex<dyn BusDevice>>);
|
.push(Arc::clone(&rtc_device) as Arc<Mutex<dyn BusDevice>>);
|
||||||
@ -1549,8 +1549,8 @@ impl DeviceManager {
|
|||||||
.map_err(DeviceManagerError::BusError)?;
|
.map_err(DeviceManagerError::BusError)?;
|
||||||
|
|
||||||
self.id_to_dev_info.insert(
|
self.id_to_dev_info.insert(
|
||||||
(DeviceType::RTC, "rtc".to_string()),
|
(DeviceType::Rtc, "rtc".to_string()),
|
||||||
MMIODeviceInfo {
|
MmioDeviceInfo {
|
||||||
addr: addr.0,
|
addr: addr.0,
|
||||||
len: MMIO_LEN,
|
len: MMIO_LEN,
|
||||||
irq: rtc_irq,
|
irq: rtc_irq,
|
||||||
@ -1573,7 +1573,7 @@ impl DeviceManager {
|
|||||||
})
|
})
|
||||||
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
||||||
|
|
||||||
let gpio_device = Arc::new(Mutex::new(devices::legacy::GPIO::new(
|
let gpio_device = Arc::new(Mutex::new(devices::legacy::Gpio::new(
|
||||||
id.clone(),
|
id.clone(),
|
||||||
interrupt_group,
|
interrupt_group,
|
||||||
)));
|
)));
|
||||||
@ -1591,8 +1591,8 @@ impl DeviceManager {
|
|||||||
self.gpio_device = Some(gpio_device.clone());
|
self.gpio_device = Some(gpio_device.clone());
|
||||||
|
|
||||||
self.id_to_dev_info.insert(
|
self.id_to_dev_info.insert(
|
||||||
(DeviceType::GPIO, "gpio".to_string()),
|
(DeviceType::Gpio, "gpio".to_string()),
|
||||||
MMIODeviceInfo {
|
MmioDeviceInfo {
|
||||||
addr: addr.0,
|
addr: addr.0,
|
||||||
len: MMIO_LEN,
|
len: MMIO_LEN,
|
||||||
irq: gpio_irq,
|
irq: gpio_irq,
|
||||||
@ -1661,7 +1661,7 @@ impl DeviceManager {
|
|||||||
&mut self,
|
&mut self,
|
||||||
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
|
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
|
||||||
serial_writer: Option<Box<dyn io::Write + Send>>,
|
serial_writer: Option<Box<dyn io::Write + Send>>,
|
||||||
) -> DeviceManagerResult<Arc<Mutex<devices::legacy::PL011>>> {
|
) -> DeviceManagerResult<Arc<Mutex<Pl011>>> {
|
||||||
let id = String::from(SERIAL_DEVICE_NAME_PREFIX);
|
let id = String::from(SERIAL_DEVICE_NAME_PREFIX);
|
||||||
|
|
||||||
let serial_irq = self
|
let serial_irq = self
|
||||||
@ -1678,7 +1678,7 @@ impl DeviceManager {
|
|||||||
})
|
})
|
||||||
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
||||||
|
|
||||||
let serial = Arc::new(Mutex::new(devices::legacy::PL011::new(
|
let serial = Arc::new(Mutex::new(devices::legacy::Pl011::new(
|
||||||
id.clone(),
|
id.clone(),
|
||||||
interrupt_group,
|
interrupt_group,
|
||||||
serial_writer,
|
serial_writer,
|
||||||
@ -1696,7 +1696,7 @@ impl DeviceManager {
|
|||||||
|
|
||||||
self.id_to_dev_info.insert(
|
self.id_to_dev_info.insert(
|
||||||
(DeviceType::Serial, DeviceType::Serial.to_string()),
|
(DeviceType::Serial, DeviceType::Serial.to_string()),
|
||||||
MMIODeviceInfo {
|
MmioDeviceInfo {
|
||||||
addr: addr.0,
|
addr: addr.0,
|
||||||
len: MMIO_LEN,
|
len: MMIO_LEN,
|
||||||
irq: serial_irq,
|
irq: serial_irq,
|
||||||
|
@ -85,7 +85,7 @@ use vmm_sys_util::eventfd::EventFd;
|
|||||||
use vmm_sys_util::terminal::Terminal;
|
use vmm_sys_util::terminal::Terminal;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use arch::aarch64::gic::gicv3::kvm::{KvmGICv3, GIC_V3_SNAPSHOT_ID};
|
use arch::aarch64::gic::gicv3::kvm::{KvmGicV3, GIC_V3_SNAPSHOT_ID};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use arch::aarch64::gic::kvm::create_gic;
|
use arch::aarch64::gic::kvm::create_gic;
|
||||||
|
|
||||||
@ -1879,7 +1879,7 @@ impl Vm {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_any_concrete_mut()
|
.as_any_concrete_mut()
|
||||||
.downcast_mut::<KvmGICv3>()
|
.downcast_mut::<KvmGicV3>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.snapshot()?,
|
.snapshot()?,
|
||||||
);
|
);
|
||||||
@ -1925,7 +1925,7 @@ impl Vm {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_any_concrete_mut()
|
.as_any_concrete_mut()
|
||||||
.downcast_mut::<KvmGICv3>()
|
.downcast_mut::<KvmGicV3>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.restore(*gic_v3_snapshot.clone())?;
|
.restore(*gic_v3_snapshot.clone())?;
|
||||||
} else {
|
} else {
|
||||||
@ -2421,19 +2421,19 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use arch::aarch64::fdt::create_fdt;
|
use arch::aarch64::fdt::create_fdt;
|
||||||
use arch::aarch64::gic::kvm::create_gic;
|
use arch::aarch64::gic::kvm::create_gic;
|
||||||
use arch::aarch64::{layout, DeviceInfoForFDT};
|
use arch::aarch64::{layout, DeviceInfoForFdt};
|
||||||
use arch::DeviceType;
|
use arch::DeviceType;
|
||||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||||
|
|
||||||
const LEN: u64 = 4096;
|
const LEN: u64 = 4096;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MMIODeviceInfo {
|
pub struct MmioDeviceInfo {
|
||||||
addr: u64,
|
addr: u64,
|
||||||
irq: u32,
|
irq: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceInfoForFDT for MMIODeviceInfo {
|
impl DeviceInfoForFdt for MmioDeviceInfo {
|
||||||
fn addr(&self) -> u64 {
|
fn addr(&self) -> u64 {
|
||||||
self.addr
|
self.addr
|
||||||
}
|
}
|
||||||
@ -2454,21 +2454,21 @@ mod tests {
|
|||||||
));
|
));
|
||||||
let mem = GuestMemoryMmap::from_ranges(®ions).expect("Cannot initialize memory");
|
let mem = GuestMemoryMmap::from_ranges(®ions).expect("Cannot initialize memory");
|
||||||
|
|
||||||
let dev_info: HashMap<(DeviceType, std::string::String), MMIODeviceInfo> = [
|
let dev_info: HashMap<(DeviceType, std::string::String), MmioDeviceInfo> = [
|
||||||
(
|
(
|
||||||
(DeviceType::Serial, DeviceType::Serial.to_string()),
|
(DeviceType::Serial, DeviceType::Serial.to_string()),
|
||||||
MMIODeviceInfo { addr: 0x00, irq: 1 },
|
MmioDeviceInfo { addr: 0x00, irq: 1 },
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
(DeviceType::Virtio(1), "virtio".to_string()),
|
(DeviceType::Virtio(1), "virtio".to_string()),
|
||||||
MMIODeviceInfo {
|
MmioDeviceInfo {
|
||||||
addr: 0x00 + LEN,
|
addr: 0x00 + LEN,
|
||||||
irq: 2,
|
irq: 2,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
(DeviceType::RTC, "rtc".to_string()),
|
(DeviceType::Rtc, "rtc".to_string()),
|
||||||
MMIODeviceInfo {
|
MmioDeviceInfo {
|
||||||
addr: 0x00 + 2 * LEN,
|
addr: 0x00 + 2 * LEN,
|
||||||
irq: 3,
|
irq: 3,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user