Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added examples/reg-test.dtb
Binary file not shown.
3 changes: 2 additions & 1 deletion src/de_mut/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
3 changes: 2 additions & 1 deletion src/de_mut/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
32 changes: 20 additions & 12 deletions src/de_mut/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<BodyCursor>,
nodes_start: Option<BodyCursor>,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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,
});
Expand All @@ -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,
});
Expand Down Expand Up @@ -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<RefDtb<'b>> = None;
let mut reg: Option<RegConfig> = None;
// Only update reg when props or init, because node's reg is for children.
let mut self_reg: Option<RegConfig> = None;
let mut next_reg: Option<RegConfig> = None;
let mut props_start: Option<BodyCursor> = None;
let mut nodes_start: Option<BodyCursor> = None;
let mut self_cursor: Option<BodyCursor> = 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;
Expand All @@ -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() {
Expand All @@ -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,
Expand All @@ -268,7 +274,8 @@ impl<'de> NodeItem<'de> {
pub fn deserialize<T: Deserialize<'de>>(&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()
Expand Down Expand Up @@ -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()
Expand Down
24 changes: 11 additions & 13 deletions src/de_mut/node_seq.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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,
}

Expand Down Expand Up @@ -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,
})
}
}

Expand Down Expand Up @@ -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,
})
}
Expand All @@ -167,8 +164,9 @@ impl<'de> NodeSeqItem<'de> {
pub fn deserialize<T: Deserialize<'de>>(&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()
}
Expand Down
128 changes: 127 additions & 1 deletion src/de_mut/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
_ => {
Expand Down Expand Up @@ -85,6 +85,8 @@ impl Iterator for RegIter<'_> {
type Item = RegRegion;

fn next(&mut self) -> Option<Self::Item> {
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);
Expand Down Expand Up @@ -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<AlignedBuffer> = 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<AlignedBuffer> = 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::<Reg>();
assert_eq!(reg.iter().next().unwrap().0, 1342177280..1408237568);
}
#[test]
fn test_depper_normal_reg_node() {
let mut aligned_data: Box<AlignedBuffer> = 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::<Reg>();
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<AlignedBuffer> = 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::<Memory>().reg.iter().next().unwrap().0,
1..4294967298
);
let node2 = iter.next().unwrap();
assert_eq!(
node2.deserialize::<Memory>().reg.iter().next().unwrap().0,
2..4
);
let node3 = iter.next().unwrap();
assert_eq!(
node3
.deserialize::<Node>()
.get_prop("reg")
.unwrap()
.deserialize::<Reg>()
.iter()
.next()
.unwrap()
.0,
3..12884901894
);
}
}
Loading