diff --git a/examples/reg-test.dtb b/examples/reg-test.dtb new file mode 100644 index 0000000..653afb6 Binary files /dev/null and b/examples/reg-test.dtb differ diff --git a/src/de_mut/data.rs b/src/de_mut/data.rs index a85ccb6..c38e280 100644 --- a/src/de_mut/data.rs +++ b/src/de_mut/data.rs @@ -16,7 +16,8 @@ pub(super) enum ValueCursor { #[derive(Clone, Copy)] pub(super) struct ValueDeserializer<'de> { pub dtb: RefDtb<'de>, - pub reg: RegConfig, + pub self_reg: RegConfig, + pub next_reg: RegConfig, pub cursor: ValueCursor, } diff --git a/src/de_mut/mod.rs b/src/de_mut/mod.rs index 3afaeb5..e95737d 100644 --- a/src/de_mut/mod.rs +++ b/src/de_mut/mod.rs @@ -44,7 +44,8 @@ where // 从一个跳过根节点名字的光标初始化解析器。 let mut d = ValueDeserializer { dtb, - reg: RegConfig::DEFAULT, + self_reg: RegConfig::DEFAULT, + next_reg: RegConfig::DEFAULT, cursor: ValueCursor::NodeIn(MultiNodeCursor { start_cursor: BodyCursor::STARTER, skip_cursor: BodyCursor::ROOT, // This item will never be used. diff --git a/src/de_mut/node.rs b/src/de_mut/node.rs index 54ca3b6..f0b1b8f 100644 --- a/src/de_mut/node.rs +++ b/src/de_mut/node.rs @@ -7,13 +7,12 @@ use core::marker::PhantomData; use serde::de::MapAccess; use serde::{Deserialize, Serialize, de}; -// TODO: Spec 2.3.5 said that we should not inherited from ancestors and the size-cell & -// address-cells should only used for current node's children. #[allow(unused)] #[derive(Clone)] pub struct Node<'de> { dtb: RefDtb<'de>, - reg: RegConfig, + self_reg: RegConfig, + next_reg: RegConfig, cursor: BodyCursor, props_start: Option, nodes_start: Option, @@ -64,7 +63,8 @@ impl<'de> Node<'de> { }; T::deserialize(&mut ValueDeserializer { dtb: self.dtb, - reg: self.reg, + self_reg: self.self_reg, + next_reg: self.next_reg, cursor: ValueCursor::NodeIn(result), }) .unwrap() @@ -148,7 +148,7 @@ impl<'de> Iterator for NodeIter<'de, '_> { let node_cursor = c.take_node_on(dtb, name); let res = Some(Self::Item { dtb, - reg: self.node.reg, + reg: self.node.next_reg, node: node_cursor, name, }); @@ -175,7 +175,7 @@ impl<'de> Iterator for PropIter<'de, '_> { let res = Some(Self::Item { dtb, body: *cursor, - reg: self.node.reg, + reg: self.node.self_reg, prop: c, name, }); @@ -212,18 +212,21 @@ impl<'de> Deserialize<'de> for Node<'_> { // While there are entries remaining in the input, add them // into our map. let mut dtb: Option> = None; - let mut reg: Option = None; + // Only update reg when props or init, because node's reg is for children. + let mut self_reg: Option = None; + let mut next_reg: Option = None; let mut props_start: Option = None; let mut nodes_start: Option = None; let mut self_cursor: Option = None; while let Some((key, value)) = access.next_entry::<&str, ValueDeserializer<'b>>()? { dtb = Some(value.dtb); - reg = Some(value.reg); if key == "/" { + self_reg = Some(value.self_reg); + next_reg = Some(value.next_reg); self_cursor = match value.cursor { ValueCursor::NodeIn(result) => Some(result.start_cursor), _ => { - unreachable!("root of NodeSeq shouble be NodeIn cursor") + unreachable!("root of Node shouble be NodeIn cursor") } }; continue; @@ -233,6 +236,8 @@ impl<'de> Deserialize<'de> for Node<'_> { if props_start.is_none() { props_start = Some(cursor); } + self_reg = Some(value.self_reg); + next_reg = Some(value.next_reg); } ValueCursor::NodeIn(cursor) => { if nodes_start.is_none() { @@ -245,7 +250,8 @@ impl<'de> Deserialize<'de> for Node<'_> { Ok(Node { dtb: dtb.unwrap(), - reg: reg.unwrap(), + self_reg: self_reg.unwrap(), + next_reg: next_reg.unwrap(), cursor: self_cursor.unwrap(), nodes_start, props_start, @@ -268,7 +274,8 @@ impl<'de> NodeItem<'de> { pub fn deserialize>(&self) -> T { T::deserialize(&mut ValueDeserializer { dtb: self.dtb, - reg: self.reg, + self_reg: self.reg, + next_reg: RegConfig::DEFAULT, cursor: ValueCursor::NodeIn(self.node), }) .unwrap() @@ -304,7 +311,8 @@ impl<'de> PropItem<'de> { use super::ValueCursor; T::deserialize(&mut ValueDeserializer { dtb: self.dtb, - reg: self.reg, + self_reg: self.reg, + next_reg: RegConfig::DEFAULT, cursor: ValueCursor::Prop(self.body, self.prop), }) .unwrap() diff --git a/src/de_mut/node_seq.rs b/src/de_mut/node_seq.rs index 0e003a8..7f517fd 100644 --- a/src/de_mut/node_seq.rs +++ b/src/de_mut/node_seq.rs @@ -1,4 +1,4 @@ -use super::{BodyCursor, Cursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer}; +use super::{Cursor, MultiNodeCursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer}; use core::{fmt::Debug, marker::PhantomData}; use serde::de::SeqAccess; use serde::{Deserialize, de}; @@ -25,7 +25,7 @@ pub struct NodeSeqIter<'de, 'b> { pub struct NodeSeqItem<'de> { dtb: RefDtb<'de>, reg: RegConfig, - body: BodyCursor, + body: MultiNodeCursor, at: &'de str, } @@ -75,13 +75,10 @@ impl<'de> Deserialize<'de> for NodeSeq<'_> { } } - serde::Deserializer::deserialize_seq( - deserializer, - Visitor { - marker: PhantomData, - lifetime: PhantomData, - }, - ) + deserializer.deserialize_seq(Visitor { + marker: PhantomData, + lifetime: PhantomData, + }) } } @@ -144,8 +141,8 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> { Some(Self::Item { dtb: self.de.dtb, - reg: self.de.reg, - body: node_reuslt.data_cursor, + reg: self.de.self_reg, + body: node_reuslt, at: suf_name, }) } @@ -167,8 +164,9 @@ impl<'de> NodeSeqItem<'de> { pub fn deserialize>(&self) -> T { T::deserialize(&mut ValueDeserializer { dtb: self.dtb, - reg: self.reg, - cursor: ValueCursor::Body(self.body), + self_reg: self.reg, + next_reg: RegConfig::DEFAULT, + cursor: ValueCursor::NodeIn(self.body), }) .unwrap() } diff --git a/src/de_mut/reg.rs b/src/de_mut/reg.rs index 445d8c4..7ee5edf 100644 --- a/src/de_mut/reg.rs +++ b/src/de_mut/reg.rs @@ -44,7 +44,7 @@ impl<'de> Deserialize<'de> for Reg<'_> { let inner = Inner { dtb: value_deserialzer.dtb, - reg: value_deserialzer.reg, + reg: value_deserialzer.self_reg, cursor: match value_deserialzer.cursor { ValueCursor::Prop(_, cursor) => cursor, _ => { @@ -85,6 +85,8 @@ impl Iterator for RegIter<'_> { type Item = RegRegion; fn next(&mut self) -> Option { + println!("{:?}", self.config.address_cells); + println!("{:?}", self.config.size_cells); let len = BLOCK_LEN * (self.config.address_cells + self.config.size_cells); if self.data.len() >= len { let (current_block, data) = self.data.split_at(len); @@ -126,3 +128,127 @@ impl Serialize for Reg<'_> { serializer.serialize_bytes(self.0.cursor.data_on(self.0.dtb)) } } + +#[cfg(test)] +mod tests { + use crate::buildin::{Node, NodeSeq, Reg}; + use crate::{Dtb, DtbPtr, from_raw_mut}; + use serde::Deserialize; + + const RAW_DEVICE_TREE: &[u8] = include_bytes!("../../examples/reg-test.dtb"); + const BUFFER_SIZE: usize = RAW_DEVICE_TREE.len(); + #[repr(align(8))] + struct AlignedBuffer { + pub data: [u8; RAW_DEVICE_TREE.len()], + } + + /// Memory range. + #[derive(Deserialize)] + #[serde(rename_all = "kebab-case")] + pub struct Memory<'a> { + pub reg: Reg<'a>, + } + #[test] + fn test_normal_reg() { + #[derive(Deserialize)] + pub struct Tree<'a> { + /// Memory information. + pub normal: Memory<'a>, + } + let mut aligned_data: Box = Box::new(AlignedBuffer { + data: [0; BUFFER_SIZE], + }); + aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE); + let mut slice = aligned_data.data.to_vec(); + let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap(); + let dtb = Dtb::from(ptr).share(); + + let node: Tree = from_raw_mut(&dtb).unwrap(); + assert_eq!( + node.normal.reg.iter().next().unwrap().0, + 1342177280..1408237568 + ); + } + #[test] + fn test_normal_reg_node() { + let mut aligned_data: Box = Box::new(AlignedBuffer { + data: [0; BUFFER_SIZE], + }); + aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE); + let mut slice = aligned_data.data.to_vec(); + let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap(); + let dtb = Dtb::from(ptr).share(); + + let node: Node = from_raw_mut(&dtb).unwrap(); + let reg = node + .find("/normal") + .unwrap() + .get_prop("reg") + .unwrap() + .deserialize::(); + assert_eq!(reg.iter().next().unwrap().0, 1342177280..1408237568); + } + #[test] + fn test_depper_normal_reg_node() { + let mut aligned_data: Box = Box::new(AlignedBuffer { + data: [0; BUFFER_SIZE], + }); + aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE); + let mut slice = aligned_data.data.to_vec(); + let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap(); + let dtb = Dtb::from(ptr).share(); + + let node: Node = from_raw_mut(&dtb).unwrap(); + let reg = node + .find("/seq/node@2/normal") + .unwrap() + .get_prop("reg") + .unwrap() + .deserialize::(); + assert_eq!(reg.iter().next().unwrap().0, 1342177280..1408237568); + } + #[test] + fn test_seq_reg_node() { + #[derive(Deserialize)] + pub struct Tree<'a> { + pub seq: Seq<'a>, + } + #[derive(Deserialize)] + pub struct Seq<'a> { + pub node: NodeSeq<'a>, + } + let mut aligned_data: Box = Box::new(AlignedBuffer { + data: [0; BUFFER_SIZE], + }); + aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE); + let mut slice = aligned_data.data.to_vec(); + let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap(); + let dtb = Dtb::from(ptr).share(); + + let node: Tree = from_raw_mut(&dtb).unwrap(); + let mut iter = node.seq.node.iter(); + let node1 = iter.next().unwrap(); + assert_eq!( + node1.deserialize::().reg.iter().next().unwrap().0, + 1..4294967298 + ); + let node2 = iter.next().unwrap(); + assert_eq!( + node2.deserialize::().reg.iter().next().unwrap().0, + 2..4 + ); + let node3 = iter.next().unwrap(); + assert_eq!( + node3 + .deserialize::() + .get_prop("reg") + .unwrap() + .deserialize::() + .iter() + .next() + .unwrap() + .0, + 3..12884901894 + ); + } +} diff --git a/src/de_mut/struct_access.rs b/src/de_mut/struct_access.rs index 640f3fe..de282cb 100644 --- a/src/de_mut/struct_access.rs +++ b/src/de_mut/struct_access.rs @@ -1,5 +1,5 @@ use super::cursor::MultiNodeCursor; -use super::{BodyCursor, Cursor, PropCursor, ValueCursor, ValueDeserializer}; +use super::{BodyCursor, Cursor, PropCursor, RegConfig, ValueCursor, ValueDeserializer}; use crate::error::Error as DtError; use serde::de; @@ -27,6 +27,7 @@ pub enum Temp { Prop(BodyCursor, PropCursor), } +// TODO: We should consider about prop after node, even it's no legal. impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { type Error = DtError; @@ -92,10 +93,10 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { self.de.cursor = ValueCursor::Body(next); match name { "#address-cells" => { - self.de.reg.address_cells = c.map_u32_on(self.de.dtb)? as usize; + self.de.next_reg.address_cells = c.map_u32_on(self.de.dtb)? as usize; } "#size-cells" => { - self.de.reg.size_cells = c.map_u32_on(self.de.dtb)? as usize; + self.de.next_reg.size_cells = c.map_u32_on(self.de.dtb)? as usize; } _ => {} } @@ -124,7 +125,8 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { *flag = true; return seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - reg: self.de.reg, + self_reg: self.de.next_reg, + next_reg: RegConfig::DEFAULT, cursor: self.de.cursor, }); } @@ -135,12 +137,14 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { match self.access_type { StructAccessType::Map(_) => seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - reg: self.de.reg, + self_reg: self.de.next_reg, + next_reg: RegConfig::DEFAULT, cursor: ValueCursor::NodeIn(*result), }), StructAccessType::Struct(_) => seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - reg: self.de.reg, + self_reg: self.de.next_reg, + next_reg: RegConfig::DEFAULT, cursor: ValueCursor::NodeIn(*result), }), _ => unreachable!(), @@ -150,7 +154,8 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { // 键是属性名字,构造属性反序列化器 seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - reg: self.de.reg, + self_reg: self.de.self_reg, + next_reg: self.de.next_reg, cursor: ValueCursor::Prop(origin_cursor, cursor), }) } @@ -188,7 +193,8 @@ impl<'de> de::SeqAccess<'de> for StructAccess<'de, '_> { self.de.cursor = ValueCursor::Body(next); seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - reg: self.de.reg, + self_reg: self.de.self_reg, + next_reg: self.de.next_reg, cursor: ValueCursor::Body(prev_cursor), }) .map(Some)