//! Simple "passthrough" bus device // use device_tree::{device_tree_driver, dt::DevTreeIndexNodeExt}; // use libk::device::manager::DEVICE_REGISTRY; use core::ops::Range; use abi::error::Error; use alloc::{sync::Arc, vec::Vec}; use device_api::{ bus::Bus, device::{Device, DeviceInitContext}, }; use device_tree::{ driver::{device_tree_driver, Node, ProbeContext}, DeviceTreePropertyRead, }; struct SimpleBus { ranges: Vec<(Range, u64)>, } impl Device for SimpleBus { unsafe fn init(self: Arc, _cx: DeviceInitContext) -> Result<(), Error> { Ok(()) } fn as_bus(self: Arc) -> Option> { Some(self) } fn display_name(&self) -> &str { "simple-bus" } } impl Bus for SimpleBus { fn map_range(&self, bus_range: Range) -> Option> { if self.ranges.is_empty() { return Some(bus_range); } let start = bus_range.start; let end = bus_range.end; for (range, offset) in self.ranges.iter() { if range.contains(&start) && range.contains(&end) { let start = start - range.start + *offset; let end = end - range.start + *offset; return Some(start..end); } } None } } device_tree_driver! { compatible: ["simple-bus"], driver: { fn probe(&self, node: &Arc, _context: &ProbeContext) -> Option> { // Format per DT spec: (child-bus-address, parent-bus-address, length) // Where: // child-bus-address: #address-cells of this node // parent-bus-address: #address-cells of parent bus // length: #size-cells of this node let ranges = node.property("ranges")?; let parent_address_cells = node.bus_address_cells(); let child_address_cells = node.self_address_cells()?; let child_size_cells = node.self_size_cells()?; let cell_sizes = (child_address_cells, parent_address_cells, child_size_cells); let mut items = Vec::new(); for (child_address, parent_address, length) in ranges.iter_cells(cell_sizes) { let child_range = child_address..child_address + length; items.push((child_range, parent_address)); } Some(Arc::new(SimpleBus { ranges: items, })) } } }