From 7038e2a73656d3846c1fc514e1c77dfe8ec5b76f Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Mon, 13 Jun 2022 23:16:34 +0300 Subject: [PATCH] wip: calc address-cells and size-cells internally --- machine/src/device_tree.rs | 87 ++++++++++++++++++++++++++++++-------- nucleus/src/main.rs | 28 +----------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/machine/src/device_tree.rs b/machine/src/device_tree.rs index e6d574a2..5119ae9a 100644 --- a/machine/src/device_tree.rs +++ b/machine/src/device_tree.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use { + crate::println, core::alloc::Layout, fdt_rs::{ base::DevTree, @@ -59,34 +60,86 @@ impl<'a> DeviceTree<'a> { } Ok(prop.unwrap()) } - - // // @todo boot this on 8Gb RasPi, because I'm not sure how it allocates memory regions there. - // println!("Address cells: {}, size cells {}", address_cells, size_cells); - // - // let mem_prop = device_tree -- node - // .props() - // -- node with property named "device_type" and value "memory" - // .find(|p| Ok(p.name()? == "device_type" && p.str()? == "memory")) - // .unwrap() - // .expect("Unable to find memory node."); - // let mem_node = mem_prop.node(); - // // let parent_node = mem_node.parent_node(); } /// Augment DevTreeIndexProp with set of pairs accessor. #[derive(Shrinkwrap)] pub struct DeviceTreeProp<'a, 'i: 'a, 'dt: 'i>(DevTreeIndexProp<'a, 'i, 'dt>); +fn get_address_cells<'a, 'i: 'a, 'dt: 'i>(node: &DevTreeIndexNode<'a, 'i, 'dt>) -> u32 { + let mut prop_iter = node.props(); + let res: Result<_, DevTreeError> = + prop_iter.try_find(|prop| Ok(prop.name()? == "#address-cells")); + + if res.is_err() { + return 1; + } + + if let Some(res) = res.unwrap() { + return res.u32(0).unwrap(); + } + + while let Some(node) = node.parent() { + let mut prop_iter = node.props(); + let res: Result<_, DevTreeError> = + prop_iter.try_find(|prop| Ok(prop.name()? == "#address-cells")); + + if res.is_err() { + return 1; + } + + if let Some(res) = res.unwrap() { + return res.u32(0).unwrap(); + } + } + + 1 +} + +fn get_size_cells<'a, 'i: 'a, 'dt: 'i>(node: &DevTreeIndexNode<'a, 'i, 'dt>) -> u32 { + let mut prop_iter = node.props(); + let res: Result<_, DevTreeError> = prop_iter.try_find(|prop| Ok(prop.name()? == "#size-cells")); + + if res.is_err() { + return 1; + } + + if let Some(res) = res.unwrap() { + return res.u32(0).unwrap(); + } + + while let Some(node) = node.parent() { + let mut prop_iter = node.props(); + let res: Result<_, DevTreeError> = + prop_iter.try_find(|prop| Ok(prop.name()? == "#size-cells")); + + if res.is_err() { + return 1; + } + + if let Some(res) = res.unwrap() { + return res.u32(0).unwrap(); + } + } + + 1 +} + impl<'a, 'i: 'a, 'dt: 'i> DeviceTreeProp<'a, 'i, 'dt> { pub fn new(source: DevTreeIndexProp<'a, 'i, 'dt>) -> Self { Self(source) } - pub fn payload_pairs_iter( - &'a self, - address_cells: u32, - size_cells: u32, - ) -> PayloadPairsIter<'a, 'i, 'dt> { + pub fn payload_pairs_iter(&'a self) -> PayloadPairsIter<'a, 'i, 'dt> { + let address_cells = get_address_cells(&self.node()); + let size_cells = get_size_cells(&self.node()); + + // @todo boot this on 8Gb RasPi, because I'm not sure how it allocates memory regions there. + println!( + "Address cells: {}, size cells {}", + address_cells, size_cells + ); + PayloadPairsIter::new(&self.0, address_cells, size_cells) } } diff --git a/nucleus/src/main.rs b/nucleus/src/main.rs index 7ccf0674..58c07cb3 100644 --- a/nucleus/src/main.rs +++ b/nucleus/src/main.rs @@ -167,24 +167,6 @@ pub fn kmain(dtb: u32) -> ! { // 2. From those read reg entries, using `/#address-cells` and `/#size-cells` as units // 3. Union of all these reg entries will be the available memory. Enter it as mem-regions. - let address_cells = device_tree - .get_prop_by_path("/#address-cells") - .expect("Unable to figure out #address-cells") - .u32(0) - .expect("Invalid format for #address-cells"); - - let size_cells = device_tree - .get_prop_by_path("/#size-cells") - .expect("Unable to figure out #size-cells") - .u32(0) - .expect("Invalid format for #size-cells"); - - // @todo boot this on 8Gb RasPi, because I'm not sure how it allocates memory regions there. - println!( - "Address cells: {}, size cells {}", - address_cells, size_cells - ); - let res: Result<_, DevTreeError> = device_tree .props() .try_find(|p| Ok(p.name()? == "device_type" && p.str()? == "memory")); @@ -204,7 +186,7 @@ pub fn kmain(dtb: u32) -> ! { let reg_prop = DeviceTreeProp::new(reg_prop); - for (mem_addr, mem_size) in reg_prop.payload_pairs_iter(address_cells, size_cells) { + for (mem_addr, mem_size) in reg_prop.payload_pairs_iter() { println!("Memory: {} KiB at offset {}", mem_size / 1024, mem_addr); } @@ -229,14 +211,6 @@ pub fn kmain(dtb: u32) -> ! { dtb ); - // let address_cells = device_tree.try_struct_u32_value("/#address-cells"); - // let size_cells = device_tree.try_struct_u32_value("/#size-cells"); - - // println!( - // "Memory DTB info: address-cells {:?}, size-cells {:?}", - // address_cells, size_cells - // ); - dump_memory_map(); #[cfg(test)]