use alloc::{sync::Arc, vec::Vec};
use axdevice_base::{Device, DmaGrant, StopGrant, TimerGrant, WakeGrant};
use crate::{DeviceManagerResult, DeviceServices, ServiceKey};
pub trait PollableDeviceOps: Send + Sync {
fn poll(&self, now_ns: u64) -> DeviceManagerResult;
}
pub trait DeviceLifecycle: Send + Sync {
fn reset(&self) -> DeviceManagerResult;
fn suspend(&self) -> DeviceManagerResult;
fn resume(&self) -> DeviceManagerResult;
}
#[non_exhaustive]
pub enum DeviceRegistration {
Device(Arc<dyn Device>),
Pollable(Arc<dyn PollableDeviceOps>),
}
#[derive(Default)]
pub struct DeviceBundle {
pub(crate) devices: Vec<Arc<dyn Device>>,
pub(crate) guest_memory_devices: Vec<(usize, DmaGrant)>,
pub(crate) timer_devices: Vec<(usize, TimerGrant)>,
pub(crate) wake_devices: Vec<(usize, WakeGrant)>,
pub(crate) stop_devices: Vec<(usize, StopGrant)>,
pub(crate) pollable: Vec<Arc<dyn PollableDeviceOps>>,
pub(crate) lifecycle: Vec<Arc<dyn DeviceLifecycle>>,
pub(crate) services: DeviceServices,
}
impl DeviceBundle {
pub const fn new() -> Self {
Self {
devices: Vec::new(),
guest_memory_devices: Vec::new(),
timer_devices: Vec::new(),
wake_devices: Vec::new(),
stop_devices: Vec::new(),
pollable: Vec::new(),
lifecycle: Vec::new(),
services: DeviceServices::new(),
}
}
pub fn from_registration(registration: DeviceRegistration) -> Self {
let mut bundle = Self::new();
bundle.push(registration);
bundle
}
pub fn push(&mut self, registration: DeviceRegistration) {
match registration {
DeviceRegistration::Device(device) => self.devices.push(device),
DeviceRegistration::Pollable(device) => self.pollable.push(device),
}
}
pub fn add_device(&mut self, device: Arc<dyn Device>) -> usize {
let index = self.devices.len();
self.devices.push(device);
index
}
pub fn grant_guest_memory_to_device(&mut self, device_index: usize, grant: DmaGrant) {
self.guest_memory_devices.push((device_index, grant));
}
pub fn grant_timer_to_device(&mut self, device_index: usize, grant: TimerGrant) {
self.timer_devices.push((device_index, grant));
}
pub fn grant_wake_to_device(&mut self, device_index: usize, grant: WakeGrant) {
self.wake_devices.push((device_index, grant));
}
pub fn grant_stop_to_device(&mut self, device_index: usize, grant: StopGrant) {
self.stop_devices.push((device_index, grant));
}
pub fn add_guest_memory_device(&mut self, device: Arc<dyn Device>) {
let device_index = self.add_device(device);
self.grant_guest_memory_to_device(device_index, DmaGrant::new());
}
pub fn add_guest_memory_device_with_grant(&mut self, device: Arc<dyn Device>, grant: DmaGrant) {
let device_index = self.add_device(device);
self.grant_guest_memory_to_device(device_index, grant);
}
pub fn add_timer_device_with_grant(&mut self, device: Arc<dyn Device>, grant: TimerGrant) {
let device_index = self.add_device(device);
self.grant_timer_to_device(device_index, grant);
}
pub fn add_wake_device_with_grant(&mut self, device: Arc<dyn Device>, grant: WakeGrant) {
let device_index = self.add_device(device);
self.grant_wake_to_device(device_index, grant);
}
pub fn add_stop_device_with_grant(&mut self, device: Arc<dyn Device>, grant: StopGrant) {
let device_index = self.add_device(device);
self.grant_stop_to_device(device_index, grant);
}
pub fn with_guest_memory_device_grant(
mut self,
device: Arc<dyn Device>,
grant: DmaGrant,
) -> Self {
self.add_guest_memory_device_with_grant(device, grant);
self
}
pub fn with_timer_device_grant(mut self, device: Arc<dyn Device>, grant: TimerGrant) -> Self {
self.add_timer_device_with_grant(device, grant);
self
}
pub fn with_wake_device_grant(mut self, device: Arc<dyn Device>, grant: WakeGrant) -> Self {
self.add_wake_device_with_grant(device, grant);
self
}
pub fn with_stop_device_grant(mut self, device: Arc<dyn Device>, grant: StopGrant) -> Self {
self.add_stop_device_with_grant(device, grant);
self
}
pub fn with_guest_memory_device(mut self, device: Arc<dyn Device>) -> Self {
self.add_guest_memory_device(device);
self
}
pub fn with_registration(mut self, registration: DeviceRegistration) -> Self {
self.push(registration);
self
}
pub fn add_lifecycle(&mut self, lifecycle: Arc<dyn DeviceLifecycle>) {
self.lifecycle.push(lifecycle);
}
pub fn with_lifecycle(mut self, lifecycle: Arc<dyn DeviceLifecycle>) -> Self {
self.add_lifecycle(lifecycle);
self
}
pub fn provide_service<K: ServiceKey>(
&mut self,
service: Arc<K::Service>,
) -> DeviceManagerResult {
self.services.provide::<K>(service)
}
pub fn with_service<K: ServiceKey>(
mut self,
service: Arc<K::Service>,
) -> DeviceManagerResult<Self> {
self.provide_service::<K>(service)?;
Ok(self)
}
pub fn is_empty(&self) -> bool {
self.devices.is_empty()
&& self.guest_memory_devices.is_empty()
&& self.timer_devices.is_empty()
&& self.wake_devices.is_empty()
&& self.stop_devices.is_empty()
&& self.pollable.is_empty()
&& self.lifecycle.is_empty()
&& self.services.is_empty()
}
}
impl From<DeviceRegistration> for DeviceBundle {
fn from(registration: DeviceRegistration) -> Self {
Self::from_registration(registration)
}
}