dev: pass DeviceInitContext into Device::init()
This commit is contained in:
parent
7348232aa9
commit
8cbde8389f
@ -8,7 +8,7 @@ use alloc::{format, sync::Arc, vec::Vec};
|
||||
use bytemuck::Zeroable;
|
||||
use data::ReceivedFis;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptAffinity, InterruptHandler, IrqVector},
|
||||
};
|
||||
use error::AhciError;
|
||||
@ -181,7 +181,9 @@ impl InterruptHandler for AhciController {
|
||||
}
|
||||
|
||||
impl Device for AhciController {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
// Do the init in background
|
||||
runtime::spawn(self.late_init())?;
|
||||
Ok(())
|
||||
|
@ -15,7 +15,7 @@ use core::{
|
||||
use alloc::{collections::BTreeMap, format, sync::Arc, vec::Vec};
|
||||
use command::{IdentifyActiveNamespaceIdListRequest, IdentifyControllerRequest};
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptAffinity, InterruptHandler, IrqVector},
|
||||
};
|
||||
use drive::NvmeNamespace;
|
||||
@ -345,7 +345,10 @@ impl InterruptHandler for NvmeController {
|
||||
}
|
||||
|
||||
impl Device for NvmeController {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
|
||||
let regs = self.regs.lock();
|
||||
|
||||
let timeout = Duration::from_millis(regs.CAP.read(CAP::TO) * 500);
|
||||
|
@ -13,8 +13,12 @@ use alloc::{format, sync::Arc, vec::Vec};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use device::{PciBusDevice, PciDeviceInfo};
|
||||
use device_api::device::DeviceInitContext;
|
||||
use interrupt::{PciInterruptMap, PciMsiMap};
|
||||
use libk::fs::sysfs::{self, object::KObject};
|
||||
use libk::{
|
||||
dma::DummyDmaAllocator,
|
||||
fs::sysfs::{self, object::KObject},
|
||||
};
|
||||
use libk_mm::address::PhysicalAddress;
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use space::legacy;
|
||||
@ -614,8 +618,11 @@ fn setup_bus_device(device: &mut PciBusDevice) -> Result<(), Error> {
|
||||
if let Some(driver) = driver::lookup_driver(&device.info) {
|
||||
log::info!("{} -> {}", device.info.address, driver.driver_name());
|
||||
let instance = driver.probe(&device.info)?;
|
||||
let cx = DeviceInitContext {
|
||||
dma_allocator: Arc::new(DummyDmaAllocator),
|
||||
};
|
||||
|
||||
unsafe { instance.clone().init() }?;
|
||||
unsafe { instance.clone().init(cx) }?;
|
||||
|
||||
device.device.replace(instance);
|
||||
device.driver_name.replace(driver.driver_name());
|
||||
|
@ -2,7 +2,7 @@ use core::mem::MaybeUninit;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptHandler, IrqVector},
|
||||
};
|
||||
use libk::error::Error;
|
||||
@ -342,7 +342,10 @@ impl InterruptHandler for Rtl8139 {
|
||||
}
|
||||
|
||||
impl Device for Rtl8139 {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
|
||||
log::info!("Initialize rtl8139 driver");
|
||||
log::info!("MAC: {}", self.mac);
|
||||
|
||||
|
@ -5,7 +5,7 @@ use core::{
|
||||
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptHandler, IrqVector},
|
||||
};
|
||||
use libk::error::Error;
|
||||
@ -592,7 +592,9 @@ impl InterruptHandler for Rtl8168 {
|
||||
}
|
||||
|
||||
impl Device for Rtl8168 {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
log::info!("Initialize rtl8168");
|
||||
log::info!("MAC: {}", self.mac);
|
||||
|
||||
|
@ -3,7 +3,7 @@ use core::sync::atomic::{AtomicU8, Ordering};
|
||||
use alloc::{boxed::Box, collections::btree_map::BTreeMap, sync::Arc, vec::Vec};
|
||||
use async_trait::async_trait;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptHandler, IrqVector},
|
||||
};
|
||||
use libk::{error::Error, task::runtime};
|
||||
@ -443,7 +443,10 @@ impl CommandExecutor for Xhci {
|
||||
}
|
||||
|
||||
impl Device for Xhci {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
|
||||
self.regs.hc_reset(10000000)?;
|
||||
log::info!("xHC reset complete");
|
||||
|
||||
|
@ -6,7 +6,7 @@ use core::mem::MaybeUninit;
|
||||
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use command::{ControlLock, ScanoutInfo};
|
||||
use device_api::device::Device;
|
||||
use device_api::device::{Device, DeviceInitContext};
|
||||
use libk::device::{
|
||||
display::{
|
||||
DisplayDevice, DisplayMode, DisplayOwner, DriverFlags, FramebufferInfo, PixelFormat,
|
||||
@ -253,7 +253,9 @@ impl<T: Transport + 'static> VirtioGpu<T> {
|
||||
}
|
||||
|
||||
impl<T: Transport + 'static> Device for VirtioGpu<T> {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
let status = self.begin_init()?;
|
||||
self.setup_queues()?;
|
||||
self.finish_init(status);
|
||||
|
@ -8,7 +8,7 @@ use core::mem::size_of;
|
||||
use alloc::{collections::BTreeMap, sync::Arc};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{InterruptAffinity, InterruptHandler, IrqVector},
|
||||
};
|
||||
use libk_mm::PageBox;
|
||||
@ -253,7 +253,9 @@ impl<T: Transport + 'static> Device for VirtioNet<T> {
|
||||
"VirtIO Network Device"
|
||||
}
|
||||
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO use DmaAllocator instead of PageBox
|
||||
let _ = cx;
|
||||
let status = self.begin_init()?;
|
||||
|
||||
// TODO multiqueue
|
||||
|
@ -1,7 +1,11 @@
|
||||
use alloc::sync::Arc;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{bus::Bus, clock::ClockController};
|
||||
use crate::{bus::Bus, clock::ClockController, dma::DmaAllocator};
|
||||
|
||||
pub struct DeviceInitContext {
|
||||
pub dma_allocator: Arc<dyn DmaAllocator>,
|
||||
}
|
||||
|
||||
pub trait Device: Sync + Send {
|
||||
fn display_name(&self) -> &str;
|
||||
@ -13,7 +17,8 @@ pub trait Device: Sync + Send {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must make sure the function is only called once.
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||
let _ = cx;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
1
kernel/lib/device-api/src/dma.rs
Normal file
1
kernel/lib/device-api/src/dma.rs
Normal file
@ -0,0 +1 @@
|
||||
pub trait DmaAllocator {}
|
@ -11,6 +11,8 @@ pub mod interrupt;
|
||||
pub mod serial;
|
||||
pub mod timer;
|
||||
|
||||
pub mod dma;
|
||||
|
||||
use device::Device;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
|
@ -8,10 +8,11 @@ use alloc::{
|
||||
use device_api::{
|
||||
bus::Bus,
|
||||
clock::ClockController,
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{ExternalInterruptController, FullIrq, MessageInterruptController},
|
||||
};
|
||||
use fdt_rs::spec::Phandle;
|
||||
use libk::dma::DummyDmaAllocator;
|
||||
use libk_mm::address::PhysicalAddress;
|
||||
use libk_util::OneTimeInit;
|
||||
use yggdrasil_abi::error::Error;
|
||||
@ -188,7 +189,8 @@ impl Node {
|
||||
pub fn lazy_init(self: Arc<Self>) -> Option<Result<(), Error>> {
|
||||
let device = self.clone().probe()?;
|
||||
let result = self.init_token.or_try_init_with(|| {
|
||||
unsafe { device.init() }?;
|
||||
let cx = self.make_init_context();
|
||||
unsafe { device.init(cx) }?;
|
||||
Ok(())
|
||||
});
|
||||
match result {
|
||||
@ -233,12 +235,21 @@ impl Node {
|
||||
.inspect_err(|_| log::error!("Does not exist: probe({:?})", self.name))?;
|
||||
|
||||
self.init_token.try_init_with_opt(|| {
|
||||
unsafe { device.init() }?;
|
||||
let cx = self.make_init_context();
|
||||
unsafe { device.init(cx) }?;
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn make_init_context(&self) -> DeviceInitContext {
|
||||
let cx = DeviceInitContext {
|
||||
dma_allocator: Arc::new(DummyDmaAllocator),
|
||||
};
|
||||
|
||||
cx
|
||||
}
|
||||
|
||||
/// Returns an iterator over the node's children
|
||||
pub fn children(&self) -> impl Iterator<Item = &Arc<Node>> {
|
||||
self.children.get().iter()
|
||||
|
@ -49,18 +49,6 @@ impl PageProvider for Partition {
|
||||
}
|
||||
|
||||
impl Device for Partition {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn deinit(&self) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn init_irq(self: Arc<Self>) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn display_name(&self) -> &str {
|
||||
"Partition"
|
||||
}
|
||||
|
@ -162,36 +162,36 @@ impl DeviceRegistry {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn run_initialization(&self) {
|
||||
let mut devices = self.pending_initialization.write();
|
||||
// pub fn run_initialization(&self) {
|
||||
// let mut devices = self.pending_initialization.write();
|
||||
|
||||
for pending in devices.iter_mut() {
|
||||
if pending.irq_only {
|
||||
continue;
|
||||
}
|
||||
// for pending in devices.iter_mut() {
|
||||
// if pending.irq_only {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
log::debug!("Init device: {:?}", pending.device.display_name());
|
||||
if let Err(error) = unsafe { pending.device.clone().init() } {
|
||||
log::error!("{:?} init error: {error:?}", pending.device.display_name());
|
||||
pending.failed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// log::debug!("Init device: {:?}", pending.device.display_name());
|
||||
// if let Err(error) = unsafe { pending.device.clone().init() } {
|
||||
// log::error!("{:?} init error: {error:?}", pending.device.display_name());
|
||||
// pending.failed = true;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
for pending in devices.drain(..) {
|
||||
if pending.failed {
|
||||
continue;
|
||||
}
|
||||
// for pending in devices.drain(..) {
|
||||
// if pending.failed {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
log::debug!("Init IRQ: {:?}", pending.device.display_name());
|
||||
if let Err(error) = unsafe { pending.device.clone().init_irq() } {
|
||||
log::error!(
|
||||
"{:?} IRQ init error: {error:?}",
|
||||
pending.device.display_name()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// log::debug!("Init IRQ: {:?}", pending.device.display_name());
|
||||
// if let Err(error) = unsafe { pending.device.clone().init_irq() } {
|
||||
// log::error!(
|
||||
// "{:?} IRQ init error: {error:?}",
|
||||
// pending.device.display_name()
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
async fn probe_partition_table(
|
||||
|
5
kernel/libk/src/dma.rs
Normal file
5
kernel/libk/src/dma.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use device_api::dma::DmaAllocator;
|
||||
|
||||
pub struct DummyDmaAllocator;
|
||||
|
||||
impl DmaAllocator for DummyDmaAllocator {}
|
@ -44,6 +44,8 @@ pub mod random;
|
||||
pub mod time;
|
||||
pub mod vfs;
|
||||
|
||||
pub mod dma;
|
||||
|
||||
#[cfg(any(target_os = "none", rust_analyzer))]
|
||||
pub mod panic;
|
||||
|
||||
|
@ -4,7 +4,7 @@ use core::{mem::offset_of, ops::Range};
|
||||
use abi::error::Error;
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{
|
||||
ExternalInterruptController, InterruptAffinity, InterruptHandler, Irq, IrqLevel,
|
||||
IrqOptions, IrqTrigger, IrqVector, MessageInterruptController, MsiInfo,
|
||||
@ -83,7 +83,7 @@ pub struct Gicv2m {
|
||||
}
|
||||
|
||||
impl Device for Gicv2m {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
let regs = self.regs.lock();
|
||||
log::info!("gicv2m: init @ {:#x}", self.base);
|
||||
|
||||
|
@ -6,7 +6,7 @@ use aarch64_cpu::asm::barrier;
|
||||
use abi::error::Error;
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{
|
||||
ExternalInterruptController, FixedInterruptTable, FullIrq, InterruptHandler,
|
||||
InterruptTable, IpiDeliveryTarget, IpiMessage, Irq, IrqLevel, IrqOptions, IrqTrigger,
|
||||
@ -58,7 +58,7 @@ impl Device for Gic {
|
||||
"ARM Generic Interrupt Controller v2"
|
||||
}
|
||||
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
log::debug!(
|
||||
"Init GIC: gicd={:#x}, gicc={:#x}",
|
||||
self.gicd_base,
|
||||
|
@ -6,7 +6,7 @@ use aarch64_cpu::registers::{CNTFRQ_EL0, CNTPCT_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0
|
||||
use abi::{error::Error, time::NANOSECONDS_IN_SECOND};
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{FullIrq, InterruptHandler, IrqVector},
|
||||
};
|
||||
use device_tree::driver::{device_tree_driver, Node, ProbeContext};
|
||||
@ -55,7 +55,7 @@ impl Device for ArmTimer {
|
||||
"ARM Generic Timer"
|
||||
}
|
||||
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET + CNTP_CTL_EL0::IMASK::SET);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -7,7 +7,10 @@ use core::ops::Range;
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use device_api::{bus::Bus, device::Device};
|
||||
use device_api::{
|
||||
bus::Bus,
|
||||
device::{Device, DeviceInitContext},
|
||||
};
|
||||
use device_tree::{
|
||||
driver::{device_tree_driver, Node, ProbeContext},
|
||||
DeviceTreePropertyRead,
|
||||
@ -18,7 +21,7 @@ struct SimpleBus {
|
||||
}
|
||||
|
||||
impl Device for SimpleBus {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,10 @@
|
||||
use aarch64_cpu::registers::ReadWriteable;
|
||||
use abi::error::Error;
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{clock::ClockController, device::Device};
|
||||
use device_api::{
|
||||
clock::ClockController,
|
||||
device::{Device, DeviceInitContext},
|
||||
};
|
||||
use device_tree::driver::{device_tree_driver, Node, ProbeContext};
|
||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
@ -52,7 +55,7 @@ impl ClockController for Bcm2835Aux {
|
||||
}
|
||||
|
||||
impl Device for Bcm2835Aux {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
let regs = DeviceMemoryIo::map(self.base, Default::default())?;
|
||||
self.regs.init(IrqSafeSpinlock::new(regs));
|
||||
Ok(())
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{device::Device, CpuBringupDevice, ResetDevice};
|
||||
use device_api::{
|
||||
device::{Device, DeviceInitContext},
|
||||
CpuBringupDevice, ResetDevice,
|
||||
};
|
||||
use device_tree::{
|
||||
driver::{device_tree_driver, Node, ProbeContext},
|
||||
DeviceTreePropertyRead,
|
||||
@ -31,7 +34,7 @@ impl Device for Psci {
|
||||
"ARM PSCI"
|
||||
}
|
||||
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
PLATFORM.psci.init(self.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use abi::{
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{FullIrq, InterruptHandler, IrqVector},
|
||||
};
|
||||
use device_tree::{
|
||||
@ -148,7 +148,7 @@ impl InterruptHandler for Bcm2835AuxUart {
|
||||
}
|
||||
|
||||
impl Device for Bcm2835AuxUart {
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
// TODO initialize pinctrl
|
||||
|
||||
// NOTE: might as well make it an error if clock cannot be initialized
|
||||
|
@ -2,7 +2,7 @@
|
||||
use abi::{error::Error, io::TerminalOptions};
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
device::{Device, DeviceInitContext},
|
||||
interrupt::{FullIrq, InterruptHandler, IrqVector},
|
||||
};
|
||||
use device_tree::driver::{device_tree_driver, Node, ProbeContext};
|
||||
@ -139,7 +139,7 @@ impl Device for Pl011 {
|
||||
"Primecell PL011 UART"
|
||||
}
|
||||
|
||||
unsafe fn init(self: Arc<Self>) -> Result<(), Error> {
|
||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||
let mut io = Io {
|
||||
regs: DeviceMemoryIo::map(self.base, Default::default())?,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user