use deforest::{ blob::Cursor, prop_value::{self, RegBlock}, DeserializeNode, }; #[derive(Debug, Default, DeserializeNode)] struct RootNode { address_cells: prop_value::AddressCells, size_cells: prop_value::SizeCells, model: String, compatible: Vec, serial_number: Option, chassis_type: Option, #[dt(child)] aliases: Option, #[dt(children)] memory: Vec, #[dt(child)] reserved_memory: Option, #[dt(child)] chosen: Option, #[dt(child)] cpus: Option, #[dt(children(rest))] rest: Vec, } #[derive(Debug, Default, DeserializeNode)] struct MemoryNode { device_type: Option, reg: Option>, initial_mapped_area: Option, hotpluggable: bool, } #[derive(Debug, Default, DeserializeNode)] struct ReservedMemoryNode { address_cells: prop_value::AddressCells, size_cells: prop_value::SizeCells, ranges: Vec, } #[derive(Debug, Default, DeserializeNode)] struct ReservedMemoryChild { reg: Option>, size: Option>, alignment: Option>, alloc_ranges: Option>, compatible: Option>, no_map: bool, reusable: bool, } #[derive(Debug, Default, DeserializeNode)] struct ChosenNode { bootargs: Option, stdout_path: Option, stdin_path: Option, } #[derive(Debug, Default, DeserializeNode)] struct CpusNode { address_cells: prop_value::AddressCells, size_cells: prop_value::SizeCells, #[dt(children)] cpu: Vec, } #[derive(Debug, Default, DeserializeNode)] struct CpuNode { device_type: Option, reg: Option>, clock_frequency: prop_value::SmallU64, timebase_frequency: prop_value::SmallU64, status: Option, enable_method: Option>, cpu_release_addr: Option, // // power ISA properties // power_isa_version: Option, // cache_op_block_size: Option, // reservation_granule_size: Option, // mmu_type: Option, // // power ISA translate look-aside buffer properties // tlb_split: bool, // tlb_size: Option, // tlb_sets: Option, // d_tlb_size: Option, // d_tlb_sets: Option, // i_tlb_size: Option, // i_tlb_sets: Option, // // power ISA cache properties // cache_unified: bool, // cache_size: Option, // cache_sets: Option, // cache_block_size: Option, // cache_line_size: Option, // i_cache_size: Option, // i_cache_sets: Option, // i_cache_block_size: Option, // i_cache_line_size: Option, // d_cache_size: Option, // d_cache_sets: Option, // d_cache_block_size: Option, // d_cache_line_size: Option, // next_level_cache: Option, } // #[derive(Debug, Default, DeserializeNode)] // struct MlAndSharedCacheNode { // compatible: String, // cache_level: u32, // } #[test] fn deserialize() { const UNALIGNED_BLOB: &[u8] = include_bytes!("../tests/tree.dtb"); let dt = deforest::blob::Devicetree::from_unaligned(UNALIGNED_BLOB).unwrap(); let root_node: RootNode = dt.parse_root().unwrap(); let cpus = root_node.cpus.unwrap().cpu; assert_eq!(cpus.len(), 4); assert!(cpus.iter().all(|c| c.device_type.is_some())); assert!(root_node.memory[0].device_type.is_some()); }