Skip to content

Commit 2a5d6ab

Browse files
authored
Merge pull request #14 from woshiluo/pmu
Add support for `riscv,pmu` device
2 parents 59d640d + 3320bf1 commit 2a5d6ab

21 files changed

+322
-40
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ Cargo.lock
44

55
# Visual Studio Code configuration files
66
.vscode/
7-
*.dts
7+
8+
*.dtb
9+
!examples/*.dtb

Cargo.toml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ edition = "2024"
1414
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1515

1616
[dependencies]
17-
serde = { version = "1.0", default-features = false }
18-
erased-serde = "0.4"
19-
20-
[dev-dependencies]
21-
serde_derive = "1.0"
17+
serde = { version = "1.0", default-features = false, features = ["derive"] }
18+
dyn_serde = { version = "1.0.2", default-features = false, optional = true }
2219

2320
[features]
24-
default = ["std"]
21+
default = ["std", "ser"]
2522

23+
ser = ["dep:dyn_serde"]
2624
std = ["serde/std"]
2725
alloc = ["serde/alloc"]

examples/hifive-unmatched-a00.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern crate alloc;
22

33
use alloc::collections::BTreeMap;
4-
use serde_derive::Deserialize;
4+
use serde::Deserialize;
55
use serde_device_tree::Compatible;
66

77
#[derive(Debug, Deserialize)]

examples/qemu-virt.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! 这是一个 `from_raw_mut` 反序列化设备树的示例。不需要 `alloc`。
22
// extern crate alloc;
33

4-
// 在实际使用中,将这里的 `serde_derive::Deserialize` 改为 `serde::Deserialize`。
5-
use serde_derive::Deserialize;
4+
use serde::Deserialize;
65

76
// - `DtbPtr`: 验证设备树首部正确性,后续也可借助这个类型传递设备树,多次解析不必重复验证。
87
// - `Dtb`: 管理反序列化出的类型生命周期。

examples/serialize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use serde_derive::Serialize;
1+
use serde::Serialize;
22
use std::io::prelude::*;
33

44
const MAX_SIZE: usize = 256 + 32;

src/de.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use serde::de;
4242
/// # });
4343
/// # aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE);
4444
/// # let fdt_ptr = aligned_data.data.as_ptr();
45-
/// use serde_derive::Deserialize;
45+
/// use serde::Deserialize;
4646
///
4747
/// #[derive(Debug, Deserialize)]
4848
/// struct Tree<'a> {
@@ -516,7 +516,7 @@ mod tests {
516516
#[cfg(feature = "alloc")]
517517
use alloc::format;
518518
#[cfg(any(feature = "std", feature = "alloc"))]
519-
use serde_derive::Deserialize;
519+
use serde::Deserialize;
520520
#[cfg(feature = "std")]
521521
use std::format;
522522

src/de_mut/matrix.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
use crate::de_mut::ValueCursor;
2+
use serde::{Deserialize, Serialize};
3+
4+
pub struct Matrix<'de, const T: usize> {
5+
data: &'de [u32],
6+
}
7+
8+
pub struct MatrixItem<'de, const T: usize> {
9+
offset: usize,
10+
data: &'de [u32],
11+
}
12+
13+
impl<'de, const T: usize> Matrix<'de, T> {
14+
#[inline(always)]
15+
pub fn get_block_size() -> usize {
16+
// Block size in bytes.
17+
T * 4
18+
}
19+
20+
#[inline(always)]
21+
pub fn iter(&self) -> MatrixItem<'de, T> {
22+
MatrixItem {
23+
offset: 0,
24+
data: self.data,
25+
}
26+
}
27+
28+
#[inline(always)]
29+
pub fn len(&self) -> usize {
30+
self.data.len() / T
31+
}
32+
33+
#[inline(always)]
34+
pub fn is_empty(&self) -> bool {
35+
self.data.len() != 0
36+
}
37+
38+
#[inline(always)]
39+
pub fn get(&self, i: usize) -> &'de [u32] {
40+
&self.data[i * T..(i + 1) * T]
41+
}
42+
}
43+
44+
impl<'de, const T: usize> Iterator for MatrixItem<'de, T> {
45+
type Item = &'de [u32];
46+
47+
#[inline(always)]
48+
fn next(&mut self) -> Option<Self::Item> {
49+
if self.data.len() <= self.offset {
50+
return None;
51+
}
52+
let result = &self.data[self.offset..self.offset + T];
53+
self.offset += T;
54+
Some(result)
55+
}
56+
}
57+
58+
impl<'de, const T: usize> Deserialize<'de> for Matrix<'_, T> {
59+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60+
where
61+
D: serde::Deserializer<'de>,
62+
{
63+
let value_deserialzer = super::ValueDeserializer::deserialize(deserializer)?;
64+
let data = match value_deserialzer.cursor {
65+
ValueCursor::Prop(_, cursor) => cursor.data_on(value_deserialzer.dtb),
66+
_ => unreachable!(),
67+
};
68+
if data.len() % Self::get_block_size() != 0 {
69+
panic!("unaligned matrix");
70+
}
71+
let (prefix, data, suffix) = unsafe { data.align_to::<u32>() };
72+
if !prefix.is_empty() || !suffix.is_empty() {
73+
panic!("Not support unaligned data");
74+
}
75+
76+
Ok(Self { data })
77+
}
78+
}
79+
80+
impl<const T: usize> Serialize for Matrix<'_, T> {
81+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82+
where
83+
S: serde::Serializer,
84+
{
85+
use serde::ser::SerializeSeq;
86+
let mut seq = serializer.serialize_seq(Some(self.data.len()))?;
87+
for x in self.data {
88+
seq.serialize_element(x)?;
89+
}
90+
seq.end()
91+
}
92+
}
93+
94+
#[cfg(test)]
95+
mod tests {
96+
use super::Matrix;
97+
use crate::{Dtb, DtbPtr, buildin::Node, from_raw_mut};
98+
use serde::Serialize;
99+
100+
const MAX_SIZE: usize = 256;
101+
#[test]
102+
fn base_ser_test() {
103+
#[derive(Serialize)]
104+
struct Base {
105+
pub hello: [u32; 16],
106+
}
107+
let array: [u32; 16] = [0xdeadbeef; 16];
108+
let mut buf1 = [0u8; MAX_SIZE];
109+
110+
{
111+
let base = Base { hello: array };
112+
crate::ser::to_dtb(&base, &[], &mut buf1).unwrap();
113+
}
114+
115+
let ptr = DtbPtr::from_raw(buf1.as_mut_ptr()).unwrap();
116+
let dtb = Dtb::from(ptr).share();
117+
let node: Node = from_raw_mut(&dtb).unwrap();
118+
let matrix = node.get_prop("hello").unwrap().deserialize::<Matrix<4>>();
119+
let mut count = 0;
120+
for x in matrix.iter() {
121+
for y in x {
122+
count += 1;
123+
assert_eq!(u32::from_be(*y), 0xdeadbeef);
124+
}
125+
}
126+
assert_eq!(count, 16);
127+
}
128+
}

src/de_mut/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::de;
77
mod cursor;
88
mod data;
99
// mod group;
10+
mod matrix;
1011
pub(crate) mod node;
1112
mod node_seq;
1213
mod reg;
@@ -18,11 +19,11 @@ mod structs;
1819
const VALUE_DESERIALIZER_NAME: &str = "$serde_device_tree$de_mut$ValueDeserializer";
1920
pub(crate) const NODE_NAME: &str = "$serde_device_tree$de_mut$Node";
2021
pub(crate) const NODE_NODE_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$NodeItem";
21-
pub(crate) const NODE_PROP_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$PropItem";
22+
// pub(crate) const NODE_PROP_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$PropItem";
2223

2324
pub use structs::{Dtb, DtbPtr};
2425
pub mod buildin {
25-
pub use super::{node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
26+
pub use super::{matrix::Matrix, node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
2627
}
2728

2829
use cursor::{BodyCursor, Cursor, MultiNodeCursor, PropCursor};

src/de_mut/node.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,18 @@ pub struct PropItem<'de> {
5454
impl<'de> Node<'de> {
5555
pub fn deserialize<T: Deserialize<'de>>(&self) -> T {
5656
use super::ValueCursor;
57+
let result = match self.cursor.clone().move_on(self.dtb) {
58+
Cursor::Title(c) => {
59+
let (name, _) = c.split_on(self.dtb);
60+
let take_result = c.take_node_on(self.dtb, name);
61+
take_result
62+
}
63+
_ => unreachable!("Node's cursor should on its start"),
64+
};
5765
T::deserialize(&mut ValueDeserializer {
5866
dtb: self.dtb,
5967
reg: self.reg,
60-
cursor: ValueCursor::Body(self.cursor),
68+
cursor: ValueCursor::NodeIn(result),
6169
})
6270
.unwrap()
6371
}
@@ -302,7 +310,7 @@ impl<'de> PropItem<'de> {
302310
.unwrap()
303311
}
304312
}
305-
impl<'se> Serialize for NodeItem<'se> {
313+
impl Serialize for NodeItem<'_> {
306314
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307315
where
308316
S: serde::Serializer,
@@ -311,7 +319,7 @@ impl<'se> Serialize for NodeItem<'se> {
311319
}
312320
}
313321

314-
impl<'se> Serialize for PropItem<'se> {
322+
impl Serialize for PropItem<'_> {
315323
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
316324
where
317325
S: serde::Serializer,
@@ -320,7 +328,7 @@ impl<'se> Serialize for PropItem<'se> {
320328
}
321329
}
322330

323-
impl<'se> Serialize for Node<'se> {
331+
impl Serialize for Node<'_> {
324332
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
325333
where
326334
S: serde::Serializer,

src/de_mut/node_seq.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl<'de> NodeSeqItem<'de> {
178178
mod tests {
179179
use crate::buildin::{NodeSeq, Reg};
180180
use crate::{Dtb, DtbPtr, from_raw_mut};
181-
use serde_derive::Deserialize;
181+
use serde::Deserialize;
182182

183183
const RAW_DEVICE_TREE: &[u8] = include_bytes!("../../examples/bl808.dtb");
184184
const BUFFER_SIZE: usize = RAW_DEVICE_TREE.len();

src/de_mut/reg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl Iterator for RegIter<'_> {
117117
}
118118
}
119119

120-
impl<'se> Serialize for Reg<'se> {
120+
impl Serialize for Reg<'_> {
121121
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
122122
where
123123
S: serde::Serializer,

src/de_mut/str_seq.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl<'de> Iterator for StrSeqIter<'de> {
9191
}
9292
}
9393

94-
impl<'se> Serialize for StrSeq<'se> {
94+
impl Serialize for StrSeq<'_> {
9595
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9696
where
9797
S: serde::Serializer,

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ extern crate alloc;
2020

2121
pub mod de;
2222
pub mod error;
23+
#[cfg(feature = "ser")]
2324
pub mod ser;
2425
pub mod utils;
26+
pub mod value;
2527

2628
mod common;
2729
mod de_mut;
2830
mod tag;
29-
mod value;
3031

3132
pub use value::compatible::Compatible;
3233

src/ser/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,16 @@ where
3939
let writer_len = writer.len();
4040
let (data_block, string_block) = writer.split_at_mut(writer.len() - offset);
4141
let (header, data_block) = data_block.split_at_mut(HEADER_LEN as usize + RSVMAP_LEN);
42-
{
42+
let struct_len = {
4343
let mut patch_list = crate::ser::patch::PatchList::new(list);
4444
let mut block = crate::ser::string_block::StringBlock::new(string_block, &mut offset);
4545
let mut dst = crate::ser::pointer::Pointer::new(Some(data_block));
4646
let mut ser =
4747
crate::ser::serializer::Serializer::new(&mut dst, &mut block, &mut patch_list);
4848
data.serialize(&mut ser)?;
4949
ser.dst.step_by_u32(FDT_END);
50-
}
50+
ser.dst.get_offset()
51+
};
5152
// Make header
5253
{
5354
let header = unsafe { &mut *(header.as_mut_ptr() as *mut Header) };
@@ -60,7 +61,7 @@ where
6061
header.last_comp_version = u32::from_be(SUPPORTED_VERSION); // TODO: maybe 16
6162
header.boot_cpuid_phys = 0; // TODO: wtf is this prop
6263
header.size_dt_strings = u32::from_be(offset as u32);
63-
header.size_dt_struct = u32::from_be(data_block.len() as u32); // TODO: correct?
64+
header.size_dt_struct = u32::from_be(struct_len as u32);
6465
}
6566
Ok(())
6667
}
@@ -71,7 +72,7 @@ pub enum Error {
7172
}
7273

7374
impl core::fmt::Display for Error {
74-
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75+
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7576
write!(formatter, "{:?}", self)
7677
}
7778
}
@@ -81,7 +82,7 @@ impl core::error::Error for Error {}
8182
impl serde::ser::Error for Error {
8283
fn custom<T>(_msg: T) -> Self
8384
where
84-
T: std::fmt::Display,
85+
T: core::fmt::Display,
8586
{
8687
Self::Unknown
8788
}

src/ser/patch.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use core::cell::Cell;
44
/// Since this crate is mostly work with `noalloc`, we use `Patch` and `PatchList` for change or
55
/// add on a dtb.
66
pub struct Patch<'se> {
7-
pub data: &'se dyn erased_serde::Serialize,
7+
pub data: &'se dyn dyn_serde::Serialize,
88
name: &'se str,
99

1010
/// This patch match how many item between its path and serializer.
@@ -15,7 +15,7 @@ pub struct Patch<'se> {
1515

1616
impl<'se> Patch<'se> {
1717
#[inline(always)]
18-
pub fn new(name: &'se str, data: &'se dyn erased_serde::Serialize) -> Patch<'se> {
18+
pub fn new(name: &'se str, data: &'se dyn dyn_serde::Serialize) -> Patch<'se> {
1919
Patch {
2020
name,
2121
data,
@@ -51,7 +51,7 @@ impl<'se> Patch<'se> {
5151
pub fn serialize(&self, serializer: &mut Serializer<'se>) {
5252
self.parsed.set(true);
5353
self.data
54-
.erased_serialize(&mut <dyn erased_serde::Serializer>::erase(serializer))
54+
.serialize_dyn(&mut <dyn dyn_serde::Serializer>::new(serializer))
5555
.unwrap();
5656
}
5757
}

0 commit comments

Comments
 (0)