axdriver/
drivers.rs

1//! Defines types and probe methods of all supported devices.
2
3#![allow(unused_imports, dead_code)]
4
5use crate::AxDeviceEnum;
6use axdriver_base::DeviceType;
7
8#[cfg(feature = "virtio")]
9use crate::virtio::{self, VirtIoDevMeta};
10
11#[cfg(feature = "bus-pci")]
12use axdriver_pci::{DeviceFunction, DeviceFunctionInfo, PciRoot};
13
14pub use super::dummy::*;
15
16pub trait DriverProbe {
17    fn probe_global() -> Option<AxDeviceEnum> {
18        None
19    }
20
21    #[cfg(bus = "mmio")]
22    fn probe_mmio(_mmio_base: usize, _mmio_size: usize) -> Option<AxDeviceEnum> {
23        None
24    }
25
26    #[cfg(bus = "pci")]
27    fn probe_pci(
28        _root: &mut PciRoot,
29        _bdf: DeviceFunction,
30        _dev_info: &DeviceFunctionInfo,
31    ) -> Option<AxDeviceEnum> {
32        None
33    }
34}
35
36#[cfg(net_dev = "virtio-net")]
37register_net_driver!(
38    <virtio::VirtIoNet as VirtIoDevMeta>::Driver,
39    <virtio::VirtIoNet as VirtIoDevMeta>::Device
40);
41
42#[cfg(block_dev = "virtio-blk")]
43register_block_driver!(
44    <virtio::VirtIoBlk as VirtIoDevMeta>::Driver,
45    <virtio::VirtIoBlk as VirtIoDevMeta>::Device
46);
47
48#[cfg(display_dev = "virtio-gpu")]
49register_display_driver!(
50    <virtio::VirtIoGpu as VirtIoDevMeta>::Driver,
51    <virtio::VirtIoGpu as VirtIoDevMeta>::Device
52);
53
54cfg_if::cfg_if! {
55    if #[cfg(block_dev = "ramdisk")] {
56        pub struct RamDiskDriver;
57        register_block_driver!(RamDiskDriver, axdriver_block::ramdisk::RamDisk);
58
59        impl DriverProbe for RamDiskDriver {
60            fn probe_global() -> Option<AxDeviceEnum> {
61                // TODO: format RAM disk
62                Some(AxDeviceEnum::from_block(
63                    axdriver_block::ramdisk::RamDisk::new(0x100_0000), // 16 MiB
64                ))
65            }
66        }
67    }
68}
69
70cfg_if::cfg_if! {
71    if #[cfg(block_dev = "bcm2835-sdhci")]{
72        pub struct BcmSdhciDriver;
73        register_block_driver!(MmckDriver, axdriver_block::bcm2835sdhci::SDHCIDriver);
74
75        impl DriverProbe for BcmSdhciDriver {
76            fn probe_global() -> Option<AxDeviceEnum> {
77                debug!("mmc probe");
78                axdriver_block::bcm2835sdhci::SDHCIDriver::try_new().ok().map(AxDeviceEnum::from_block)
79            }
80        }
81    }
82}
83
84cfg_if::cfg_if! {
85    if #[cfg(net_dev = "ixgbe")] {
86        use crate::ixgbe::IxgbeHalImpl;
87        use axhal::mem::phys_to_virt;
88        pub struct IxgbeDriver;
89        register_net_driver!(IxgbeDriver, axdriver_net::ixgbe::IxgbeNic<IxgbeHalImpl, 1024, 1>);
90        impl DriverProbe for IxgbeDriver {
91            #[cfg(bus = "pci")]
92            fn probe_pci(
93                    root: &mut axdriver_pci::PciRoot,
94                    bdf: axdriver_pci::DeviceFunction,
95                    dev_info: &axdriver_pci::DeviceFunctionInfo,
96                ) -> Option<crate::AxDeviceEnum> {
97                    use axdriver_net::ixgbe::{INTEL_82599, INTEL_VEND, IxgbeNic};
98                    if dev_info.vendor_id == INTEL_VEND && dev_info.device_id == INTEL_82599 {
99                        // Intel 10Gb Network
100                        info!("ixgbe PCI device found at {:?}", bdf);
101
102                        // Initialize the device
103                        // These can be changed according to the requirments specified in the ixgbe init function.
104                        const QN: u16 = 1;
105                        const QS: usize = 1024;
106                        let bar_info = root.bar_info(bdf, 0).unwrap();
107                        match bar_info {
108                            axdriver_pci::BarInfo::Memory {
109                                address,
110                                size,
111                                ..
112                            } => {
113                                let ixgbe_nic = IxgbeNic::<IxgbeHalImpl, QS, QN>::init(
114                                    phys_to_virt((address as usize).into()).into(),
115                                    size as usize
116                                )
117                                .expect("failed to initialize ixgbe device");
118                                return Some(AxDeviceEnum::from_net(ixgbe_nic));
119                            }
120                            axdriver_pci::BarInfo::IO { .. } => {
121                                error!("ixgbe: BAR0 is of I/O type");
122                                return None;
123                            }
124                        }
125                    }
126                    None
127            }
128        }
129    }
130}
131
132cfg_if::cfg_if! {
133    if #[cfg(net_dev = "fxmac")]{
134        use axalloc::global_allocator;
135        use axhal::mem::PAGE_SIZE_4K;
136
137        #[crate_interface::impl_interface]
138        impl axdriver_net::fxmac::KernelFunc for FXmacDriver {
139            fn virt_to_phys(addr: usize) -> usize {
140                axhal::mem::virt_to_phys(addr.into()).into()
141            }
142
143            fn phys_to_virt(addr: usize) -> usize {
144                axhal::mem::phys_to_virt(addr.into()).into()
145            }
146
147            fn dma_alloc_coherent(pages: usize) -> (usize, usize) {
148                let Ok(vaddr) = global_allocator().alloc_pages(pages, PAGE_SIZE_4K) else {
149                    error!("failed to alloc pages");
150                    return (0, 0);
151                };
152                let paddr = axhal::mem::virt_to_phys((vaddr).into());
153                debug!("alloc pages @ vaddr={:#x}, paddr={:#x}", vaddr, paddr);
154                (vaddr, paddr.as_usize())
155            }
156
157            fn dma_free_coherent(vaddr: usize, pages: usize) {
158                global_allocator().dealloc_pages(vaddr, pages);
159            }
160
161            fn dma_request_irq(_irq: usize, _handler: fn()) {
162                warn!("unimplemented dma_request_irq for fxmax");
163            }
164        }
165
166        register_net_driver!(FXmacDriver, axdriver_net::fxmac::FXmacNic);
167
168        pub struct FXmacDriver;
169        impl DriverProbe for FXmacDriver {
170            fn probe_global() -> Option<AxDeviceEnum> {
171                info!("fxmac for phytiumpi probe global");
172                axdriver_net::fxmac::FXmacNic::init(0).ok().map(AxDeviceEnum::from_net)
173            }
174        }
175    }
176}