devmgr_srv/
lib.rs

1use devmgr::{DriverSpec, OwnedDevice};
2use pci_types::device_type::DeviceType;
3use twizzler::{
4    collections::vec::VecObject,
5    object::{ObjID, ObjectBuilder},
6};
7use twizzler_abi::kso::{KactionCmd, KactionFlags};
8use twizzler_driver::{
9    bus::pcie::{PcieDeviceInfo, PcieFunctionHeader, PcieKactionSpecific},
10    device::{BusType, Device},
11};
12use twizzler_rt_abi::error::TwzError;
13use volatile::map_field;
14
15fn get_pcie_offset(bus: u8, device: u8, function: u8) -> usize {
16    ((bus as usize * 256) + (device as usize * 8) + function as usize) * 4096
17}
18
19fn start_pcie_device(seg: &Device, bus: u8, device: u8, function: u8) {
20    let kr = seg.kaction(
21        KactionCmd::Specific(PcieKactionSpecific::RegisterDevice.into()),
22        ((bus as u64) << 16) | ((device as u64) << 8) | (function as u64),
23        KactionFlags::empty(),
24        0,
25    );
26    match kr {
27        Ok(_) => {}
28        Err(_) => eprintln!(
29            "failed to register pcie device {:x}.{:x}.{:x}",
30            bus, device, function
31        ),
32    }
33}
34
35fn start_pcie(seg: Device) {
36    tracing::info!("[devmgr] scanning PCIe bus");
37    let mmio = seg.get_mmio(0).unwrap();
38
39    for bus in 0..=255 {
40        for device in 0..32 {
41            let off = get_pcie_offset(bus, device, 0);
42            let cfg = unsafe { mmio.get_mmio_offset::<PcieFunctionHeader>(off) };
43            let cfg = cfg.as_ptr();
44            if map_field!(cfg.vendor_id).read() != 0xffff
45                && map_field!(cfg.device_id).read() != 0xffff
46                && map_field!(cfg.vendor_id).read() != 0
47            {
48                let mf = if map_field!(cfg.header_type).read() & 0x80 != 0 {
49                    7
50                } else {
51                    0
52                };
53                for function in 0..=mf {
54                    let off = get_pcie_offset(bus, device, function);
55                    let cfg = unsafe { mmio.get_mmio_offset::<PcieFunctionHeader>(off) };
56                    let cfg = cfg.as_ptr();
57                    if map_field!(cfg.vendor_id).read() != 0xffff {
58                        let dt = DeviceType::from((
59                            map_field!(cfg.class).read(),
60                            map_field!(cfg.subclass).read(),
61                        ));
62                        tracing::info!(
63                            "pcie device: {:02x}:{:02x}.{:02x} -- {:?} ({:x} {:x})",
64                            bus,
65                            device,
66                            function,
67                            dt,
68                            map_field!(cfg.class).read(),
69                            map_field!(cfg.subclass).read()
70                        );
71                        start_pcie_device(&seg, bus, device, function)
72                    }
73                }
74            }
75        }
76    }
77}
78
79#[secgate::entry(lib = "devmgr")]
80pub fn devmgr_start() -> Result<(), TwzError> {
81    tracing::subscriber::set_global_default(
82        tracing_subscriber::fmt()
83            .with_max_level(tracing::Level::INFO)
84            .without_time()
85            .finish(),
86    )
87    .unwrap();
88
89    let device_root = twizzler_driver::get_bustree_root();
90    for device in device_root.children() {
91        if device.is_bus() && device.bus_type() == BusType::Pcie {
92            start_pcie(device);
93        }
94    }
95    Ok(())
96}
97
98#[secgate::entry(lib = "devmgr")]
99pub fn get_devices(spec: DriverSpec) -> Result<ObjID, TwzError> {
100    match spec.supported {
101        devmgr::Supported::PcieClass(class, subclass, progif) => {
102            let device_root = twizzler_driver::get_bustree_root();
103            let mut ids = Vec::new();
104            for device in device_root.children() {
105                if device.is_bus() && device.bus_type() == BusType::Pcie {
106                    for child in device.children() {
107                        let info = unsafe { child.get_info::<PcieDeviceInfo>(0).unwrap() };
108                        if info.get_data().class == class
109                            && info.get_data().subclass == subclass
110                            && info.get_data().progif == progif
111                        {
112                            ids.push(child.id());
113                        }
114                    }
115                }
116            }
117
118            tracing::debug!("found devices {:?} for spec {:?}", ids, spec);
119            let mut owned_devices_object = VecObject::new(ObjectBuilder::default())?;
120            for id in ids {
121                owned_devices_object.push(OwnedDevice { id })?;
122            }
123            // TODO: on-drop for this object.
124            Ok(owned_devices_object.object().id())
125        }
126        devmgr::Supported::Vendor(vendor_code, device_code) => {
127            let device_root = twizzler_driver::get_bustree_root();
128            let mut ids = Vec::new();
129            for device in device_root.children() {
130                if device.is_bus() && device.bus_type() == BusType::Pcie {
131                    for child in device.children() {
132                        unsafe {
133
134                        let Some(info) =  child.get_info::<PcieDeviceInfo>(0)  else {continue;};
135                        if info.get_data().device_id == device_code
136                            && info.get_data().vendor_id == vendor_code
137                        {
138                            ids.push(child.id());
139                        }
140                        }
141                    }
142                }
143            }
144
145            tracing::debug!("found devices {:?} for spec {:?}", ids, spec);
146            let mut owned_devices_object = VecObject::new(ObjectBuilder::default())?;
147            for id in ids {
148                owned_devices_object.push(OwnedDevice { id })?;
149            }
150            // TODO: on-drop for this object.
151            Ok(owned_devices_object.object().id())
152        }
153    }
154}